C 언어 포인터 정복하기
TAE-HYONG KIM
COMPUTER ENG, KIT
10강. 포인터로 포인터 가리키기
학습 내용
포인터가 가리킬 수 있는 것 확장하기
두 포인터 변수의 값을 서로 바꿔보자
이중 포인터 자료형
이중 포인터는 언제 사용할까?
포인터를 원소로 갖는 배열
2
포인터가 가리킬 수 있는 것들
기본 자료형
int *, char *, double *
배열이름(1차원), 문자열은 역시 기본 자료형임
확장 자료형
배열 형: 배열 전체를 가리키는 포인터?
포인터 형: 포인터 변수를 가리키는 포인터?
3
int arr[5] = {1, 2, 3, 4, 5};
? = &arr;
int a = 10;
int *p = &a;
? = &p;
두 포인터변수의 값을 바꿔보자
포인터 p, q가 가리키는 문자열을 서로 바꾸어 보자
만약 이 작업을 수행하는 함수
(swap_ptr())를 설계한다면 함수의 인자로 무엇을 사용해야 할까?
4
char *p = “win”;
char *q = “lose”;
100 101 102 103
200 201 202 203 204 205
‘w’
‘i’
‘n’
‘\0’
. . .
‘l’
‘o’
‘s’
‘e’
‘\0’
p
q
11 12 13 14 15 16 17 18 19 20 21 22
10 char
100
200
char
char *temp = p;
p = q;
q = temp;
temp
100
char 200
100 char char char
swap_ptr(p, q); // correct?
두 포인터변수의 값을 바꿔보자 (2)
문제점
pa, pb만 바뀔 뿐 p와 q는 변하지 않는다
Call by value과 동일한 문제점
해결책
Call by reference로 호출해야 함
함수의 인자는 어떤 자료형으로 선언해 야 하는가?
문자 포인터 변수의 포인터?
5
swap_ptr(p, q);
...
void swap_ptr(char *pa, char *pb) {
100 101 102 103
200 201 202 203 204 205
‘w’
‘i’
‘n’
‘\0’
. . .
‘l’
‘o’
‘s’
‘e’
‘\0’
p
q
11 12 13 14 15 16 17 50 51 52 53
10 char
100
200
char 100
200
54 55 56 57
pa
char
100
pb
char
200
swap_ptr(&p, &q);
이중 포인터 자료형
포인터 자료형
자료형 * (int *, char *, double *, …)
자료형포인터 형: int **, char **, double **, … 이중 포인터 자료형
이중 포인터의 생성
이중 포인터 변수의 선언
6
char c = ‘a’; char *cp = &c;
? = &cp;
100 101 102 103 104 105 106 107 108 109 110 111 112 char c = ‘a’; char *cp = &c;
char **cpp = &cp;
포인터변수라는 의미 포인터변수의 이름 가리키는 자료형이
char * 형
포인터변수 cp의 포인터 저장
c ‘a’
char
cp
100
cpp
104
char *
이중 포인터가 가리키는 값 얻기
이중포인터에 참조연산자 적용
이중 포인터로 문자열을 가리킬 때
7
int a = 10;
int *ap = &a;
int **app = ≈
printf(“%u”, app);
printf(“%u”, *app);
printf(“%d”, **app);
char str1[] = "win";
char *str2 = str1;
char **cpp = &str2;
printf("str2=%s\n", *cpp);
printf("str1[0]=%c\n", **cpp);
이중 포인터의 사용 예
8
패턴 15 포인터변수가 가리키는 문자열 서로 바꾸기
#include <stdio.h>
void swap_ptr(char **, char **);
int main(void) {
char *p=“win";
char *q=“lose";
printf("p: %s, q: %s\n", p, q);
swap_ptr(&p, &q);
printf("p: %s, q: %s\n", p, q);
return 0;
}
void swap_ptr(char **app, char **bpp) {
char *tp; // 문자 포인터(char *) 임시저장 포인터 변수 tp=*app;
*app=*bpp;
*bpp=tp;
}
이중포인터를 사용하는 경우
배열의 이름은 값의 의미(R-value)로 쓰일 경우, 배열의 첫 요소를 가리키는 포인터이다
&arr[0]의 자료형: int *, char *, double *, …
arr[0](배열요소)가 포인터 자료형이라면?
배열요소를 포인터 형으로 확장해 보자
배열 요소가 char *라면?
9
100 104 108
112
char
arr[0]
arr[1]
arr[2]
arr[3]
char char char
포인터 배열
포인터 배열: 포인터를 요소로 갖는 배열
포인터 배열의 선언
배열의 선언: 배열요소자료형 배열이름[배열요소의수];
포인터배열의 선언: 포인터자료형 배열이름[배열요소의수];
Ex) int *parr[5]; char *qarr[5]; double *rarr[5];
10
char *pstr1[2] = {“win”, “lose”};
배열의 이름 배열 요소의 수 배열 요소의 자료형
100 104 pstr1[0]
pstr1[1]
200
‘w’ ‘i’ ‘n’ ‘\0’
300
‘l’ ‘o’ ‘s’ ‘e’ ‘\0’
char 200
300 char
포인터배열의 이름이 이중포인터이다!
pstr1 char*
포인터 배열의 이름 저장하기
11
포인터배열의 이름을 이중포인터 변수에 저장하자
포인터배열을 인자로 함수 호출하기
char *pstr1[2] = {“win”, “lose”};
char **cpp = pstr1;
printf(“%s”, *cpp);
printf(“%s”, cpp[1]);
printf(“%c”, **cpp);
printf(“%c”, cpp[1][1]);
char *pstr1[2] = {“win”, “lose”};
...
prnstr(pstr1);
...
void prnstr(char **pstr) // or *pstr[]
포인터 배열의 활용
1차원배열의 배열명(R-value)은 포인터이므로 포인터배열에 저 장할 수 있다
포인터배열을 2차원배열처럼 쓸 수 있다
12
char str1[5] = “win”;
char str2[5] = “lose”;
char *pstr2[2] = { str1, str2 };
205
printf(“%c”, pstr2[1][1]);
200
‘w’ ‘i’ ‘n’ ‘\0’
205
‘l’ ‘o’ ‘s’ ‘e’ ‘\0’
str1 str2
100 104 pstr2[0]
pstr2[1]
char 200
char
pstr2 char*
포인터 배열의 활용 (2)
main() 함수의 인자?
main() 함수는 운영체제에서 프로그램을 실행할 때 호출된다
main() 함수의 인자는 프로그램을 실행할 때 줄 수 있다
운영체제는 명령행의 문자열을 포인터배열(argv)의 형태로 인 자의 개수(argc)와 함께 main() 함수에게 인자로 전달한다
포인터 배열을 인자로 받을 때 포인터배열의 이름은 이중 포인터이므로 이중포인터변수로 받아야 한다
배열의 이름을 인자로 받을 때 포인터변수 대신 빈크기의 배열로 받을 수 있는 것처럼 포인터배열의 이름도 빈크기의 포인터배열로 받을수있다
13
C:\>copy file1 file2
프로그램이름: 인자0 인자1 인자2
int main(int argc, char **argv);
int main(int argc, char *argv[]);
포인터 배열의 활용 예
14
패턴 16 main()함수의 인자 출력하기
#include <stdio.h>
int main(int argc, char **argv)
// int main(int argc, char *argv[]) {
int i;
for(i=0; i<argc; i++){
printf("%s\n", argv[i]);
}
return 0;
}
C:\>prog arg1 arg2
100 104 argv[0]
argv[1]
200
300 400
char 200
300 char
argv
400 108 char
‘p’ ‘r’ ‘o’ ‘g’
argv[2]
‘\0’
‘a’ ‘r’ ‘g’ ‘1’ ‘\0’
‘a’ ‘r’ ‘g’ ‘2’ ‘\0’
100 char*