본문으로 이동
메뉴 여닫기
환경 설정 메뉴 여닫기
개인 메뉴 여닫기
로그인하지 않음
지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.

C 언어 배열은 같은 자료형의 값 여러 개를 메모리의 연속된 공간에 차례로 저장하고, 하나의 이름과 첨자(인덱스)로 각 값에 접근하게 하는 자료 구조다.

  • 첨자는 0부터 시작한다. 크기가 n 인 배열의 마지막 원소는 [n−1] 이다.
  • 배열 이름은 첫 원소의 주소처럼 쓰인다. 그래서 배열과 포인터는 거의 같은 방식으로 다룰 수 있다.
  • C 언어는 첨자가 범위를 벗어났는지 검사하지 않는다. 범위 밖에 쓰면 다른 변수를 덮어쓴다 → 버퍼 오버플로우
int a[5] = {10, 20, 30};   /* 나머지 a[3], a[4] 는 0 으로 채워진다 */
int b[] = {1, 2, 3};        /* 크기를 생략하면 초깃값 개수(3)로 정해진다 */
  • 초깃값을 일부만 주면 나머지는 0 이 된다. 초깃값을 하나도 주지 않은 지역 배열은 쓰레기값을 갖는다.
  • sizeof(a) / sizeof(a[0]) 로 원소 개수를 구한다.
  • a[i] 와 *(a + i) 는 같다. 포인터 p = a 이면 p[i], *(p + i) 도 같은 원소다.
int a[2][3] = {{1, 2, 3}, {4, 5, 6}};

2차원 배열도 메모리에는 1차원으로 이어져 저장된다. C 언어는 행 우선(row-major) 순서를 쓰므로 첫 행을 다 놓은 뒤 다음 행을 놓는다.

메모리 순서 0 1 2 3 4 5
원소 a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2]
값 1 2 3 4 5 6
  • a[i] 는 i 번째 행이며, 그 행의 첫 원소 주소처럼 쓰인다. 그래서 int *p = a[0]; 은 a[0][0] 을 가리킨다.
  • a[i][j] 는 첫 원소에서 i × 열의 수 + j 칸 떨어진 원소다.
  • 2차원 배열을 함수에 넘길 때는 열의 크기를 반드시 적는다: void f(int a[][3])

포인터로 2차원 배열 훑기

편집 원본 편집
#include <stdio.h>

int main(void) {
    int a[2][2] = {{11, 22}, {44, 55}};
    int i, sum = 0;
    int *p;

    p = a[0];                    /* a[0][0] 의 주소 */
    for (i = 1; i < 4; i++)
        sum += *(p + i);         /* 메모리 순서 1·2·3 번 칸 */
    printf("%d", sum);           /* 22 + 44 + 55 = 121 */
    return 0;
}
  • 메모리에는 11, 22, 44, 55 가 이 순서로 붙어 있다. p 가 11 을 가리키므로 *(p+1)=22, *(p+2)=44, *(p+3)=55 다.
  • 반복이 i = 1 부터 시작하므로 11 은 더하지 않는다. 결과는 121 이다. i = 0 부터였다면 132 다.
  • p 는 int * 이므로 p + 1 은 int 하나 크기만큼 이동한다. 행 단위로 이동하려면 int (*q)[2] = a; 처럼 행 포인터를 쓴다.

문자열은 널 문자('\0')로 끝나는 char 배열이다. char s[] = "KOREA"; 의 크기는 널 문자를 포함해 6 이다. 문자열을 다루는 함수는 C 언어 string.h 를 본다.