본문 바로가기
  • 시간(時間)을 아끼는 방법은 시간을 낭비하지 않는것


C_ language/C언어 심화_모각코

C언어_심화_이중 포인터

by pk7912 2022. 5. 10.
728x90
728x90

커뮤니티_모각코 (모여서, 각자, 코딩) 활동을 하면서 배운 내용을 되새기며 쓴 글입니다.

코딩을 배우고 싶다면 코뮤니티 활동을 적극 추천합니다.

https://cafe.naver.com/codeuniv 

 

코딩 커뮤니티 - 코뮤니티 [파이썬/... : 네이버 카페

코뮤니티 [코딩공부/독학/스터디/대외활동] : python, C언어, java, 자바스크립트, HTML, CSS, 웹/앱개발

cafe.naver.com

 


이중 포인터란?

이중 포인터를 알려면 포인터부터 알아야 합니다.

포인터란?

어떤 값이 들어있는 메모리의 주소를 가리키는 변수입니다.

그럼 이중 포인터는 포인터의 주소를 가리키는 포인터입니다.

 

예시)

#pragma warning(disable : 4996)
#include <stdio.h> 

int main() 
{ 
	int num1 = 10;
    
    int* ptr = &num1; // ptr => num1의 메모리 주소 
    
    int** pptr = &ptr; // pptr => ptr의 메모리 주소
    
    printf("pptr : %p\n\n", pptr); 
    
    printf("*pptr : %p\n", *pptr); 
    
    printf("ptr : %p\n\n", ptr); 
    
    printf("**pptr: %d\n", **pptr); //포인터를 두 번 역참조! 
    
    printf("num1 : %d", num1); 
    return 0; 
}

출력)

pptr : 004FF9B4 

*pptr : 004FF9C0 
ptr : 004FF9C0 

**pptr: 10 
num1 : 10

이중포인터 " 포인터를 값으로 갖는 포인터 "를

바로 아래와 같은 구조로 이뤄진 셈이죠!

 

 

2차원 배열과 이중 포인터의 관계

 

#pragma warning(disable : 4996)
#include <stdio.h>

int main()
{
	int num[2][3] = {{1, 2, 3},{11, 12, 13}};
    
    printf("num			: %p\n", num);
    printf("num[0] 		: %p\n", num[0]);
    printf("&num[0][0]  : %p\n\n", &num[0][0]);
    printf("num[1] 		: %p\n", num[1]); 
    printf("&num[1][0]	: %p\n", &num[1][0]);

출력)

num 		: 00AFF6D0 
num[0] 		: 00AFF6D0 
&num[0][0]	: 00AFF6D0 

num[1] 		: 00AFF6DC 
&num[1][0]	: 00AFF6DC

*포인터 = 배열에서 배열의 주소 값과 배열의 0번째 인덱스의 주소는 같다. 

 

2차원 배열에서 배열의 이름의 값은 이중 포인터와 같다.

예시)

#pragma warning(disable : 4996)
#include <stdio.h> 

int main() 
{ 
	int num[2][3] = { {1, 2, 3}, {11, 12, 13} }; 
    
    printf("num : %d\n", num); 
    printf("num+1 : %d\n\n", num+1); 
    
    printf("num[0] : %d\n", num[0]); 
    printf("num[0]+1 : %d\n", num[0]+1); }

출력)

num : 5242464 
num+1 : 5242476 

num[0] : 5242464 
num[0]+1 : 5242468

 

num 배열은 2행 3열의 배열입니다.

한 행에 int 자료형 4byte가 3개씩 12byte 단위로 묶여있기 때문에

주소 값 + 1이 12씩 증가하게 됩니다.

 

 

 

Call by value, Call by reference (이중 포인터 함수)

#pragma warning(disable : 4996)
#include <stdio.h>

void swap(int **num1, int **num2)
{
	int * tmp;
    tmp = *num1;
    *num1 = *num2;
    *num2 = tmp;
}

int main()
{
	int num1 = 10;
    int num2 = 20;
    
    int *p_num1 = &num1;
    int *p_num2 = &num2;
   
   	printf("변경전\n"); 
  	printf("num1 : %d\n", *p_num1); 
   	printf("num2 : %d\n\n", *p_num2);

    swap(&P_num1, &p_num2);
    
    printf("변경후\n"); 
    printf("num1 : %d\n", *p_num1); 
    printf("num2 : %d\n\n", *p_num2);

    return 0;
)

 

출력)

변경전 
num1 : 10 
num2 : 20 

변경후 
num1 : 20 
num2 : 10

swap 함수 실행 이전까지는 변수들이 아래의 포인터 관계를 가집니다.

 

하지만 swap함수가 실행된 이후, 아래와 같이 포인터 tmp가 추가되고,

각 변수의 주소 값이 아래와 같이 변경됩니다.

 


 

practice

최댓값 구하기

 

이중 포인터와 크기가 5인 배열을 선언하고,

함수를 사용해서 입력된 수 중 최댓값을 출력해보세요.

 

조건

  • 함수는 void형입니다.
  • 최대값을 저장하는 이중 포인터 변수는 main함수에 초기화해야 합니다.
#pragma warning(disable : 4996)
#include <stdio.h>

void print_max(int* arr, int** maxx, int size); 

int main() 
{ 
	int arr[5] = { 0, }; 
    int* max; 
    int size = sizeof(arr) / sizeof(int); 
    
    printf("5개의 숫자를 입력하시오.\n"); 
    for (int i = 0; i < 5; i++) 
    { 
    	scanf_s("%d", &arr[i]); 
    } 
        
    print_max(arr,&max, size); 
    
    return 0; 
} 

void print_max(int* arr, int ** maxx, int size) 
{ 
	int * max_num = arr; 
    
    for (int i = 0; i < size; i++) 
    { 
    	if (*max_num <= arr[i]) 
        	max_num = &arr[i]; 
    } 
    *maxx = max_num; 
    
    printf("\n\n최대값 : %d\n", **maxx); 
    
}

code


 

마무리

값의 메모리 주소를 저장하는 게 포인터 -> 그 포인터 주소를 저장하는게 이중 포인터

2차원 배열은 이중 포인터로

함수에서 매개변수로 이중 포인터를 사용할 수 있다. 함수에서 이중 포인터로 스왑 하면 

메모리 안의 값은 서로 바뀌나 주소 값은 유지된다.

 

포인터가 어려워서 다들 포기한다는 말을 많이 들어서 배우기 전에 엄청 졸았었네요...

배우고, 이해하고 넘어간다 생각했는데...

다시 들여다보니 전혀 이해 못 했네요 ㅎㅎ;;

정리할 때마다 새로운 게 이상하네요.... 분명 열심히 공부했었는데...

 

 

댓글