다차원 배열은 행 우선으로 이어진 하나의 메모리 블록으로 읽는 편이 맞습니다.
int a[3][4]가 메모리에 어떻게 놓이는지 다시 보고 싶다- 함수 매개변수에서 왜 두 번째 차원을 알아야 하는지 헷갈린다
- 동적 2차원 배열을
int **로 잡아도 되는지 판단하고 싶다
숏컷 코드
c
int m[2][3] = {
{1, 2, 3},
{4, 5, 6}
};문법
C의 2차원 배열은 "배열의 배열"이고 메모리는 행 우선으로 이어집니다. 그래서 메모리 관점에서는 1 2 3 4 5 6이 한 줄로 붙어 있는 것과 가깝습니다.
m[r][c]를 주소로 계산하려면 한 행의 길이를 알아야 하므로, 두 번째 차원 크기가 중요해집니다.
순회와 전달
함수 인자에서는 보통 이렇게 갑니다.
c
void print_matrix(int rows, int cols, int m[rows][cols]);열이 고정이면 아래처럼 둘 수도 있습니다.
c
void print_4col(int rows, int m[][4]);순회는 행을 바깥, 열을 안쪽에 두는 편이 메모리 배치와 잘 맞습니다.
c
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
printf("%d ", m[r][c]);
}
}체크포인트
int a[R][C]는 행 우선으로 이어진 배열 블록입니다.- 함수 인자에서 다음 차원 크기는 주소 계산에 필요합니다.
- 행을 바깥, 열을 안쪽에 두는 순회가 메모리 배치와 잘 맞습니다.
- 동적 2D는
int **와 flat buffer가 모양은 비슷해도 메모리 구조가 다릅니다. - 정적 2D 배열과
int **를 같은 타입처럼 섞으면 안 됩니다.
주의할 점
int **와 int [R][C]는 같은 것이 아닙니다. 둘 다 "2차원처럼" 보여도 메모리 구조와 인덱싱 전제가 다르므로, 정적 2D 배열을 받는 함수에 int **를 넘길 수 있다고 생각하면 타입/메모리 해석 문제가 바로 생깁니다.
참고 링크
1 sources