본문 바로가기
공부/TIL

[TIL]2022/03/09

by 노르웨이모리 2022. 3. 9.

C 포인터 연산

 

int main()
{
    int arr[3] = { 1,2,3 };
    
    printf("%p\n", arr);
    printf("%p\n", arr + 1);
    printf("%p\n", arr + 2);
    
    printf("%p\n", &arr[0]);
    printf("%p\n", &arr[1]);
    printf("%p\n", &arr[2]);
    return 0;
}

위에 세개랑 아래 세개는 같은 값을 출력한다. 

arr는 배열의 첫 원소를 가리키는 포인터이다. 여기에 + 1을 하면 주소값(16길이의 hex)에 + 1을 하는 게 아니라 배열의 원소의 크기 만큼 1 번 더한다는 뜻이다. arr + 1을 하면 arr 주소값에 arr 배열 원소의 크기를 한 번 더한다. arr + 2을 하면 arr 주소값에 arr 배열 원소의 크기를 두 번 더한다.

포인터 + 1 를 하면 포인터가 가리키는 주소 + 포인터가 가리키는 자료형 크기 * 1 이다. 배열이 아닌 그냥 단일 자료형을 가리키는 포인터라도 마찬가지이다. 다음 코드를 보면 int를 가리키는 포인터 a에 + 1 을 했을 때, a의 주소 + a가 가리키는 자료형(int)의 크기 * 1만큼 더해진 것을 알 수 있다.

int* a;
int b = 1;
a = &b;
printf("%p\n", a);
printf("%p\n", a + 1);

output:
0x0000003e69effaa4
0x0000003e69effaa8

 

그러니까 포인터 연산할 때는 포인터가 가리키는 자료형 만큼의 크기를 곱해서 더해지기 때문에 arr + sizeof(int)*1로 해야 하는 게 아닐까? 이런 의문은 틀린 거다. 이미 arr + 1가 그 의미를 내포하고 있다. 그러니까 arr + sizeof(int)*1는 arr + 4와 같은 의미를 지니는 것이다.

 

 

추가로 arr + 1 vs &arr + 1

 

arr는 배열 첫번째 원소의 포인터. 

&arr는 배열 전체에 대한 포인터.

 

예를 들어 arr가 다음과 같다고 하자.

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

arr는 int 형을 가리키는 포인터이기 때문에 + 1을 하면 int의 크기 만큼 한 번 더해진다.

&arr는 (int*)[5]형을 가리키는 포인터이기 때문에 +1을 하면 int[5] 크기 만큼 한 번 더해진다.

https://www.log2base2.com/C/pointer/arr+1-vs-address-of-arr+1.html 

 

arr+1 vs &arr+1

arr+1 vs &arr+1 int arr[5] = {10,20,30,40,50}; Here, arr is an integer pointer (int*) which points the first element of the array. &arr is an integer array pointer (int*)[5] which points the whole array. (all five elements.) &arr + 1 arr + 1 &arr is a poin

www.log2base2.com

 

 

(int*p)[3] vs int *p[3] 

https://www.geeksforgeeks.org/difference-between-int-p3-and-int-p3/

 

Difference between int (*p)[3] and int* p[3]? - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

(int*p)[3]는 int[3] 배열을 가리키는 포인터 p란 뜻.

int *p[3]는 int*를 가리키는 p[3] 배열이란 뜻.

'공부 > TIL' 카테고리의 다른 글

[TIL]2022/03/22 C 다중소스 분할 컴파일  (0) 2022.03.22
[TIL]2022/03/08  (0) 2022.03.08
[TIL]2022/03/05  (0) 2022.03.05
[TIL]2022/03/01  (0) 2022.03.01
[TIL]2022/02/22  (0) 2022.02.22