본문 바로가기

C&C++_Basic/C_Pointer

#C언어 배열 : 이차원 " 배열 포인터 "

#include<stdio.h>

int main()

{

int ary[][4] = { 5,7,6,2,7,8,1,3};

/* 5 7 6 2

7 8 1 3 */

int (*ptr)[4] = ary; 
printf("%2d, %2d\n", **ary, **ptr++);// 1행 1열 value 출력
printf("%2d, %2d\n", **(ary+1), **(ptr++)); // 1행 2열 value 출력
ptr = ary; // 다시 초기화 해주는 것. 이후 ary와 ptr 값이 달라지므로 ( 위에서 ptr 후위 증감)


printf("%2d, %2d\n", *(ary[1]+1),*(ptr[1]+1)); // 2행 2열을 출력
printf("%2d, %2d\n", *(*(ary + 1) +1),*(*(ptr + 1) +1)); //
printf("%2d, %2d\n", *(*(ary+1)),*(*(ptr+1))) ; //
printf("%2d, %2d\n", sizeof(ary), sizeof(ptr)); 
// ary의 크기는 4byte * 2 * 4 = 32 , ptr은 포인터만을 의미하므로, int 형 선언이니까 4byte 인것이다.

/*  출력결과
 5,  5
 7,  7

 8,  8
 8,  8
 7,  7
32,  8 */


return 0;
}
더보기

* " 배열 포인터와 포인터 배열 "


ary[][4]에 대한 포인터를 설정하는 방법 ?

int (*ptr)[4] = ary ;

뒤의 괄호에 있는 [4] 는 , 열의 크기를 나타내며,

(*ptr) 과 같이, 괄호를 붙여주는 것이 매우 중요하다.

한편,

괄호가 없는 int *ptr[4]는, 포인터 변수 4개를 선언하는 포인터 배열 선언 문장

ex.int ary[][4] = { 5,7,6,2,7,8,1,3}이면

int (*ptr)[4] = ary : 열이 4인 배열을 가리키는 포인터, 즉, " 배열 포인터 "

int *ptr[4] = ary : " 포인터 배열 "을 의미한다.

그렇다면, 배열 포인터와 , 포인터 배열 사이의 차이점은 무엇일까 ?

1) " 포인터 배열" 이란?

= 주소값을 저장하는 포인터를 배열 원소로 하는 배열.

= 즉, 포인터 여러개가 모여서, 배열로 있는 것.

ex.

int a =5, b = 6, c = 7;

int *pa[3] : 배열크기가 3인 포인터 배열

>> pa[0] = &a , pa[1] = &b, pa[2] = &c 를 의미한다.

2) " 배열 포인터 "

= 배열을 가리키는 "하나의 포인터"

= 특정 사이즈의 배열'만' 가리키는 " 하나의 포인터 " 이다.

"포인터 배열"은, "여러개"의 포인터이고, " 배열 포인터"는, 오로지 하나의 포인터.

- 특정 사이즈의 배열을 표현하는 새로운 표현 형태.라고 생각하면 된다

ex. int (*ptr)[4]

- " 열이 4인 배열 " 을 가리키는 포인터

즉, 변수 ptr은 열의 수가 4인 이차원 " 배열의 주소값 "을 저장할 수 있는 배열 포인터

그에 비해,

int *ptr[4] = ary

- 포인터 배열을 의미. 즉, 총 4개의 포인터 배열이 할당

변수 ptr = &ary[0][0] : 즉, 변수 ptr은 배열 ary 첫 원소의 주소값이다.

즉, *ptr[ i ] 는, '하나의 상수'를 가리키고,

(* ptr )[4] 는, 주소값 4개를 지닌 '하나의 배열'을 가리키는 포인터이다.

* 이차원 배열 포인터 참조하기*


- 만일 배열 첫 원소 ( ary[0][0] )를 참조하려면 **ptr을 이용한다.

쉽게 비유하면, 이차원 배열 포인터는, 이차원 포인터로, * 를 2개 쓴다고 생각하면 된다.

- 연산식 **ptr++ = **(ptr++)와 같다.

ptr++ 과정에서, 주소값의 이동이 발생한다.

이후에 나오는 **(ptr)들은 그 다음 원소의 "값"을 참조할 것이다.

즉, ptr = &&ary[0][0] >> **ptr++ (후위 증감) >> **(ptr++)

2행 1열 에 해당하는 원소를 가리킨다.

*(ary[i] + j) 와 *(ptr[i] + j)

*(* (ary + i ) + j) , * ( *( ptr + i) + j) 은

각각, (i +1)행, (j +1)열의 원소를 참조

>>

ary[i] = 값을 참조 / ary + i = 주소를 참조

그러므로, ary[i] = *(ary + i)

*/