본문 바로가기
C++/C++ 문법

C++ 함수와 매개변수

by Sein_ 2025. 10. 13.
728x90

[Do it C++ 완전정복_ 119~124, 127~128p]

함수 기본 사용법

함수 정의
반환형 함수명(매개변수들) { ... }
→ 함수의 실제 동작을 작성하는 부분

함수 호출
함수명(인자들);
→ main()이나 다른 함수 안에서 실행시키는 구문

함수 원형(선언)
반환형 함수명(매개변수형 …);
→ 함수가 정의보다 먼저 호출될 때 필요

 

#include <iostream>

// 함수 원형(선언)
int add(int a, int b);

int main() {
    int result = add(3, 5);          // 함수 호출
    std::cout << "result = " << result << '\n';
    return 0;
}

// 함수 정의
int add(int a, int b) {
    return a + b;
}

 

함수의 매개변수 전달

함수의 호출 방식 참고 (https://slowbreeze.tistory.com/234)

 

1. 값 전달

  • 매개변수는 기본적으로 복사되어 전달(=값에 의한 전달)됩니다.
  • 함수 안에서 값을 바꿔도 원본에는 영향이 없습니다.
void addOne(int n) {    // 복사본 n 생성
    n = n + 1;
}

int main() {
    int a = 10;
    addOne(a);
    cout << a << endl;  // 결과: 10 (원본은 그대로)
}

 

2. 포인터로 전달

  • 변수의 주소를 매개변수로 전달합니다.
  • 간접 접근(역참조)을 통해 원본 값을 수정할 수 있습니다.
void addOne(int* n) {   // 주소를 받음
    (*n)++;             // 포인터로 가리키는 실제 변수 값 변경
}

int main() {
    int a = 10;
    addOne(&a);         // 주소 전달
    cout << a << endl;  // 결과: 11 (원본 변경)
}

 

3. 참조 전달

  • 원본 변수를 직접 참조하여 전달합니다.
  • 포인터보다 문법이 간단하고, 원본 변수 자체를 그대로 다룰 수 있습니다.
void addOne(int& n) {   // 참조로 전달
    n++;
}

int main() {
    int a = 10;
    addOne(a);          // 변수 그대로 전달 (주소 아님)
    cout << a << endl;  // 결과: 11 (원본 변경)
}

 

 

배열을 매개변수로 사용하는 방법

배열명(=첫 번째 요소의 주소)을 함수에 전달하면 자동으로 포인터로 변환되어 전달된다.

배열의 크기 정보는 사라지므로, 크기를 따로 매개변수로 전달해야 한다.

// 동일한 함수 선언
void printArray(int arr[], int size);
void printArray(int* arr, int size);

 

void printArray(const int arr[], int size) {
    for (int i = 0; i < size; i++)
        cout << arr[i] << " ";
    cout << endl;
}

int main() {
    int nums[5] = {1, 2, 3, 4, 5};
    printArray(nums, 5);  // 배열명 = 첫 번째 요소의 주소
}

 

구조체를 매개변수로 사용하는 방법

  • 구조체 변수를 함수에 전달할 때 값, 포인터, 참조로 전달할 수 있다.
  • 구조체가 큰 경우 포인터나 참조로 전달하는게 효율적이다.
  • 포인터로 구조체를 가리킬 경우, 멤버에 접근할 때 . 대신 -> 연산자를 사용해야한다. (*포인터).멤버 == 포인터->멤버
struct Point {
    int x;
};

// 값으로 전달 (복사본)
void passValue(Point p) {
    p.x += 1;
    cout << "passValue 내부: x = " << p.x << endl;
}

// 포인터로 전달 (주소 전달)
void passPointer(Point* p) {
    p->x += 1;
    cout << "passPointer 내부: x = " << p->x << endl;
}

// 참조로 전달 (원본 직접 접근)
void passReference(Point& p) {
    p.x += 1;
    cout << "passReference 내부: x = " << p.x << endl;
}

int main() {
    Point a = {1};

    passValue(a);        // 복사본 전달 → 원본 변화 없음
    cout << "값 전달 후: x = " << a.x << endl << endl;

    passPointer(&a);     // 주소 전달 → 원본 수정
    cout << "포인터 전달 후: x = " << a.x << endl << endl;

    passReference(a);    // 참조 전달 → 원본 직접 수정
    cout << "참조 전달 후: x = " << a.x << endl;
}