C(8): 2-dim Array

이규현·2024년 12월 5일

2차원 배열 == 배열의 배열

시각적으로 행렬을 연상

int arr[2][3] = {
   {1, 2, 3}, // 0행
   {4, 5, 6}  // 1행
};
int arr[2][3] = {1,2,3,4,5,6};

실행 예제

#define ROW 2
#define COL 3

int main() {
  int i, j;
  int first[ROW][COL], second[ROW][COL], add[ROW][COL];

  for(i = 0; i < ROW; i++){
    for(j = 0; j<COL; j++){
      printf("Enter first matrix[%d][%d]: ", i, j);
      scanf("%d", &first[i][j]);
    }
  }

  for(i = 0; i < ROW; i++){
    for(j = 0; j<COL; j++){
      printf("Enter second matrix[%d][%d]: ", i, j);
      scanf("%d", &second[i][j]);
    }
  }

  for(i = 0; i < ROW; i++){
    for(j = 0; j<COL; j++){
      add[i][j] = first[i][j] + second[i][j];
    }
  }

  printf("Sum of two matrices: \n");
  for(i = 0; i < ROW; i++){
    for(j = 0; j<COL; j++){
      printf("%d ", add[i][j]);
    }
    printf("\n");
  }

  return 1;
}

arr, &arr, arr[0], arr[0][0], p, q, p+1, q+1... 차이 이해하기

int main() {
  int *p, *q, arr[2][3] = {1, 2, 3, 4, 5, 6 };

  printf("arr: %p\n", arr);
  printf("arr+1: %p\n", arr+1);
  printf("&arr: %p\n", &arr);
  printf("&arr+1: %p\n\n", &arr+1);

  printf("arr[0]: %p\n", arr[0]);
  printf("arr[0]+1: %p\n", arr[0]+1);
  printf("&arr[0]: %p\n", &arr[0]);
  printf("&arr[0]+1: %p\n\n", &arr[0]+1);

  p = arr;
  printf("p: %p, p+1: %p \n", p, p+1);

  q = arr[0];
  printf("q: %p, q+1: %p \n", q, q+1);

  printf("(q+1)[2]: %d \n\n", (q+1)[2]);

  return 0;
}
  • &arr: 배열 전체를 가리키는 포인터(2차원 배열 전체) -> &arr+1은 배열 전체의 크기 4byte * 6, 즉 arr에 24를 더한 값이 된다.
  • arr: 하나의 행을 가리키는 포인터 -> arr + 1은 arr에 4byte * 3, 즉 arr에 12를 더한 값이 된다.
  • arr[0]: arr[0][0], arr[0][1], arr[0][2]의 세 요소로 이루어진 배열.
    즉 arr[0] 그 자체도 배열명과 동시에 배열의 시작주소.
    arr[0] + 1은 arr[0]에 4를 더한 값이 된다.
  • &arr[0]: 행 전체를 가리킨다. &arr[0] +1은 &arr[0]에 행 전체 크기인 12를 더한 값.

&arr, arr, arr[0]이 다 같이 배열 시작주소를 가리키지만 포인터 산술 연산시 이동 단위가 다르다!

  • p, q는 4byte단위로 움직인다.
  • q가 배열의 시작 주소인 arr[0][0]을 가리키는 상황에서 (q+1)은 arr[0][1]을 가리킨다. 4byte 단위로 이동하기 때문. q+1자체를 arr[0][1]에서 시작하는 배열명으로 생각하면 (q+1)[2]는 arr[1][0]인 4가 찍힌다.

int* p[]: 배열 p의 요소가 정수 포인터
int (*p)[]: 포인터 p가 가리키는 것이 정수 배열

malloc으로 배열 만들기

void print_it(int p[2][3]){
  int i, j;
  for(i = 0; i < 2; i++){
    for(j = 0; j < 3; j++){
      p[i][j] = i*i+j*j;
      printf("%d ", p[i][j]);
    }
    printf("\n");
  }
}

int main() {
  int *arr = (int*)malloc(2*3*sizeof(int));
  if(arr != NULL)
    print_it(arr);
  free(arr);
  arr = NULL;

  return 0;
}

프로그램 실행 도중 행과 열의 크기를 받아 동적 배열을 만들기

#include <stdlib.h>

int ** create_matrix(int, int);
void destroy_matrix(int**, int);

int main() {
  int row, column, i, j, **matrix;

  printf("Enter row and column.\n");
  scanf("%d%d", &row, &column);

  matrix = create_matrix(row, column);
  for (i = 0; i < row; i++) {
    for (j = 0; j < column; j++) {
      matrix[i][j] = i * i + j * j;
      printf("%d\t", matrix[i][j]);
    }
    printf("\n");
  }
  destroy_matrix(matrix, row);

  return 0;
}

int ** create_matrix(int row, int col) {
  int i, **p;
  p = (int**)malloc(row * sizeof(int*));
  if (p == NULL)
    exit(1);
  for (i = 0; i < row; i++) {
    p[i] = (int*)malloc(col * sizeof(int));
    if (p[i] == NULL)
      exit(1);
  }
  return p;
}

void destroy_matrix(int** p, int row) {
  int i;
  for (i = 0; i < row; i++)
    free(p[i]);
  free(p);
  p = NULL;
}
  • 정적 포인터 배열은 int *p[100]; 으로 선언
  • 동적 포인터 배열은 int **p; 으로 선언

0개의 댓글