본문 바로가기
Computer Science/C 언어

[C #13] 포인터와 배열 (Pointers and Arrays)

by rnasterofmysea 2024. 12. 11.
반응형

12장: 포인터와 배열 (Pointers and Arrays)

  • 포인터와 배열:
    • 배열 이름은 첫 번째 요소의 주소를 가리키는 포인터.
    • arr[i]는 *(arr + i)와 동일.
  • 다차원 배열과 포인터:
    • arr[i][j]는 *(*(arr + i) + j)와 동일.
    • 동적 2차원 배열은 이중 포인터로 처리.
  • 포인터 배열과 배열 포인터:
    • 포인터 배열: 여러 포인터를 저장.
    • 배열 포인터: 배열 전체를 가리킴.

12.1 포인터와 배열의 관계

1) 배열은 포인터처럼 작동

  • 배열의 이름은 배열의 첫 번째 요소의 주소를 나타냅니다.
  • arr은 &arr[0]과 동일한 의미를 가집니다.
#include <stdio.h>

int main(void) {
    int arr[5] = {10, 20, 30, 40, 50};
    printf("arr: %p\n", arr);         // 배열의 시작 주소
    printf("&arr[0]: %p\n", &arr[0]); // 첫 번째 요소의 주소
    return 0;
}

출력 결과 (예시):

arr: 0x7ffeea9c3040
&arr[0]: 0x7ffeea9c3040

2) 포인터를 사용한 배열 요소 접근

  • 배열 요소는 포인터 연산을 통해 접근 가능합니다.
  • arr[i]는 *(arr + i)와 동일.
#include <stdio.h>

int main(void) {
    int arr[5] = {10, 20, 30, 40, 50};
    printf("arr[2]: %d\n", arr[2]);      // 30
    printf("*(arr + 2): %d\n", *(arr + 2)); // 30
    return 0;
}

출력 결과:

arr[2]: 30
*(arr + 2): 30

12.2 포인터와 배열의 차이점

1) 배열

  • 배열은 크기가 고정되어 있으며, 선언 시 크기를 변경할 수 없습니다.
int arr[5];  // 크기: 5

2) 포인터

  • 포인터는 배열처럼 작동하지만, 다른 메모리 위치를 가리킬 수 있음.
int *p;
p = arr;         // p는 arr를 가리킴
p = &arr[3];     // p는 arr[3]을 가리킴

12.3 이중 포인터와 2차원 배열

1) 2차원 배열

  • 2차원 배열은 배열의 배열로 표현됩니다.
  • arr[i][j]는 *(*(arr + i) + j)와 동일.
#include <stdio.h>

int main(void) {
    int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
    printf("matrix[1][2]: %d\n", matrix[1][2]);      // 6
    printf("*(*(matrix + 1) + 2): %d\n", *(*(matrix + 1) + 2)); // 6
    return 0;
}

출력 결과:

matrix[1][2]: 6
*(*(matrix + 1) + 2): 6

2) 이중 포인터와 2차원 배열

  • 이중 포인터는 동적으로 할당된 2차원 배열을 처리할 때 사용됩니다.
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int **matrix;
    int rows = 2, cols = 3;

    // 동적 메모리 할당
    matrix = (int **)malloc(rows * sizeof(int *));
    for (int i = 0; i < rows; i++) {
        matrix[i] = (int *)malloc(cols * sizeof(int));
    }

    // 값 할당
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            matrix[i][j] = i * cols + j + 1;
        }
    }

    // 값 출력
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }

    // 메모리 해제
    for (int i = 0; i < rows; i++) {
        free(matrix[i]);
    }
    free(matrix);

    return 0;
}

출력 결과:

1 2 3
4 5 6

12.4 문자열과 포인터

1) 문자열과 배열

  • 문자열은 char 배열로 저장됩니다.
  • 배열의 이름은 문자열의 첫 번째 문자를 가리키는 포인터.
#include <stdio.h>

int main(void) {
    char str[] = "Hello";
    printf("문자열: %s\n", str);
    printf("첫 번째 문자: %c\n", *str);
    return 0;
}

출력 결과:

문자열: Hello
첫 번째 문자: H

2) 문자열 상수

  • 문자열 상수는 포인터로 처리됩니다.
#include <stdio.h>

int main(void) {
    char *str = "Hello";
    printf("문자열: %s\n", str);
    printf("첫 번째 문자: %c\n", *str);
    return 0;
}

12.5 포인터 배열과 배열 포인터

1) 포인터 배열

  • 배열 안에 여러 포인터를 저장.
#include <stdio.h>

int main(void) {
    char *fruits[] = {"Apple", "Banana", "Cherry"};
    printf("첫 번째 과일: %s\n", fruits[0]);
    printf("두 번째 과일: %s\n", fruits[1]);
    return 0;
}

출력 결과:

첫 번째 과일: Apple
두 번째 과일: Banana

2) 배열 포인터

  • 배열 전체를 가리키는 포인터.
#include <stdio.h>

int main(void) {
    int arr[3] = {10, 20, 30};
    int (*p)[3] = &arr;

    printf("첫 번째 요소: %d\n", (*p)[0]);
    printf("두 번째 요소: %d\n", (*p)[1]);
    return 0;
}

출력 결과:

첫 번째 요소: 10
두 번째 요소: 20

12.6 심화 예제

1. 배열의 합 계산

#include <stdio.h>

int sumArray(int *arr, int size) {
    int sum = 0;
    for (int i = 0; i < size; i++) {
        sum += arr[i];
    }
    return sum;
}

int main(void) {
    int numbers[] = {1, 2, 3, 4, 5};
    int result = sumArray(numbers, 5);
    printf("배열의 합: %d\n", result);
    return 0;
}

출력 결과:

배열의 합: 15

2. 문자열 길이 계산

#include <stdio.h>

int stringLength(const char *str) {
    int length = 0;
    while (*str++) {
        length++;
    }
    return length;
}

int main(void) {
    char str[] = "Hello, World!";
    printf("문자열 길이: %d\n", stringLength(str));
    return 0;
}

출력 결과:

문자열 길이: 13
반응형