와드의 블로그

17. 다차원 포인터 본문

프로그래밍 언어/C

17. 다차원 포인터

Ward 2021. 9. 17. 23:49

(1) 다차원 포인터 개념

 

* 다차원 포인터란?

다차원 포인터는 간접으로 여러 번 가리키는 포인터이다. 포인터 변수를 선언할 때  * 키워드를 한 개만 사용한 포인터를 1차원 포인터라고 이야기하며 * 키워드를 하나씩 더 사용할 때마다 차원이 하나씩 증가한다. 이처럼 * 키워드를 두 개 이상 사용해서 선언한 포인터를 다차원 포인터라고 한다.

 

(2) 2차원 포인터

 

* 2차원 포인터의 선언과 사용

2차원 포인터는 다음과 같이 * 키워드를 두 개 사용해서 선언한다.

int** pp;

그래서 포인터를 사용할 때, pp, *pp, **pp처럼 * 연산자를 최대 2개까지 사용할 수 있다.

 

* 2차원 포인터의 구성

2차원 포인터는 1차원 포인터의 주소 값을 저장하는 데 사용된다.

int **pp, *p, data = 3;
p = &data;
pp = &p;
**pp = 5;

* 2차원 포인터가 가리키는 대상을 동적으로 할당하기

1차원 포인터는 동적으로 할당한 메모리의 주소 값을 받아 사용할 수 있다. 마찬가지로 2차원 포인터를 malloc 함수를 통해 할당받아서 사용할 수 있다.

int **pp, data = 3;
pp = (int**)malloc(sizeof(int*));
*pp = &data;
**pp = 5;

※ 2차원 포인터가 가리키는 대상을 동적으로 할당하면 좋은 점

동적 할당으로 4바이트 보다 큰 바이트를 할당 받으면 여러 주소를 한 번에 저장하여 주소들의 배열처럼 사용할 수 있다.

 

(3) 2차원 포인터와 함수의 매개변수

 

* 함수의 매개변수로 2차원 포인터 사용하기

#include <stdio.h>
#include <stdlib.h>

void GetMyData(int** q) { // q에 저장된 값(p의 주소)에 4바이트의 메모리 할당
	*q = (int*)malloc(sizeof(int)); 
}


int main()
{
	int* p;
	GetMyData(&p); 
	*p = 5;
   	printf("%d", *p);
	free(p);

	return 0;
}

p의 주소를 할당하기 위해 p의 포인터를 넘기고 이차원 포인터 q로 받으면 함수에서 포인터 변수 p의 메모리 할당이 가능하다.

 

(4) 2차원 포인터와 2차원 배열

 

* 여러 개의 1차원 포인터를 정적으로 할당하기

int* 형식의 1차원 포인터가 100개 필요하면 다음과 같이 선언한다.

int *p[100];

하지만 위와 같은 표현은 변수 p의 메모리 크기가 고정되어 버리므로 만약 포인터가 100개 초과로 필요할 때는 소스 파일을 변경한 후 다시 컴파일해야 한다. 또한 400바이트의 메모리를 할당했는데 5개의 포인터만 사용하는 경우 메모리가 낭비된다. 따라서 포인터 변수들을 동적으로 할당하는 것이 좋다.

 

* 여러 개의 1차원 포인터를 동적 할당하기

malloc 함수로 4 * n 바이트의 메모리를 할당하여 2차원 포인터에 저장하면 그 메모리를 n개의 1차원 포인터와 같이 사용할 수 있다.

int n;
int** pp;
scanf("%d", &n);
pp = (int**)malloc(sizeof(int*) * n);

 

* 2차원 배열과 동적 메모리 할당

다음은 어떤 회사에서 직원들의 체력을 테스트한 결과를 저장하는 프르그램이다. 1분간 윗몸 일으키기를 한 횟수를 연령대 별로 저장한다. 이 코드에서 2차원 배열과 같은 용도로 사용할 수 있는 메모리를 동적으로 할당하는 방법이 나온다.

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int* p_limit_table; // 연령별 인원수를 저장할 포인터
	int** p; // 연령별 윗몸 일으키기 횟수를 저장할 2차원 포인터
	int age_step, tmp;

	printf("20대부터 시작해서 연령층이 몇 개인가요? : ");
	scanf("%d", &age_step);
	
	p_limit_table = (int*)malloc(sizeof(int) * age_step); // 연령별 인원수를 저장할 메모리를 만든다.
	p = (int**)malloc(sizeof(int*) * age_step); // 직원들의 체력 테스트 결과를 저장할 메모리를 만든다.

	for (int i = 0; i < age_step; i++) {
		printf("\n%d0대 연령의 윗몸 일으키기 횟수\n", i + 2);
		printf("이 연령대는 몇 명입니까? : "); // 해당 연령대에 소속된 인원수를 입력 받는다.
		scanf("%d", &tmp);

		*(p_limit_table + i) = tmp;
		*(p + i) = (int*)malloc(sizeof(int) * tmp); // 인원수만큼 메모리를 할당한다.

		for (int j = 0; j < *(p_limit_table + i); j++) { // 연령대별 직원 순서대로 윗몸 일으키기 횟수를 입력 받는다.
			printf("%dth : ", j + 1);
			scanf("%d", &tmp);
			*(*(p + i) + j) = tmp;
		}
	}
	
	printf("\n\n연령별 평균 윗몸 일으키기 횟수\n");

	for (int i = 0; i < age_step; i++) {  // 연령대 별로 윗몸 일으키기 횟수의 평균값을 출력한다.
		printf("%d0대 : ", i + 2);
		int sum = 0;
		for (int j = 0; j < *(p_limit_table + i); j++)
			sum += *(*(p + i) + j);
		printf("%5.2f\n", (double)sum / *(p_limit_table + i));

		free(*(p + i));
	}

	free(p);
	free(p_limit_table);

	return 0;
}

 

 참조자료: C언어 입문

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

19. 파일 입출력  (0) 2021.09.18
18. 구조체  (0) 2021.09.17
16. 메모리 할당  (0) 2021.09.17
15. 배열과 포인터  (0) 2021.09.17
14. 표준 입력 함수  (0) 2021.09.16