역할
형식
데이터형 **변수명
→ int **ptr;
활용
이중 포인터 활용(1)
포인터 변수의 메모리 주소를 저장
#include <stdio.h>
#include <stdlib.h>
int main(void){
    int var = 12;
    int *ptr;
    int **pptr;
    ptr = &var;
    pptr = &ptr;
    printf("%ld %ld %p %p %p\\n", sizeof(ptr), sizeof(pptr), ptr, pptr, &pptr);
    printf("%p %p %d\\n", pptr, *pptr, **pptr);
    return 0;
}
이중 포인터의 활용(2)
열의 개수가 서로 다른 배열을 다룸(배열보다는 메모리를 다룬다고 생각할 수 있다.)
int **pptr;
1단계 : pptr = (int **)malloc(sizeof(int *) * 3);
2단계 :
pptr[0] = (int*)malloc(sizeof(int) * 4);
pptr[1] = (int*)malloc(sizeof(int) * 2);
pptr[2] = (int*)malloc(sizeof(int) * 3);
#include <stdio.h>
#include <stdlib.h>
int main(void){
    int **pptr, i;
    pptr = (int**)malloc(sizeof(int*)*3); // 행 선언
    pptr[0] = (int*)malloc(sizeof(int)*4); // 열 선언
    pptr[1] = (int*)malloc(sizeof(int)*2); // 열 선언
    pptr[2] = (int*)malloc(sizeof(int)*3); // 열 선언
    pptr[0][0] = 1;
    pptr[0][1] = 2;
    pptr[0][2] = 3;
    pptr[0][3] = 4;
    pptr[1][0] = 10;
    pptr[1][1] = 20;
    pptr[2][0] = 100;
    pptr[2][1] = 200;
    pptr[2][2] = 300;
    printf("%d %d %d %d\\n", pptr[0][0], pptr[0][1], pptr[0][2], pptr[0][3]);
    printf("%d %d\\n", pptr[1][0], pptr[1][1]);
    printf("%d %d %d\\n", pptr[2][0], pptr[2][1], pptr[2][2]);
    for(i = 0; i < 3; i++){
        free(pptr[i]); // 각각 시작하는 메모리주소를 가지고 있다.  열을 선언한 메모리를 해제하는 행동
    }
    free(pptr); // 행 선언한 메모리를 해제 하는 행동
    
    return 0;
}
이중 포인터의 활용(3)
길이가 다른 문자열을 다룰 때 → 메뉴 구성
ex)
1. 관리자 모드
2. 로그인
3. 로그아웃
#include <stdio.h>
#include <stdlib.h>
int main(void){
    char menu1[] = "1. 관리자 모드";
    char menu2[] = "2. 로그인";
    char menu3[] = "3. 로그아웃";
    char **ppmanu;
    int i;
    ppmanu = (char**)malloc(sizeof(char*)*3);
    ppmanu[0] = menu1;
    ppmanu[1] = menu2;
    ppmanu[2] = menu3;
    printf("------(( 메뉴 ))------\\n");
    for(i = 0; i < 3; i++){
        printf("%s\\n", ppmanu[i]);
    }
    printf("----------------------\\n");
    free(ppmanu);
    
    return 0;
}