본문 바로가기
공부,일/c언어

포인터

by fromnothing1 2021. 5. 24.

 

포인터 기본 개념 

 

모든 변수는 주소를 가지고 있다. 

따라서 주소와 캐스팅만 알고 있다면 모든 변수에 접근 가능하다.

#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

댓글