#include <stdio.h>
int main() {
int n = 10;
int *ptr = &n;
printf("address of n: %d\n", &n);
printf("address of n: %d\n", ptr);
printf("value of pointer: %d\n", *ptr);
return 0;
}
address of a: 6422296
address of a: 6422296
value of pointer: 10
포인터도 일종의 자료형이다. int와 char 같은.
포인터 타입의 선언은 [자료형]* [포인터 변수명] = [주소값]으로 한다.
이 때, *의 위치는 상관없다.
Ex)
int ptr: int형 자료가 들어있는 주소값
char ptr: char형 자료가 들어있는 주소값
위 그림에서 변수 n은 10이 할당되어 있고 이는 메모리 어딘가에 저장된다.
int는 4바이트를 차지하므로 00120B14~00120B17까지 주소를 할당받는데 포인터가 가리키는 주소값은 가장 첫 번째다.
(변수의 주소값은 코드를 실행할 때마다 항상 바뀌므로 위 코드의 주소값과 그림의 주소값이 다르다고 의아해할 필요 없다.)
다시 본론으로 돌아와서 위 코드를 해석해보자면
나는 n에 10을 담았고 ptr에 n의 주소를 담았다.
&은 변수의 주소값을 반환하는 문법이다.
따라서 첫번째와 두번째 printf는 n의 현재 주소값인 6422296를 출력한다.
*는 주소값에 들어있는 데이터를 반환하는 문법이다.
위 예시를 보면, ptr에 n의 주소값이 담겨있으므로
*ptr을 하면 n의 데이터인 정수형 10이 반환되는 것이다.
#include <stdio.h>
int main() {
double num = 3.1415;
double* numAddress = #
printf("%d\n", sizeof(numAddress));
printf("%d\n", sizeof(num));
printf("num: %.4f\n", num);
printf("&num: %d\n", &num);
printf("numAddress: %d\n", numAddress);
printf("&numAddress: %d\n", &numAddress);
printf("*numAddress: %.4f\n", *numAddress);
return 0;
}
배열도 일종의 포인터다.
#include <stdio.h>
int main() {
int ary[] = {1,2,3};
printf("array: %d\n", ary);
printf("array0: %d\n", ary[0]);
printf("array1: %d\n", ary[1]);
printf("array2: %d\n", ary[2]);
printf("*array: %d\n", *ary);
return 0;
}
array: 6422292
array0: 1
array1: 2
array2: 3
*array: 1
ary를 출력해보면 주소값인 6422292가 나온다.
즉, 배열도 일종의 포인터 자료형이라고 볼 수 있다.
#include <stdio.h>
int main() {
int ary[] = {1,2,3};
// 포인터는 가변
int* ptr = NULL;
printf("%d\n", ptr);
ptr = ary;
printf("%d\n", ptr);
// 배열은 불변
int num = 5;
ary = #
return 0;
}
expression must be a modifiable lvalue
포인터의 값은 바꿀 수 있지만 배열의 값은 바꿀 수 없다.
따라서, 배열은 포인터 성격을 띠고 있지만 값을 바꿀 수 없다는 점에서 "포인터 상수"라고 볼 수 있다.
#include <stdio.h>
int main() {
int ary[] = {1,2,3};
printf("array: %d\n", ary);
printf("array+1: %d\n", ary+1);
printf("array+2: %d\n", ary+2);
printf("array+3: %d\n", ary+3);
printf("&array: %d\n", &ary);
printf("&array+1: %d\n", &ary+1);
printf("&array+2: %d\n", &ary+2);
printf("&array+3: %d\n", &ary+3);
return 0;
}
array: 6422292
array+1: 6422296
array+2: 6422300
array+3: 6422304
&array: 6422292
&array+1: 6422304
&array+2: 6422316
&array+3: 6422328
포인터+1 연산을 하면 주소값+1이 아니다.
주소값+[자료형 크기]가 된다.
예를 들어, 위 코드의 array는 정수 배열이므로 4바이트다.
따라서, 포인터에 +1을 할때마다 4씩 주소가 커진다.
반면에 &array는 배열 자체의 주소를 의미하기 때문에 4바이트(정수형)*3(길이가 3인 배열이므로) = 12바이트씩 주소가 커진다.
이를 활용하면 아래처럼 배열의 원소값에 접근 가능하다.
#include <stdio.h>
int main() {
int ary[] = {1,2,3};
for (int i=0;i<3;i++) {
printf("%d\n", *(ary+i));
}
return 0;
}
1
2
3