A와 B 둘다 변수라고 할 수 있다. 각기 다른 주소에 기록된 변수인데, B는 포인터 변수이기 때문에 A라는 변수의 주소를 값으로 가지고 있는 것.
int *b = &a;
처럼 "선언할 때" 쓰는 *는 포인터 변수임을 알려주기 위한 목적을 가진다.(이 때 *는 포인터)*b
라고 쓰게 되면, 이것은 포인터 변수 b가 가리키는 주소의 값을 의미한다. 다시말해 5라는 값 자체가 된다.(이때 *는 간접참조연산자
라고 한다.)#include <stdio.h>
int main(void){
int a = 5;
int *b = &a;
printf("%d\n",*b);
return 0;
}
포인터 변수 b가 가리키고 있는 a의 값을 출력하므로 출력값은 5가 된다.
int main(void){
int a = 5;
int *b = &a;
printf("%d", b);
}
출력값 : -486066420
간접참조연산자를 안붙이고 b를 출력하면 a의 주소가 출력되었다.
#include <stdio.h>
int main(void){
int a[] = {1,2,3,4,5,6,7,8,9,10};
int i;
for(i = 0; i < 10; i++){
printf("%d\n", &a[i]);
}
}
결과 :
-354949408
-354949404
-354949400
-354949396
-354949392
-354949388
-354949384
-354949380
-354949376
-354949372
int형이 4byte므로 4씩 증가하는 모습을 볼 수 있다.(아래에서 위로). 배열이란 걸 이용하게 되면 동일한 하나의 자료형을 연속적인 공간에 배치할 수 있다. 다시말해, 4바이트씩 총 10개를 차지하니깐 총 40바이트만큼 차지하는 배열임을 주소연산자를 사용해서 확실하게 확인할 수 있다.
다음과 같은 코드는 굉장히 위험한 코드이다.
int *a = 0x3384735;
*a = 0;
포인터는 다중으로도 사용할 수 있다.
#include <stdio.h>
int main(void){
int a = 5;
int *b = &a;
//여기까지는 포인터 b가 a의 주소값을 가리키고 있다.
//포인터 b또한 컴퓨터에 기록된 일종의 변수이다.
int **c = &b;
//그래서 포인터의 포인터임을 알려주는 **을 사용해 포인터 변수인 b의 메모리 주소값을 가리키도록 할 수 있다.
printf("%d\n", **c);
//포인터 변수 c가 가리키고 있는 주소가 b인 거니까, 그 b가 가리키고 있는 값을 또 참조해야 하므로 **을 붙여줬다.
//출력값 : 5
}
배열과 포인터
int main(void){
int a[] = {1,2,3,4,5,6,7,8,9,10};
int *b = a; //주소연산자를 안붙였다. a라는 배열의 이름자체를 주소값으로 사용하고 있다.
//사실 내부적으로 배열이름 자체는 주소값을 가지고 있기 때문에 이렇게 사용할 수 있다.
printf("%d",b[2]);
//출력값 : 3
return 0;
}