• 검색 결과가 없습니다.

11강. 포인터로 이차원배열 다루기

N/A
N/A
Protected

Academic year: 2022

Share "11강. 포인터로 이차원배열 다루기"

Copied!
13
0
0

로드 중.... (전체 텍스트 보기)

전체 글

(1)

C 언어 포인터 정복하기

TAE-HYONG KIM

COMPUTER ENG, KIT

11강. 포인터로 이차원배열 다루기

(2)

학습 내용

 이차원배열(이름)을 함수에서 인자로 받으려면?

 이차원배열 이름의 정체

 배열포인터의 개념 이해하기

 이차원 배열 요소를 포인터로 접근하기

 중첩 포인터와 배열 총정리하기

2

(3)

이차원배열 다시 보기

 2차원배열은 1차원배열을 요소로 갖는 1차원배열이다

 Ex) int score[2][3];

 함수에서 2차원배열을 인자로 받을 때

 특정 배열 요소를 갖는 크기가 없는 1차원배열처럼 선언한다

3

score[0]

score[1]

int arr2dSum(int arr[][3], int arrSize)

(4)

이차원 배열 이름의 정체

 이차원 배열(이름)을 인자로 함수 호출할 때 함수에서 이를 저장 하기 위해서 정확히 어떤 자료형의 변수가 필요할까?

 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];

(5)

이차원 배열 이름의 정체 (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)

배열 포인터 변수 선언하기

 배열포인터는 포인터다

 가리키는 자료형이 배열이다

 배열은 배열명 뒤에 []가 따라온다

 이것은 포인터배열 선언 방식

 *보다 []의 연산자 우선순위가 높다

 배열포인터와 포인터배열

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]; // 포인터배열 (포인터를 요소로 갖는 배열)

(7)

배열포인터 변수의 사용

 배열포인터 상수의 저장

 배열명에 포인터연산: 배열전체(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)

배열포인터 변수의 사용 예

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”);

} }

(9)

이차원 배열 내 요소 배열의 접근

 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

(10)

이차원 배열의 각 요소 접근하기

 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)

중첩된 포인터와 배열 총정리

 각 자료형의 개념 정리

11

이차원배열

이중포인터 포인터배열

배열포인터 이름

이름

(12)

중첩된 포인터와 배열 총정리 (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]);

(13)

다음 강의 소개

 12강. 특별한 자료를 가리키는 포인터

 함수의 이름은 어떤 성질을 가질까?

 모든 포인터를 저장할 수 있는 만능 포인터

 파일을 읽고 쓰는 위한 포인터

 파일을 읽고 쓰는 방식과 용법

13

참조

관련 문서