다차원 배열과 포인터 배열
2차원 배열의 필요성
- 2차원 배열은 굉장히 많은 목적으로 사용됨
- 행렬 데이터를 표현할 때, 그래프 알고리즘을 처리할 때, 다수의 실생활 데이터를 처리할 때 등
- 흔히 우리가 보는 표 구조가 2차원 배열과 흡사함
이름 영어 성정 수학 성적 국어 성적
가나다 85 97 79
라마바 100 89 98
사아자 99 77 99
차카타 89 70 78
파하 95 98 98
2차원 배열의 초기화
- 2차원 배열은 1차원 배열이 중첩되었다는 의미로 [](대괄호)를 두 번 연속하여 사용
- 초기화하고 싶은 값이 있다면 괄호를 두 번씩 중첩해서 사용하는 방식으로 초기화가 가능
자료형 배열 이름 [행] [열] = {{값, 값, 값, ...}, {값, 값, 값, ...}, ...}
int a[10][10];
- 2차원 배열 또한 기본적으로 0 인덱스부터 시작
A[0(행)][0(열)] A[0][1] A[0][2]
A[1][0] A[1][1] A[1][2]
A[2][0] A[2][1] A[2][2]
A[3][0] A[3][1] A[3][2]
A[4][0] A[4][1] A[4][2]
* 2차원 배열은 2중 for문과 함께 많이 사용됨
#include <stdio.h>
#include <stdlib.h>
int a[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int main(void){
int i, j;
for (i = 0; i < 3; i++){
for (j = 0; j < 3; j++) {
printf("%d", a[i][j]);
}
printf("\n");
}
system("pause");
return 0;
}
다차원 배열
- 2차원 배열 이상의 다차원 배열 또한 사용할 수 있음
- 컴퓨터는 기본적으로 화면에 2차원 형태만 출력할 수 있음
* 3차원 배열 다루기
#include <stdio.h>
#include <stdlib.h>
int a[2][3][3] = { { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } },
{ { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } } };
int main(void){
int i, j, k;
for (i = 0; i < 2; i++){
for (j = 0; j < 3; j++) {
for (k = 0; k < 3; k++) {
printf("%d ", a[i][j][k]);
}
printf("\n");
}
printf("\n");
}
system("pause");
return 0;
}
포인터 배열의 구조 분석
- 배열은 포인터와 동일한 방식으로 동작함
- 배열의 이름은 배열의 원소의 첫 번째 주소가 됨
- 유일한 차이점이라고 하면 포인터는 변수이며 배열의 이름은 상수
* 배열의 이름이 변수인지 상수인지 확인해보기
#include <stdio.h>
#include <stdlib.h>
int main(void){
int a = 10;
int b[10];
b = &a; // 배열 이름 자체는 상수이기 때문에 다른 주소 값으로 넣어줄 수 없음
system("pause");
return 0;
}
* 포인터를 배열처럼 사용하기
#include <stdio.h>
#include <stdlib.h>
int main(void){
int a[5] = { 1, 2, 3, 4, 5 };
int *b = &a;
printf("%d\n", b[2]);
system("pause");
return 0;
}
* 배열의 이름은 배열의 첫 번째 원소의 주소라는 것을 기억하는 게 중요
#include <stdio.h>
#include <stdlib.h>
int main(void){
int a[5] = { 1, 2, 3, 4, 5 };
int *b = &a[0];
printf("%d\n", b[2]);
system("pause");
return 0;
}
포인터 배열의 구조 분석
1.
- 포인터는 연산을 통해 자료형의 크기만큼 이동함
- 따라서 정수(int) 형 포인터는 4바이트(Bytes)씩 이동함
#include <stdio.h>
#include <stdlib.h>
int main(void){
int a[5] = { 1, 2, 3, 4, 5 };
int i;
for (i = 0; i < 5; i++) {
printf("%d", a[i]);
}
system("pause");
return 0;
}
* 크기가 10인 double형(각각의 원소는 8바이트) 배열을 선언했을 때 배열의 시작 주소가 X(마지막 원소까지 9칸을 뛰어야 함)라고 한다
이때 배열의 마지막 원소의 주소는 몇인가 (8 x 9를 해서 72만큼 시작 주소에서 떨어져 있는 거니까 정답은 x + 72라고 할 수 있음)
#include <stdio.h>
#include <stdlib.h>
int main(void){
double b[10];
printf("%d %d\n", b, b + 9);
return 0;
}
* 배열을 포인터처럼 사용해 각 원소에 접근할 수도 있음
#include <stdio.h>
#include <stdlib.h>
int main(void){
int a[5] = { 1, 2, 3, 4, 5 };
int i;
for (i = 0; i < 5; i++) {
printf("%d", *(a + i));
}
system("pause");
return 0;
}
* 다음 프로그램의 결과는? 1, 3, 5
#include <stdio.h>
#include <stdlib.h>
int main(void){
int a[5] = { 1, 2, 3, 4, 5 };
int *p = a;
printf("%d\n", *(p++));
printf("%d\n", *(++p));
printf("%d\n", *(p + 2));
system("pause");
return 0;
}
* 2차원 배열 또한 포인터로 처리할 수 있음
#include <stdio.h>
#include <stdlib.h>
int main(void){
int a[2][5] = { { 1, 2, 3, 4, 5 },
{ 6, 7, 8, 9, 10 } };
int (*p)[5] = a[1];
int i;
for (i = 0; i < 5; i++) {
printf("%d ", p[0][i]);
}
system("pause");
return 0;
}
- 2차원 배열 이상을 표현할 수 있음
- C언어의 배열은 내부적으로 포인터와 동일하므로 포인터 연산으로 배열을 대체할 수 있음