Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

나의 IT일지

이중 포인터 본문

프로그래밍 언어/C언어

이중 포인터

세레프 2023. 2. 23. 04:20

 포인터 변수의 주소를 저장하는 공간으로, 변수를 사용할 때 변수의 이름이 아닌 주소로 접근하기 위해 사용한다.

 

포인터의 기본

C언어는 컴퓨터의 메모리 주소를 이용해 메모리 안에 기억되어 있는 값을 제어할 수 있는 시스템 프로그래밍이 가능한 언어이다. 즉, 컴퓨터안의 메모리 주소에 접근이 가능하며, 그 안의 값을

my-it-diary.tistory.com

생성방법 주소저장 변수값 접근
포인터형 * 포인터명;

ex) int *ptr;
포인터=&변수명;

ex) ptr = ar;
* 포인터명;

ex) * ptr;

 이때, 생성방법에서 포인터형은 생성할 포인터의 자료형이 아닌, 포인터에 저장할 변수의 자료형을 적는다.

 

 포인터에 저장되어 있는 주소 값도 데이터이며, 데이터를 저장하는 공간은 변수라고 했다. 즉, 주소값를 저장한 포인터도 변수의 일종이고, 다른 포인터에 주소를 저장하고 가리키는 것도 가능하다. 그렇다면 포인터의 주소를 어떻게 저장할 수 있을까?

 

이중 포인터

 포인터의 주소는 일반 변수에 저장할 수 없다.그래서 우리는 포인터 주소를 저장할 수 있는 포인터를 만들어야 한다. 그 역할하는 것이 중포인터이다. 이중포인터란 일반 변수의 주소를 저장하고 있는 포인터의 주소를 저장하는 포인터로, 다중포인터중 하나이다.

포인터형** 변수명;

 위의 구조는 이중포인터를 만드는 구조로, 포인터를 만드는 구조와 비슷하다. 차이점이 있다면, 포인터 기호가 2개있다는 점이다. 변수의 값을 출력할 때도 마찬가지로 포인터와 비슷한 구조이지만, 포인터 기호를 2개 사용한다는 점에서 차이점이 생긴다.

** 포인터명; 

 

#include<stdio.h>

int main() {
	int num1 = 10, num2;
	num2 = 20;

	int* pnum1 = &num1, *pnum2;
	pnum2 = &num2;

	int** dpnum1 = &pnum1, ** dpnum2;
	dpnum2 = &pnum2;

	int sum, psum, dpsum;
	sum = num1 + num2;
	printf("num1+num2:%d\n", sum);

	psum = *pnum1 + *pnum2;
	printf("*pnum1+*pnum2:%d\n", psum);

	dpsum = **dpnum1 + **dpnum2;
	printf("**dpnum1+**dpnum2:%d\n", dpsum);


	return 0;
}

  변수와 포인터 이중포인터의 구조를 비교하면 다음과 같다.

  생성 출력
변수 자료형 변수명; 포인터명; 
포인터 자료형* 변수명; * 포인터명;  
이중포인터 자료형** 변수명; ** 포인터명; 

 

 이중포인터와 배열

#include<stdio.h>

void main() {
	int ar[] = { 1,2,3,4,5 };
	int* par, ** dpar;
	par = ar;
	dpar = &par;
	printf("ar[0]:%d", ar[0]);
	printf("*par:%d", *par);
	printf("**dpar:%d", **dpar);

}

 위의 코드를 보면, 배열명을 포인터에 저장하고 포인터의 주소를 이중포인터에 저장하는 것을 확인 할 수 있다. 그리고 출력 결과를 보면, 다 같은 값을 같는 것을 확인 할 수 있다.  즉, ar[0]과 *par과 **dpar은 같은 변수를 가리키고 있다는 것을 알 수 있다. 이때, 변수명은 포인터와 같이 주소값을 가지지만, 포인터가 아니기 때문에, &변수명으로 이중포인터에 저장할 수 없다. 즉, "**par = &ar"은 불가능 하다.

 

 그리고 "이름[번호]"와 "*(이름+번호)"은 같은 표현이며, "*par"는 "*(par+0)"을 생략해서 사용한 것이기에, "*par" 대신에 "par[0]"를 사용해도 똑같은 결과가 나온다. 이중 포인터도 마찬가지로 "**dpar"은 "*(*(dpar+0)+0)"을 생략해서 사용한 것이기에, "dpar[0][0]"을 사용해도 된다.

#include<stdio.h>

void main() {
	int ar[] = { 1,2,3,4,5 };
	int* par;
	int** dpar;
	par = &ar;
	dpar = &par; //이중포인터에 포인터의 주소를 저장
	printf("ar[0]:%d\n", ar[0]);
	printf("*par:%d\n", par[0]);
	printf("**dpar:%d\n", dpar[0][0]);

}

 정리하자면 포인터의 [ ]의 갯수는 *의 갯수와 같으며, 다음과 같이 설명할 수 있다.

*(포인터명+주소 증감량) = 포인터명[주소 증감량]

 예를들면 "**ppa"라고 했을 때, "*(*(ppa+0)+0)"이기에 "ppa[0][0]"이 된다. 만약 "ppa[1][0]"일 경우, "ppa"에 저장되어 있는 주소값에 "+1"한 뒤, 그 주소에 있는 포인터의 값에 위치하는 변수의 값을 출력하게 된다.  "ppa[0][1]"경우에는 "ppa"에 저장되어 있는 주소값에 있는 포인터의 값에 "+1"한 뒤, 그 위치에 있는 변수의 값을 출력하게 된다. 즉 "a[1]"을 출력하게 된다.

'프로그래밍 언어 > C언어' 카테고리의 다른 글

동적 메모리 할당 1  (0) 2023.02.25
포인터 배열과 배열 포인터  (0) 2023.02.24
함수와 포인터  (0) 2023.02.22
배열과 포인터  (0) 2023.02.21
포인터 연산  (0) 2023.02.19
Comments