티스토리 뷰

반응형

 

C언어 기초 Chapter 13: 포인터와 배열 함께 이해하기


13-1. 포인터와 배열의 관계

배열과 포인터

  • 배열 이름은 사실상 첫 번째 원소의 주소
  • arr 와 &arr[0] 는 같은 의미

예제:

#include <stdio.h>
int main(void) {
    int arr[3] = {10, 20, 30};
    int *p = arr;   // arr == &arr[0]

    printf("%d %d\n", arr[0], *p);      // 10 10
    printf("%d %d\n", arr[1], *(p+1));  // 20 20
    printf("%d %d\n", arr[2], *(p+2));  // 30 30
    return 0;
}

👉 배열과 포인터는 밀접하게 연결되어 있음


13-2. 포인터 연산

포인터에 정수를 더하거나 빼면, 자료형 크기 단위로 이동

int arr[5] = {1, 2, 3, 4, 5};
int *p = arr;

printf("%d\n", *p);     // 1
printf("%d\n", *(p+1)); // 2
printf("%d\n", *(p+2)); // 3

⚠️ 주의: 포인터 연산은 같은 배열 내에서만 의미가 있음


13-3. 상수 형태의 문자열을 가리키는 포인터

#include <stdio.h>
int main(void) {
    char *str = "Hello";   // 문자열 상수 (읽기 전용)
    printf("%s\n", str);

    // str[0] = 'h';   // ❌ 오류 (문자열 상수 수정 불가)
    return 0;
}
  • "Hello" 는 메모리의 읽기 전용 영역에 저장
  • char str[] = "Hello"; 로 선언하면 수정 가능
char str[] = "Hello";
str[0] = 'h';   // 가능
printf("%s\n", str);  // hello

13-4. 포인터 변수로 이뤄진 배열: 포인터 배열

포인터 배열

  • 포인터들을 원소로 가지는 배열
  • 대표적으로 문자열 배열을 표현할 때 유용

예제:

#include <stdio.h>
int main(void) {
    const char *fruits[3] = {"Apple", "Banana", "Cherry"};

    for (int i = 0; i < 3; i++) {
        printf("%s\n", fruits[i]);
    }
    return 0;
}

👉 출력:

Apple
Banana
Cherry

2차원 배열과 포인터 배열 비교

char arr[3][10] = {"Apple", "Banana", "Cherry"};  // 2차원 배열
const char *ptr[3] = {"Apple", "Banana", "Cherry"}; // 포인터 배열
  • arr: 고정된 크기(각 문자열이 같은 길이)
  • ptr: 가변 길이 문자열 가능 (더 효율적)

핵심 정리 ✅

  • 배열 이름은 첫 번째 원소 주소와 동일
  • 포인터 연산은 자료형 크기 단위로 이동
  • 문자열 상수를 가리키는 포인터는 수정 불가
  • 포인터 배열은 문자열 집합을 관리할 때 유용

연습 문제 ✍️

  1. 배열 {10, 20, 30, 40, 50} 을 포인터를 이용해 출력해보세요.
  2. 포인터 연산을 이용해 배열의 합을 구하는 프로그램 작성하기.
  3. 문자열 상수 "Good" 을 char *str 로 선언했을 때와 char str[] 로 선언했을 때의 차이를 실험해보세요.
  4. 과일 이름 5개를 포인터 배열에 저장하고 모두 출력하는 프로그램을 작성하세요.

👉 연습문제 정답은? ▼

 

Chapter 13 연습문제 풀이


1) 배열 {10, 20, 30, 40, 50} 을 포인터로 출력하기

#include <stdio.h>
int main(void) {
    int arr[5] = {10, 20, 30, 40, 50};
    int *p = arr;

    for (int i = 0; i < 5; i++) {
        printf("%d ", *(p + i));
    }
    return 0;
}

👉 출력: 10 20 30 40 50


2) 포인터 연산으로 배열의 합 구하기

#include <stdio.h>
int main(void) {
    int arr[5] = {1, 2, 3, 4, 5};
    int *p = arr;
    int sum = 0;

    for (int i = 0; i < 5; i++) {
        sum += *(p + i);
    }

    printf("배열 합 = %d\n", sum);
    return 0;
}

👉 출력: 배열 합 = 15


3) 문자열 상수 "Good" 을 char *str 과 char str[] 로 선언했을 때 차이

#include <stdio.h>
int main(void) {
    char *str1 = "Good";   // 문자열 상수 (읽기 전용)
    char str2[] = "Good";  // 배열 (수정 가능)

    printf("str1 = %s\n", str1);
    printf("str2 = %s\n", str2);

    // str1[0] = 'F';  // ❌ 실행 시 오류 발생 가능 (읽기 전용)
    str2[0] = 'F';     // ✅ 가능
    printf("수정된 str2 = %s\n", str2);

    return 0;
}

👉 차이점

  • char *str1 = "Good"; → 읽기 전용 문자열 상수를 가리킴, 수정 불가
  • char str2[] = "Good"; → 배열에 복사, 수정 가능

4) 과일 이름 5개를 포인터 배열에 저장하고 출력하기

#include <stdio.h>
int main(void) {
    const char *fruits[5] = {"Apple", "Banana", "Cherry", "Orange", "Grape"};

    for (int i = 0; i < 5; i++) {
        printf("%s\n", fruits[i]);
    }
    return 0;
}

👉 출력:

Apple
Banana
Cherry
Orange
Grape

핵심 정리 ✅

  • 포인터를 이용하면 배열 원소를 쉽게 접근 가능
  • *(p+i) 는 arr[i] 와 동일
  • 문자열 상수는 수정 불가, 배열에 복사하면 수정 가능
  • 포인터 배열은 여러 문자열을 효율적으로 저장·출력 가능

 

반응형