[표 3-5]와 같이 2016~2017년 분기별 노트북 판매량에 대한 리스트를 생각해 보자.

[표 3-5]는 분기와 연도를 모두 표현해야 하므로 순서가 두 종류 필요하다. 이 때는 [ 그림 3-10 ]과 같이 행 인덱스와 열 인덱스가 있는 2차원 배열을 사용한다.

2차원 배열 구조를 논리적으로 표현할 때는 행과 열의 구조로 나타내지만, 실제로 메모리에 저장될 때는 1차원의 구조로 저장된다. 2차원인 논리적 순서가 1차원인 물리적 순서로 변환되는 방법에는 인덱스를 기준으로 하는 행 우선 순서 방법과 마지막 인덱스를 기준으로 하는 열 우선 순서 방법이 있다.

행 우선 순서 방법은 행을 기준으로 같은 행 안에 있는 열을 먼저 저장하는 방법이다. [ 그림 3-10 ]의 2차원 배열을 행 우선 순서를 방법으로 메모리에 저장하면 [ 그림 3-11 ]의 ( a )와 같이 sale[0][0]=63, sale[0][1]=84, slae[0][2]=140, sale[0][3]=130, sale[1][0]=157, sale[1][1]=209, sale[1][2]=251, sale[1][3]= 312 순서가 된다. 열 우선 순서 방법은 열을 기준으로 하여 같은 열 안에 있는 행을 먼저 저장하는 방법으로 (b)와 같이 sale[0][0]=64, sale[1][0]=157, sale[0][1]=84, sale[1][1]=209, sale[0][2]=140, sale[1][2]=251, sale[0][3]=130, sale[1][3]=312 순서가 된다.

행 우선 순서 방법이냐 열 우선 순서 방법이냐에 따라 물리적 저장 순서가 달라지므로 배열의 원소 위치를 계산하는 방법도 달라져야 한다. 행의 개수가 ni이고 열의 개수가 nj인 2차원 배열 A[ni][nj]의 시작 주소가 a고, 원소 길이가 l이라면, i행 j열 원소, 즉 A[i][j]의 위치는 행 우선 순서 방법에는 a+(i x ni + j ) x l 이 되고, 열 우선 순서 방법에서는 a+(j + ni + i) x l이 된다.

논리 순서를 물리 순서로 변환하는 방법은 프로그래밍 언어의 컴파일러에 따라 결정되는데, C 컴파일러는 행 우선 순서 방법을 사용한다.

[ 예제 3-2 ]는 2016년~2017년 분기별 판매량 선형 리스트를 2차원 배열로 구현하고, 논리적 순서와 물리적 순서가 일치하는 순차 구조인지 확인하는 프로그램이다.

#include <stdio.h>
void main() {
   int i, n = 0, *ptr;
   int sale[2][4] = { { 63, 84, 140, 130 }, { 157, 209, 251, 312 } }; // 2차원 배열의 초기화

   ptr = &sale[0][0];
   for ( i = 0; i < 8; i++) {
      printf("\\n address : %u sale %d = %d", ptr, i, *ptr);
      ptr++;
   }
   getchar();
}

08행은 배열 sale의 시작 주소인 &sale[0][0]을 포인터 ptr에 저장한다.

09~12행은 배열 sale의 첫 번째 원소부터 마지막 원소까지 메모리에 저장된 순서대로 출력한다.

10행 : 포인터 ptr에 저장된 배열 원소의 주소를 %u 형식으로 출력하고, 포인터 ptr이 가리기큰 참조값(*ptr), 즉 배열 원소의 값을 %d 형식으로 출력한다.

11행 : 현재 포인터 ptr에 저장된 주소를 다음 자리, 즉 현재 위치에서 4바이트인 int만큼 이동하여 배열의 다음 원소 주소로 변경한다.