여전히 pointer 나 reference 를 사용하는 C, C++은 어렵게 느껴진다.
기본적인 차이는 Fortran은 call by reference가 기본이라
사실은 언제나 pointer를 사용하는 셈이라는 것에 비해, C++은
call by value가 기본이기 때문에 Fortran처럼 사용하기 위해서는
함수에서 pointer를 사용해야 한다는 것이다.
포인터는 기본적으로 변수의 주소를 가리키는 것이라고는 알고 있지만,
가장 헷갈리는 것은 * 와 & 의 사용법과 함수에서의 input/output으로의 사용법이다.
문제를 더 복잡하게 만드는 것은 C/C++ 에서는 array와 C-string 을 pointer로
취급한다는 사실과 reference의 경우에는 implicit referencing과 dereference가
자동으로 일어난다는 점, 그리고 * 와 &가 문맥에 따라 다른 의미로 사용된다는
점이다. 이 때문에 포트란이나 파이쏜에 익숙한 내가 보기에는 일관되지 않은 사용법이
나타난다.
내가 이해하는 범위에서 포인터,레퍼런스 등의 사용법을 살펴보도록 하자.
(1) a, *a, &a 의 차이가 무엇일까?
일반적인 변수는 'int a' 와 같은 형태로 선언한다. 이 때, 컴파일러는 이 변수마다 주소를 할당하고 프로그램에서는 이 주소에 값을 저장한다. ( 집이 변수, 집 안의 물건이 변수값, 집의 주소 의 관계로 생각할 수 있다.) b=a 와 같은 명령은 집 a안의 물건을 집 b 에 복사하는 역할을 한다.
포인터는 'int* a_ptr' 과 같이 선언한다. 이 때, 'a_ptr'은 포인터로써 주소값을 가진다.
'*' 는 포인터(주소)가 가리키는 집안의 물건을 꺼내는 역할을 한다. (즉, '*' 는 포인터를 물건으로 바꾸는 역할을 한다.)
한편, '&'는 변수의 주소를 나타낸다. ' &a' 는 a 라는 변수의 주소를 준다.
(즉, '&'는 물건을 주소로 바꾸는 역할을 한다.)
int thing; // thing은 일반 변수(집) 이다.
int* thing_ptr ;// thing_ptr은 포인터(주소)로 선언한다.
thing : 변수(집)
thing = 4; // thing 에 숫자 4를 넣는다.
&thing : 변수 thing의 주소
thing_ptr : 포인터(주소)
thing_ptr = &thing ;
// &thing은 thing의 주소값이고,
thing_ptr은 따라서 thing의 포인터가 된다.
따라서 이후로는 thing과 *thing_ptr은 같은 것을 나타낸다.
*thing_ptr : 어떤 것(이 경우는 정수).
other = *thing_ptr;
// *thing_ptr은 thing_ptr 주소가 나타내는 변수(집)이므로,
other라는 집에 thing_ptr이 가리키는 것을 넣는다.
여기서, other는 정수값이 된다.
*thing_ptr = 5; (?)
// *thing_ptr은 thing_ptr 주소가 나타내는 변수(집)이므로,
thing 에 5라는 숫자를 넣는 역할을 한다. (?)
*thing : thing은 포인터가 아니므로 틀린 문법.
&thing_ptr : 포인터의 포인터.
좀 더 정확한 pointer와 reference의 차이는 앞의 글 참조.
(주의?) c++의 character pointer 는 다른 포인터와 달리 string의 pointer 로 취급한다?
char some_characters[10] = "Hello"; // A simple set of characters char *char_ptr = &some_characters[0]; // Pointer to a character
std::cout << some_characters << "\n" // output is "Hello"
std::cout << &some_characters << "\n"l //output is an address
std::cout << some_characters[0] << "\n"l //output is "H"
std::cout << &some_characters[0] << "\n"l //output is "Hello"std::cout << char_ptr << '\n'; // output is "Hello"
// So with string pointers, the string itself is printed.
std::cout << *char_ptr << "\n"; // output is "H"
std::cout << &char_ptr << "\n"; // output is an address
In a similar way, one can define string pointer directly,
```c++
char *test_ptr = "abcde"; // equivalent two step std::cout << "String pointer test= " << test_ptr << "\n"; //output is "abcde" std::cout << " *test= " << *test_ptr << "\n"; //output is "a" std::cout << " &test= " << &test_ptr << "\n"; //output is an address
```
(주의) c++의 pointer 와 array는 같이 방식으로 취급된다.
char array[10] = "012345678";
char *array_ptr = &array[0];
array_ptr=&array[0];
array_ptr= array ; // these two lines are quivalent.
When passing an array to a procedure, C++ will automatically change the array into a pointer
한편, string이 아닌 숫자의 array의 경우는
int array[10] // initialized as 0,1,2,3,4,5,6,7,8,9
std::cout << " array= " << array << "\n"; // output is an addressstd::cout << "&array= " << &array << "\n"; //output is an address same as above
std::cout << "*array= " << *array << "\n"; //output is 0 std::cout << " array[1]= " << array[1] << "\n"; //output is 1 std::cout << "*array[0]= " << *array[0] << "\n"; // error ! this setence is wrong std::cout << "&array[1]= " << &array[1] << "\n"; // output is an address
즉, array 는 array[0]의 위치를 가리키는 pointer 이다. (array와 &array[0]는 동일)
반면, array[0]나 array[1] 은 integer 이고, pointer가 아님.
함수가 다음과 같이 정의 되었을 때
void init_array_1(int data[])
void init_array_2(int *data_ptr)
다음 둘은 같은 역할을 한다.
init_array_1(array);
init_array_1(&array[0]);
그리고
init_array_2(array)
도 비슷하게 사용가능하다.
댓글 없음:
댓글 쓰기