C 언어 포인터 정복하기
TAE-HYONG KIM
COMPUTER ENG, KIT
11강. 포인터로 이차원배열 다루기
학습 내용
이차원배열(이름)을 함수에서 인자로 받으려면?
이차원배열 이름의 정체
배열포인터의 개념 이해하기
이차원 배열 요소를 포인터로 접근하기
중첩 포인터와 배열 총정리하기
2
이차원배열 다시 보기
2차원배열은 1차원배열을 요소로 갖는 1차원배열이다
Ex) int score[2][3];
함수에서 2차원배열을 인자로 받을 때
특정 배열 요소를 갖는 크기가 없는 1차원배열처럼 선언한다
3
score[0]
score[1]
int arr2dSum(int arr[][3], int arrSize)
이차원 배열 이름의 정체
이차원 배열(이름)을 인자로 함수 호출할 때 함수에서 이를 저장 하기 위해서 정확히 어떤 자료형의 변수가 필요할까?
1차원 배열의 확장으로 접근하기
int [3] 배열을 요소로 하는 두 요소를 갖는 배열
int [3] 자료형을 INT3이라는 자료형으로 생각하면
배열이름 score는 &score[0] (R-value) 또는 전체공간 으로서의 변수 (L-value)가 된다.
여기서 score[0]는 INT3 형, 즉 세 요소를 갖는 정수 배열(int [3])이므로
&score[0]는 세 요소를 갖는 정수 배열(int [3])을 가리키는 포인터가 된다
배열을 가리키는 포인터: 배열포인터
4
int score[2][3]; score[0]
score[1]
INT3 score[2];
이차원 배열 이름의 정체 (2)
이차원 배열 이름의 정체 확인
이차원 배열의 이름은 첫 번째 묶음배열 요소을 가리 키는 포인터(R-value) 또는 이차원 배열 전체공간을 의미하는 변수(L-value)를 의미한다
이차원 배열 이름을 저장하기 위해서 어떤 자료 형의 변수가 필요할까?
5
int score[2][3];
printf(“%u”, score);
printf(“%u”, &score[0]);
printf(“%u”, score+1);
printf(“%u”, &score+1);
printf(“%u”, sizeof(score));
printf(“%u”, sizeof(*score));
score[0]
score[1]
100 104 108 112 116 120
배열 포인터 변수 선언하기
배열포인터는 포인터다
가리키는 자료형이 배열이다
배열은 배열명 뒤에 []가 따라온다
이것은 포인터배열 선언 방식
*보다 []의 연산자 우선순위가 높다
배열포인터와 포인터배열
6
score[0]
score[1]
100 104 108 112 116 120 자료형 *arrptr;
int[3] *arrptr; // correct?
int *arrptr[3]; // correct?
int (*arrptr)[3]; // OK!
int (*arrptr)[3]; // 배열포인터 (배열을 가리키는 포인터) int *ptrarr[3]; // 포인터배열 (포인터를 요소로 갖는 배열)
배열포인터 변수의 사용
배열포인터 상수의 저장
배열명에 포인터연산: 배열전체(l-value)를 가리키는 포인터
배열의 자료형(요소의 개수, 요소의 자료형)이 동일해야 함
함수에서 2차원배열 이름을 인자로 받아 저장할 때
1차원배열 인자의 경우 int *ptr을 int ptr[]로 쓰는 것과 동일
함수 내부에서는 2차원배열처럼 쓸 수 있음
7
int arr[3];
int (*arrptr)[3] = &arr;
int arr2[2][3] = {1,2,3,4,5,6};
func(arr2);
void func(int (*arrptr)[3]) { ...
// void func(int arrptr[][3]) { ...
배열포인터 변수의 사용 예
8
패턴 17 2차원배열의 각 요소를 출력하는 함수
#include <stdio.h>
#define N 4
void ary_prn(int (*)[4], int);
int main(void) {
int ary[][N]={{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
ary_prn(ary, sizeof(ary)/sizeof(ary[0]));
return 0;
}
void ary_prn(int (*ap)[N], int size) // ary_prn(int ap[][4], ...
{
int i, j;
for(i=0; i<size; i++){
for(j=0; j<N; j++){
printf(“%5d”, ap[i][j]);
}
printf(“\n”);
} }
이차원 배열 내 요소 배열의 접근
score[0]의 값?
배열 score의 첫 요소: 배열형
첫 부분배열(int [3]형)의 이름
• R-value: &score[0][0]
• L-value: 부분배열 전체공간
9
score[0]
score[1]
100 104 108 112 116 120 int score[2][3];
printf(“%u”, score[0]);
printf(“%u”, &score[0][0]);
printf(“%u”, score[0]+1);
printf(“%u”, &score[0]+1);
printf(“%u”, sizeof(score[0]));
printf(“%u”, sizeof(*score[0]));
score[0]
100 int
이차원 배열의 각 요소 접근하기
score[1][1]을 접근하는 방법들
*(score[1]+1)
*(score+1)은 score[1]과 같다
*(*(score+1)+1)
(*(score+1))[1]
정리
10
int score[2][3]; score[1]
112 112
116 120 score[1]+1
116
100 104 108 112 116 120 score
100
score+1 112
*(score+1) score[i][j]
*(score[i]+j)
*(*(score+i)+j)
(*(score+i))[j]
score[i] *(score+i)
중첩된 포인터와 배열 총정리
각 자료형의 개념 정리
11
이차원배열
이중포인터 포인터배열
배열포인터 이름
이름
중첩된 포인터와 배열 총정리 (2)
함수 매개변수에 따른 함수원형 정리
인자: 포인터변수의 포인터 이중포인터
인자: 포인터배열 이중포인터
인자: 이차원 배열 배열포인터
12
int a=1, *ap=&a;
a = ft1(&ap); int ft1(int **bp);
int a=1;
char *arp[]={“abc”, “def”};
a = ft2(arp); int ft2(char **brp);
int ft2(char *brp[]);
int a=1;
char ar[][5]={“abc”, “def”};
a = ft3(ar); int ft3(char (*br)[5]);
int ft3(char br[][5]);