iOS/정보처리기사

[정보처리기사] C언어 - 2차원 배열과 포인터

Chafle 2022. 6. 13. 21:01
반응형

 

지난 시간 1차원 배열 포인터를 배웠다면

 

https://accompani-i.tistory.com/206

 

[정보처리기사] C언어 - 배열과 포인터(배열에도 주소값이 있다)

포인터 변수는 주소를 가진다 배열도 주소를 가지는데 예를 들어 int a[5]로 배열을 선언하게 되면, a라는 변수가 메모리 어딘가에 만들어지고 메모리 상에 5개의 공간이 만들어지는데, 배열 a가

accompani-i.tistory.com

 

 

이번 시간에는 2차원 배열과 포인터를 학습해보자.

 

ex. int a[3][2] = {{1,2},{3,4},{5,6}};

 

a에는 배열의 첫 번째 주소값이 들어가므로, 100이 들어가고

a   배열 행을 대표하는 번지 수 배열의 값[임의의 번지수] 배열의 값[임의의 번지수]
100번지   a[0] 100번지 1[100번지] 2[101번지]
  a[1] 102번지 3[102번지] 4[103번지]
  a[2] 104번지 5[104번지] 6[105번지]

 

여기서 1차원 배열과 차이점은 각 행을 대표하는 번지 수가 있다.

각 행을 대표하는 번지수는 각 배열의 첫 번째 값의 번지수와 같다

 

 

지금까지 배운 배열과 포인터를 간략하게 표현하면, 

배열(a) 자체를 대표하는 주소가 있고(위에서 a=100)

2차원 배열에서는 행(a[0])을 대표하는 주소가이 있고(100번지, 102번지, 104번지)

배열의 각각의 에는 각각의 값마다 주소가 있다.(100번지~105번지)

 

printf("%d₩n",a); = 100 

 

주의1

printf("%d₩n", *a); = 100

1차원 배열에서 *a는 'a의 값'으로 참조하고 있는 주소의 값을 반환했는데,

여기서는 참조하고 있는 것이 값 자체 가 아니고 주소를 참조하고 있기 때문에, 1이 아니고 행의 대표주소인 100을 출력하게 된다.

 

주의2

printf("%d₩n", **a) = 1

여기에서는 쉽게 **a는 'a의 값의 값'으로 생각 하면 되는데, a가 참조하고 있는 행이 다시 참조 하고 있는 값 즉 1이 반환된다.

 

 


 

 

ex.

#include<stdio.h>

int main() {

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

int *p = data[1];

int x,y;

x = *p;

y = *(p+2);

printf("x=%d, y=%d₩n", x,y);

}

 

 

 

 

해설

 

data[][3]은 어렵게 생각하지 말고 3열로 맞추면 알아서 []가 채워진다. 고로 3행 3열짜리 배열이 완성된다.

p data배열 행 대표 번지수 배열의 값[임의의 번지수] 배열의 값[임의의 번지수] 배열의 값[임의의 번지수]
100번지 data[0] 100번지 1[100번지] 3[101번지] 4[102번지]
data[1] 103번지 5[103번지] 2[104번지] 9[105번지]
data[2] 106번지 6[106번지] 8[107번지] 7[108번지]

 

배열을 위 표처럼 세팅해놓고 시작하면 된다.

 

int *p = data[1];

int x,y;

x = *p;

y = *(p+2);

 

*p x= *p y = *(p+2)
배열의 2번째 번지수를 참조하므로 *p = p주소의 값이므로
103번지의 값인 5
p는 103이고 p+2는 105이므로
105번지의 값인 9를 출력한다.
103

 

답 5,9

 

 

 

여어어어기에서의 주의1

 

 

*p가 위에 배운 것처럼 2차원 배열일 경우 번지수를 참조하는 경우 아닌가욧???????????

그래서 번지수의 값이 아니고 103,105를 출력해야 되는 거 아닌가욧?!!!?!?!?!?

3,9를 출력하려면 **p, **(p+2)여야 하는 것이 아닌가욧?!!?!?!!?

 

 

 

헷갈릴 수 있는 부분인데, 무엇을 참조하느냐가 관건이다...

 

제일 상단에서의 참조 순서는 a->행의 대표 주소->배열의 대표 주소로 참조하기 때문에

*a가 무얼 참조하느냐 : 행의 대표주소를 참조합니다.

**a가 무얼 참조하느냐: *(행의 대표주소를 참조합니다.) -> 행의 대표주소의 값은 무엇이냐 -> (*a)의 값을 참조합니다.

이런 연산 결과가 펼쳐지는 것이고

 

 

위 예제에서는

이미 행의 대표 주소 중 하나를 참조하고 있으므로, *p는 그 주소의 값을 출력하라는 의미이다 

 

 

 

여어어어기에서의 주의2

선언하는 것과 주소의 값을 출력하는 것의 차이

포인터 변수의 '선언'

int *p -> p는 포인터 변수야.

x=*p -> p가 참조하고 있는 값을 x에 할당해라.

 

 

주의 1과 2를 주의깊게 잘 읽어보도록 하자.

 

 

 


 

 

ex.

 

#include<stdio.h>

int main() {

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

int sum1, sum2;

sum1 = *(*darr+1) + *(*darr+2);

sum2 = *darr[1] + *darr[2];

printf("%d, %d", sum1, sum2);

}

 

 

 

 

반응형

 

 

해설

 

위 2차원 배열을 표로 표현하면

darr   darr배열 행 대표 번지수 배열의 값[임의의 번지수] 배열의 값[임의의 번지수] 배열의 값[임의의 번지수]
100번지   darr[0] 100번지 1[100번지] 2[101번지] 3[102번지]
  darr[1] 103번지 4[103번지] 5[104번지] 6[105번지]
  darr[2] 106번지 7[106번지] 8[107번지] 9[108번지]

 

먼저 sum1,sum2가 무엇을 의미하는지 파악해보면

 

sum1 = *(*darr+1) + *(*darr+2)   -> darr이 참조하는 값+ 1 값이 참조하는 값  + darr이 참조하는 값 +2가 참조하는 값

sum2 = *darr[1] + *darr[2]  -> darr[1] 행 대표 번지가 참조하는 값 + darr[2] 행 대표 번지가 참조하는 값

 

 

sum1 = *(*darr+1) + *(*darr+2) sum2 = *darr[1] + *darr[2]
*(*darr+1) ->  *(*100+1 번지) ->*(101) -> 101번지의 값 -> 2 *darr[1] ->103번지의 값 ->4
*(*darr+2) -> *(*100+2번지) -> *(103) -> 103번지의 값-> 3 *darr[2] ->106번지의 값->7
2+3 = 5 4+7 = 11

 

*(*darr+1)은 정확히 darr의 값이므로 행 대표 번지수의 첫 번째 주소인 100번지를 참조한다.(darr의 주소인 100이 아니다)

 

반응형