본문 바로가기

C언어

Chapter 5. 포인터의 포인터

Chapter 5.포인터의 포인터

포인터의 포인터는 다루는 대상체가 포인터인 포인터 변수를 뜻한다.

즉, 포인터들을 다루는 포인터라는 이야기다.

포인터의 포인터 변수 정의

char**imsipp;

어디에 사용 하는가
  1. 매개변수가 포인터 배열인 함수를 작성하기 위해 사용
  2. 명령행 인자에서 사용
초기화

5_1.c

#include <stdio.h>

main()
{
char *imsip[3], **imsipp;
int one, *two, **three;

imsip[0] = "imsi";
imsip[1] = "temp";
imsip[2] = "jamgan";

imsipp = imsip;

two = &one;
three = &two;
}

포인터의포인터 변수에서는 다음을 명확히 알아두어야 한다.

  1. three
    포인터의 포인터 변수이므로 주소 값을 저장할 수 있고 three에는 two의 주소값이 저장되어 있다.
  2. &three
    three 변수가 할당된 메모리 주소를 뜻한다.
  3. *three
    three가 가리키는 것을 참조하라는 말이다. three에는 two의 주소값이 저장되어 있고 two에는 one의 주소값이 저장되어 있으므로 one의 주소값이 나온다.
  4. **three
    이는 위의 *three에서와 같이 one이 저장된 곳의 위치 값이며 이를 참조하여 one에 저장된 정수 값을 얻어오게 된다.
포인터의 포인터 참조

5_2.c

#include <stdio.h>

main()
{
char *imsi[3];
char **imsipp;

imsipp = imsi; // imsipp = &imsi[0];

imsi[0] = "archie";
imsi[1] = "Park Une Ju";
imsi[2] = "Jung Sun Yune";

printf("imsi[0] : %#010x\n", imsi[0]); // (1)
printf("imsi[1] : %#010x\n", imsi[1]); // (2)
printf("imsi[2] : %#010x\n", imsi[2]); // (3)
putchar('\n');

printf("&imsi[0] : %#010x\n", &imsi[0]); // (4)
printf("&imsi[1] : %#010x\n", &imsi[1]); // (5)
printf("&imsi[2] : %#010x\n", &imsi[2]); // (6)
putchar('\n');

printf("imsipp : %#010x\n", imsipp); // (7)
printf("imsi : %#010x\n", imsi); // (8)
putchar('\n');

printf("imsi[0] : %s\n", imsi[0]);// (9)
printf("imsi[1] : %s\n", imsi[1]);// (10)
printf("imsi[2] : %s\n", imsi[2]); // (11)
putchar('\n');

printf("*imsipp : %s\n", *imsipp); // (12)
printf("*(imsipp + 1) : %s\n", *(imsipp + 1)); // (13)
printf("*(imsipp + 2) : %s\n", *(imsipp + 2)); // (14)
putchar('\n');

printf("**imsipp : %c\n", **imsipp); // (15)
}

gcc -o 5_2 5_2.c
./5_2
imsi[0] : 0x08048600
imsi[1] : 0x08048607
imsi[2] : 0x08048613

&imsi[0] : 0xbfa0fce4
&imsi[1] : 0xbfa0fce8
&imsi[2] : 0xbfa0fcec

imsipp : 0xbfa0fce4
imsi : 0xbfa0fce4

imsi[0] : archie
imsi[1] : Park Une Ju
imsi[2] : Jung Sun Yune

*imsipp : archie
*(imsipp + 1) : Park Une Ju
*(imsipp + 2) : Jung Sun Yune

**imsipp : a

(1), (2), (3)

포인터 배열 변수 안에 저장된 주소를 출력하는 문장이므로 주소 값이 출력 되었다.

imsi[0]이 현재 가리키고 있는 주소는 "archie"의 'a'가 저장된 곳의 위치이다.

(4), (5), (6)

&imsi[0]은 imsi[0]자체가 할당된 메모리의주소를 뜻한다.

포인터 배열 변수이기 때문에 메모리에 4byte가 할당된다.

imsi[0]변수가 할당된메모리의 위치를 출력하라는 의미이다.

(7), (8)

imsipp를 출력하라는 의미는 imsipp가 담고 있는 값을 출력하라는 것이다.

따라서, imsi[0]이 가리키고 있는 값, 즉 imsi[0]에 저장된 값이 아닌 imsi[0]이 할당된메모리의 위치가출력된다.

(15)

*imsipp는 imsi[0]이 저장된 곳의 주소 값이다.

따라서, **imsipp는imsi[0]이 가리키는 곳의 값을 말한다. imsi[0]이 가리키고 있는 값은 "archie"의 'a'라는 문자이므로 이 값을 취하게 된다.

주의 사항

char *imsi[3];

char **imsipp;

imsi는 포인터 배열로 선언된 배열명이다. 배열명 imsi는 배열 상수이지 절대 변수가 아니다. 따라서, imsi++와 같은 연산은 불가능하다.

하지만, imsipp++는 가능하다.바로 포인터 변수이기 때문이다. 즉, 포인터 배열을 다루기 위한 변수이기 때문에연산이 가능하다.

5_3.c

#include <stdio.h>

main()
{
char *imsi[3];
char **imsipp;

imsi[0] = "Cha Hong Suk";
imsi[1] = "Jung Kang Hun";
imsi[2] = "Lee Se Jin";

imsipp = imsi;

printf("imsipp : %#010x\n", imsipp);
printf("imsi : %#010x\n", imsi);
printf("imsi[0] : %#010x\n", imsi[0]);
printf("&imsi[0] : %#010x\n", &imsi[0]);
printf("*imsipp : %#010x\n", *imsipp);
printf("&**imsipp : %#010x\n", &**imsipp);
}

gcc -o 5_3 5_3.c
./5_3
imsipp : 0xbfb37e04
imsi : 0xbfb37e04
imsi[0] : 0x080484d0
&imsi[0] : 0xbfb37e04
*imsipp: 0x080484d0
&**imsipp : 0x080484d0

명령행 인자

int main(int argc, int **argv, **env)

argc는 명령행 인자의 개수를 뜻한다.

**argv는입력되는 인자가 무엇인지 알 수 있게 해주는 변수이며 space로 구분된다.

**env는 현재 시스템에 설정되어 있는 환경을 출력해준다.

5_4.c

#include <stdio.h>

main(int argc, char **argv, char **env)
{
for(;*env;env++)
puts(*env);
}

gcc -o 5_4 5_4.c
./5_4
HOSTNAME=monserv
SHELL=/bin/bash
TERM=linux
HISTSIZE=1000
USER=icreater
LS_COLORS=no=00: fi=00: di=01;34: ln=01;36: pi=40;33: so=01;35: bd=40;33;01: cd=40;33;01: or=01;05;37;41: mi=01;05;37;41: ex=01;32: *.cmd=01;32: *.exe=01;32:

*.com=01;32: *.btm=01;32: *.bat=01;32: *.sh=01;32: *.csh=01;32: *.tar=01;31: *.tgz=01;31: *.arj=01;31: *.taz=01;31: *.lzh=01;31: *.zip=01;31: *.z=01;31: *.Z=01;31:

*.gz=01;31: *.bz2=01;31: *.bz=01;31: *.tz=01;31: *.rpm=01;31: *.cpio=01;31: *.jpg=01;35: *.gif=01;35: *.bmp=01;35: *.xbm=01;35: *.xpm=01;35: *.png=01;35: *.tif=01;35:
MAIL=/var/spool/mail/icreater
PATH=/usr/kerberos/bin: /usr/local/bin: /bin: /usr/bin: /home/icreater/bin
INPUTRC=/etc/inputrc
PWD=/home/icreater/pointer
LANG=ko_KR.UTF-8
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
SHLVL=1
HOME=/home/icreater
LOGNAME=icreater
CVS_RSH=ssh
LESSOPEN=|/usr/bin/lesspipe.sh %s
G_BROKEN_FILENAMES=1
_=./5_4
OLDPWD=/home/icreater

'C언어' 카테고리의 다른 글

Chapter 9. 포인터의 개념을 깨는 `0`  (0) 2011.10.16
Chapter 4. 문자열과 포인터  (0) 2011.10.16
Chapter 6. scanf()와 fgets()  (0) 2011.10.16
Chapter 2. 1차원 배열과 포인터  (0) 2011.10.16
Chapter 3. 2차원 배열과 포인터  (0) 2011.10.16