C언어 초급 - 10장: 포인터 (10.3 포인터와 함수)

2025. 2. 24. 11:46프로그래밍 언어/C

10.3 포인터와 함수

C 언어에서 포인터를 함수의 매개변수로 전달하면
함수가 직접 변수의 값을 수정할 수 있어 효율적이고 유연한 프로그래밍이 가능합니다.
또한, 문자열을 다룰 때 문자열 포인터를 사용하면 메모리를 효율적으로 관리할 수 있습니다.


1. 포인터를 매개변수로 전달

1.1 포인터를 사용한 함수 호출 방식

함수에서 변수를 변경하려면 포인터를 사용하여 변수의 주소를 전달해야 합니다.

함수 호출 방식 설명  예제
값 전달(Call by Value) 복사본을 전달하여 원본 값이 변경되지 않음 void func(int a);
주소 전달(Call by Reference) 변수의 주소를 전달하여 원본 값 변경 가능 void func(int *p);

1.2 값 전달(Call by Value) 예제

값을 직접 전달하면, 함수 내부에서 변경해도 원본 값은 변경되지 않습니다.

#include <stdio.h>

void changeValue(int num) {
    num = 100;  // 변경되지만 main의 변수에는 영향을 주지 않음
}

int main() {
    int a = 10;
    
    printf("변경 전: %d\n", a);
    changeValue(a);  // 값 전달
    printf("변경 후: %d\n", a);  // a 값 유지

    return 0;
}

출력 결과

변경 전: 10
변경 후: 10

📌 설명

  • changeValue(a) 호출 시 a의 복사본이 전달됨.
  • 따라서 함수 내부에서 값을 변경해도 원본 변수 a는 영향을 받지 않음.

1.3 포인터를 사용한 주소 전달(Call by Reference)

포인터를 사용하면 함수 내부에서 원본 값을 직접 수정할 수 있습니다.

#include <stdio.h>

// 포인터를 사용하여 값 변경
void changeValue(int *ptr) {
    *ptr = 100;  // 포인터가 가리키는 변수의 값 변경
}

int main() {
    int a = 10;

    printf("변경 전: %d\n", a);
    changeValue(&a);  // 주소 전달
    printf("변경 후: %d\n", a);  // a 값이 변경됨

    return 0;
}

출력 결과

변경 전: 10
변경 후: 100

📌 설명

  • changeValue(&a); → a의 주소를 전달.
  • *ptr = 100; → 포인터를 통해 a의 값을 직접 변경.

이 방식은 함수가 여러 값을 반환하거나 큰 데이터를 수정할 때 유용합니다.
특히 동적 메모리 할당, 배열, 문자열 처리에서 많이 사용됩니다.


2. 포인터를 이용한 두 변수 값 교환 (Swap)

포인터를 사용하면 두 변수의 값을 쉽게 교환할 수 있습니다.

#include <stdio.h>

// 두 변수의 값을 교환하는 함수
void swap(int *x, int *y) {
    int temp = *x;
    *x = *y;
    *y = temp;
}

int main() {
    int a = 5, b = 10;

    printf("교환 전: a = %d, b = %d\n", a, b);
    swap(&a, &b);  // 주소 전달
    printf("교환 후: a = %d, b = %d\n", a, b);

    return 0;
}

출력 결과

교환 전: a = 5, b = 10
교환 후: a = 10, b = 5

📌 설명

  • swap(&a, &b); → a와 b의 주소를 전달하여 값을 직접 변경.
  • temp 변수를 사용하여 값 교환.

포인터를 사용하지 않으면, 두 변수를 교환하는 함수는 원본 값을 변경할 수 없습니다.


3. 문자열 포인터 활용

3.1 문자열을 포인터로 관리

C에서는 문자열이 char 배열의 형태로 저장됩니다.
배열의 이름 자체가 첫 번째 문자의 주소를 의미하므로, 문자열을 포인터로 다룰 수 있습니다.

#include <stdio.h>

int main() {
    char str[] = "Hello, World!";
    char *ptr = str;  // 문자열을 포인터로 관리

    printf("문자열: %s\n", ptr);
    printf("첫 번째 문자: %c\n", *ptr);
    
    return 0;
}

출력 결과

문자열: Hello, World!
첫 번째 문자: H

📌 설명

  • ptr = str; → 문자열의 첫 번째 문자 주소를 ptr에 저장.
  • *ptr → 첫 번째 문자(H)를 출력.

문자열을 포인터로 다루면 메모리를 효율적으로 사용할 수 있습니다.


3.2 문자열을 함수에 전달

문자열을 함수에 전달할 때는 배열 전체가 아니라, 포인터(주소)만 전달하면 됩니다.

#include <stdio.h>

// 문자열을 매개변수로 받는 함수
void printMessage(char *msg) {
    printf("메시지: %s\n", msg);
}

int main() {
    char text[] = "Hello, C Programming!";
    
    printMessage(text);  // 문자열 포인터 전달
    
    return 0;
}

출력 결과

메시지: Hello, C Programming!

📌 설명

  • text는 배열의 첫 번째 문자 주소를 의미.
  • char *msg → 문자열 포인터를 매개변수로 받아 처리.

문자열을 포인터로 전달하면 메모리를 효율적으로 사용할 수 있습니다.


3.3 문자열 수정 (포인터 활용)

포인터를 이용하면 문자열의 내용을 직접 수정할 수 있습니다.

#include <stdio.h>

int main() {
    char str[] = "Hello";
    char *ptr = str;  // 문자열의 주소를 포인터에 저장

    *ptr = 'h';  // 첫 번째 문자 변경
    printf("수정된 문자열: %s\n", str);

    return 0;
}

출력 결과

수정된 문자열: hello

📌 설명

  • *ptr = 'h'; → 첫 번째 문자를 'h'로 변경.

배열에 저장된 문자열은 수정이 가능하지만, 문자열 리터럴(상수 문자열)은 수정할 수 없습니다.


4. 정리

개념  설명  예제
포인터 매개변수 전달 함수에서 변수 값을 직접 변경 가능 void func(int *p);
주소 전달(Call by Reference) 포인터를 사용하여 변수 값 변경 swap(int *a, int *b);
포인터를 이용한 문자열 관리 문자열을 포인터로 다룸 char *ptr = str;
문자열을 함수에 전달 포인터를 사용하여 문자열 전달 void printMsg(char *msg);
포인터를 통한 문자열 수정 포인터로 문자열의 일부 문자 변경 *ptr = 'A';

📌 포인터를 사용하면 변수 값을 직접 변경할 수 있음 (Call by Reference)
📌 문자열은 포인터로 쉽게 관리할 수 있으며, 메모리를 효율적으로 사용 가능
📌 함수에 문자열을 전달할 때 포인터를 사용하면 속도가 빠르고 메모리 사용량이 줄어듦