title: “C언어 간접 참조 연산자-와 포인터 연산” categories:

  • C

    #C언어 간접 참조 연산자*와 포인터 연산 : 네이버 블로그

전 포스팅에서는 포인터에 변수의 주소를 저장하는 방법을 알아보았다.

포인터는 변수의 주소를 저장하는 역할만이 아닌 포인터를 통해 값을 읽어오거나 변경할 수 있다.

포인터p가 가르키는 주소에 저장된 내용을 읽으려면 *p를 하면 된다

이것을 포인터(주소)를 통해 메모리를 간접참조 한다고 한다.

아래 예제를 보자

#include 
int main() {
 int i = 3000;
 int \*p = NULL;
 p = &i //주소를 p에 대입
 printf("%u\n", p);
 printf("%u\n", &i);
 printf("%d\n", i);
 printf("%d\n", \*p);
}

실행 해보았는가? p와 &i는 같고 i와 *p가 같다.

즉 *를 사용하여 주소의 메모리를 참조 할 수 있다. 참조하는 크기는 선언된 포인터의 자료형으로 계산된다.

포인터의 연산은 포인터의 자료형에 따라 결과가 달라진다

#include
int main() {
 char \*pc;
 int \*pi;
 double \*pd;

 pc = (char \*)10000; //주소를 10000으로 초기화
 pi = (int \*)10000;
 pd = (double \*)10000;
 printf("증가 전 char %d int %d double %d\n", pc, pi, pd);
 pc++; //1씩 올린다
 pi++;
 pd++;
 printf("증가 후 char %d int %d double %d\n", pc, pi, pd);
}

증가 후 각 포인터의 값은 1의 상승이 아닌 각 자료형의 크기만큼 올라간다.

즉 포인터 변수의 계산은 자료형에 따라 달라진다.

아래 예제를 통해 포인터 변수 참조와 포인터 연산에 대해 알아보자

#include
int main() {
 int i = 10;
 int \*pi = &i //이는 int \*p; p=&i와 같다. \*p=&i가 아니다
 printf("i = %d, pi = %u\n", i, \*pi);
 (\*pi)++; //pi의 주소를 참조한 값은 1 올린다
 printf("i = %d, \*pi = %u\n\n", i, \*pi);
 \*pi++; //참조하기전 pi의 값을 올린다
 printf("i = %d, \*pi = %u\n\n", i, \*pi); //\*pi보다 4 큰 메모리의 주소에 있는 데이터이다
}

위의 예제에서 알아야 하는 것은 *가 어디에 있느냐에 따라 결과가 달라진다.

*pi는 pi에 저장된 주소의 데이터를 참조한다. 중요한것은 *(pi)++를 해야지 pi의 주소를 참조한 후 ++가 진행되지 *pi++를 하면 ++가 진행된 후 *(참조)가 진행된다

즉 참조할 메모리의 값을 바꾸는 것이 아닌 메모리를 참조하는 값을 바꾸려는 것이라면

*를 사용해 먼저 불러온 후 이후 계산을 해야한다.

#include
int main() {
 int data = 0x1A2B3C4D; //16진수 0x0A0B0C0D
 printf(" %x\n", data);
 char \*pc;
 pc = (char \*)&data //&data를 char로 참조
 for (int i = 0; i < 4; i++)
 {
 printf(" %x\n", \*(pc + i));
 }
}

즉 int data로 4까지의 주소를 char형으로 1로 나누게 되어

0A0B0C0D가 저장된 메모리를 4개로 나누게 된다.

나눠진 결과로는 4d 3c 2b 1a로 메모리의 주소가 1씩 올라가며 메모리를 참조한다.

왜 역순으로 저장되는것인지는 모르겠으나 int형 4바이트를 char형 1바이트로 형변환 후 하나씩 출력했다는 사실을 알 수 있다.

업데이트: