int arr[4] {}; 를 정의했을 때


cout << arr;

cout << &arr

의 출력은 같다는 걸 발견할 수 있다.

2018-02-18

arr은 0번째 원소의 주소를 담고있는 포인터 즉 [arr[0]의 타입]* 타입(여기선 int* 타입)

&arr은 arr의 주소를 담고있는 상수 포인터. 즉 [arr의 타입]* 타입이다. (컴파일러는 arr의 크기를 알고있음)

둘이 같은 이유는 arr은 배열의 첫 원소가 할당된 지점이고 &arr은 배열이 할당된 지점이기 때문이다.


2018-02-21

배열이름이 반드시 포인터인 것은 아니다! 단지 포인터로 decaying 할 뿐이다. 

(출처 : https://stackoverflow.com/questions/1461432/what-is-array-decaying)


배열이름이 포인터로 디케잉 하지않는 특수상황 :

(https://stackoverflow.com/questions/17752978/exception-to-array-not-decaying-into-a-pointer)

1. when it's the argument of the & (address-of) operator.

2. when it's the argument of the sizeof operator.

3. When it's a string literal of type char [N + 1] or a wide string literal of type wchar_t [N + 1] (N is the length of the string) which is used to initialize an array, as in char str[] = "foo"; or  wchar_t wstr[] = L"foo";.



배열의 이름은 첫 번째 원소를 가르키는 상수 포인터로 변환된다. 

하지만 배열의 이름이 예외적으로 다르게 쓰이는 경우가 있는데 그중 하나는 sizeof(arr)과 같이 sizeof의 대상으로 쓰였을 때다.

(출처: https://en.wikipedia.org/wiki/Sizeof#Application_to_arrays)

cout << sizeof(arr)        //16

cout << sizeof(&arr)        //4

sizeof 에 배열의 이름을 쓸 수 있는 상황은 이미 컴파일러가 배열의 크기를 알고있는 상황이기 때문에,(C/C++의 컴파일러는 왜 배열의 크기를 알아야 할까?) sizeof는 &arr에 사용했을 때 처럼의 포인터 크기 4 대신 사용하는 배열 전체의 크기(여기선 4*4 16)를 출력한다. 


그런데 arr + 1과 &arr + 1의 경우는 위와 느낌이 다르다.

위의 흐름대로라면 arr + 1은 배열 한칸의 크기를, &arr + 1이 4바이트 한 칸의 크기를 건너야 할 것 같지만 실상은 반대다.

arr의 주소가 1000이라고 할 때

arr + 1 == 1004

&arr + 1 == 1016이다. 

&arr + 1이 배열 전체크기를 건너 뛸 수 있는 것도 arr의 크기를 컴파일러가 알고있을 때에만 가능한 결과다. 

2018-02-18

arr + 1의 결과는 arr의 타입이 무엇이냐에 따라 다르다. 여기서 arr은 포인터인데 첫 번째 원소의 주소를 담는 포인터이므로 연산의 이동거리는 첫 번째 원소의 타입의 크기만큼이다.여기선 arr[0]은 int이므로 4바이트. + 연산의 결과(리턴값)는 &arr[0]에서 이동한 &arr[1]이다.

&arr도 상수 포인터인데 arr의 타입의 주소를 담는 포인터다. 여기서는 배열이므로 이때의 이동거리는 arr의 크기만큼이 될 것이다. (컴파일러가 알고있다면)


마지막으로 배열 이름을 함수의 인자로 넣는다면 함수 안에서는 그저 포인터로 취급(decaying)될 뿐이다. 이 때 포인터도 복사가 되기에 &arr은 복사된 포인터의 주소라는걸 기억하자.



다음은 공부를 위해 테스트를 진행한 코드. (별로 중요하지 않음)

void testA(int a[])

{

cout << "\n testA  함수 내의 작동 :\n";

cout << a << endl;

cout << a + 1<< endl;

cout << &a << endl;

cout << &a + 1 << endl;

cout << "------\n";

}


int main()

{

int arr[4] = { 0, 1, 2 };


cout << "arr : " << arr << endl;

cout << "arr + 1 : " << arr + 1 << endl;

cout << "&arr + 1 : " << &arr + 1 << endl;

cout << "&arr + 1 - &arr : " << int(&arr + 1) - int(arr) << endl;


testA(arr);


cout << sizeof(arr) << endl;

cout << sizeof(&arr) << endl;


    return 0;

}

실행결과: