포인터 기본 개념
모든 변수는 주소를 가지고 있다.
따라서 주소와 캐스팅만 알고 있다면 모든 변수에 접근 가능하다.
#include<stdio.h>
int main()
{
int iNum=1;
printf("%p\n", &iNum);
printf("%d\n", *((int*)(0x0019FED8)));
*((int*)(0x0019FED8)) = 200;
printf("%d\n", *((int*)(0x0019FED8)));
printf("%p\n", main);
return 0;
}//0019FED8
포인터 vs 배열
배열은 포인터 상수이다. ~~~!
a vs &a 의 차이
#include<stdio.h>
int main()
{
char a[10] = "ababab";
char* b;
char(*c)[10];
// a ,a& 모두 값은 같다.
b = a; // a 는 char* type
c = &a; // &a 는 char (*)[10] type
printf("a = %p\n", a);
printf("a+1 = %p\n", a+1);
printf("&a = %p\n", &a);
printf("&a+1 = %p\n", &a+1);
printf("b = %p\n", b);
printf("b+1 = %p\n", b + 1);
printf("c = %p\n", c);
printf("c+1 = %p\n", c + 1);
}
a 는 char type pointer 임으로 1칸씩 증가
&a 는 char (*)[10] type 으로 10 칸씩 메모리가 증가한다.
-> 즉 배열을 넘길때는 char(*)[10] 등 배열의 type 을 정확히 명시해 줘야한다 .
배열 심화
다차원 배열에서 * 의 역활
#include<stdio.h>
int main()
{
char a[4][4] = { {1,12,13,14} ,{2,22,23,24}, {3,},{4,} };
char(*p1)[4];
char(*p2)[2][2];
p1 = a;
p2 = a;
printf("p = %p\n", p1);
printf("p+1 = %p\n", p1+1);
printf("p1[1][1] : %d\n", p1[1][1]);
printf("*((char *)(p1+1)+1) : %d\n", *((char *)(p1+1)+1));
printf("*(*(p1 + 1) + 1) : %d\n", *(*(p1 + 1) + 1)); //*p1 은 char 형태이다.
printf("p1 : %p\n", p1);
printf("p1+1 : %p\n", p1+1);
printf("*p1 : %p\n", *p1);
printf("*p1+1 : %p\n\n", *p1+1);
printf("p2 : %p\n", p2);
printf("p2+1 : %p\n", p2 + 1);
printf("*p2 : %p\n", *p2);
printf("*p2+1 : %p\n", *p2 + 1);
printf("**p2 : %p\n", **p2);
printf("**p2+1 : %p\n", **p2 + 1);
char *c;
char(*c1)[2];
p1 = 100;
//*p1 = 100;
//*c = *p1;
c = *p1 ;
c1 = *p2;
//*p2 = 123;
**p1 = "ㅁㄴㅇㄹㄴㅁ";
}
1. char(*p1)[4];
P1 은 char (*)[4] tyep 이고 a 배열의 첫번째 주소를 가지고 있다.
*p1 은 char[4] type 이고 a 배열의 첫번째 주소를 가지고 있다.
char[4] 는 조금 특이한 char* 라 생각 하면된다. 덧셈 연산에서 char 의 크기만큼 움직이는 것은 똑같다.
때문에 , *((char *)(p1+1)+1) , *(*(p1 + 1) + 1) 식은 동일한 결과를 얻는다.
**p1 은 char type 이고 a 배열의 첫번째 주소의 값을 나타낸다.
2. char(*p2)[2][2] 의 경우
위와 거의 동일함
*p2 = char[2][2] type 으로 char (*)[2] type 으로 생각하면 된다.
**P2 = char[2] type 으로 char * type 으로 생각하면 된다.
결론 : * 쓸때마다 한 단계 씩 들어가는 느낌
배열 심화의 심화
포인터 배열의 포인터
#include<stdio.h>
int main()
{
char* p1[4][4]; // 2차원 포인터 배열
char* (*p2)[4]; // 2차원 포인터 배열의 주소값을 받는 char* (*)[4] type 포인터
char* (*p3)[4][4]; // 전체 2차원 배열을 가리키는 포인터
p2 = p1; // 문제 없이 동작
p3 = &p1;
printf("p1 : %p\n", p1);
printf("p1+1 : %p\n", p1+1); // 16byte 씩 증가 주소값은 4byte 임
printf("p2 : %p\n", p2);
printf("p2+1 : %p\n", p2+1);
printf("*p2 : %p\n", *p2);
printf("*p2+1 : %p\n", *p2 + 1);
printf("p3 : %p\n", p3);
printf("p3+1 : %p\n", p3 + 1);
printf("*p3 : %p\n", *p3);
printf("*p3+1 : %p\n\n", *p3 + 1);
**p2 = 1; // p2 2차원배여 [0][0] 번째 주소 = 1로 설정
printf("**p2 : %p\n", **p2);
printf("**p2+1 : %p\n", **p2+1);
return 0;
}
p2 는 4개의 포인터를 같는 배열을 가리키는 포인터 임으로 한번에 4*4 = 16 byte 씩 움직인다.
이 그림이 이해하는데 조금은 도움이 될까 ?
'공부,일 > c언어' 카테고리의 다른 글
sizeof 와 포인터 & 배열의 data type (0) | 2021.06.01 |
---|---|
void pointer , malloc (0) | 2021.06.01 |
Code 영역 (0) | 2021.05.31 |
배열&문자열 함수 (0) | 2021.05.30 |
포인터 2 메모리 직접 다루기 (0) | 2021.05.26 |
댓글