정보처리기사/C

[C] Call by Value 문제 분석(24년7월 기출)

나르는나른 2025. 2. 13. 23:13
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
void swap(int a, int b) {
    int t = a;
    a = b;
    b = t;
}
int main() {
    int a = 11;
    int b = 19;
    
    swap(a, b);
    
    switch (a) {
        case 1:
            b += 1;
        case 11:
            b += 2;
        default:
            b += 3;
            break// Added break statement here
    }
    
    printf("%d", a - b);
}
cs

 

 

2024년 7월에 시행된 정보처리기사 기출문제다.

 

먼저 swap()함수 부분을 살펴보자

 

두 정수형 변수를 각각 a와 b라는 매개변수로 전달받고,

변수 t에 a의 값을 저장한다.

그리고 a에 b의 값을 저장한다.

그리고 b에 t의 값을 저장한다.

 

흐름으로 보았을때, a와 b의 값을 스왑(swap)하려는 함수인것같다.

 

하지만 이는 실제로 작동하지 않는다.

 

이유는 바로 「Call by Value(값에 의한 호출)」 때문이다.

 

C언어에서 함수의 매개변수는 기본적으로 값이 복사되어 전달된다.

즉, 원본 변수(a, b)의 값이 새로운 *지역 변수(a, b)에 복사되며, 함수 내부에서 값을 변경해도 원본 변수는 영향을 받지 않게된다.

*지역변수: 함수 또는 블록 내부에서 선언된 변수로, 해당 범위 내에서만 접근할 수 있는 변수

 

 

고로 main()의 switch(a)문에서는 case 11: 이 실행되며, break; 가 없으므로 폴스루(fall-through)가 발생하여 default: 도 함께 실행된다.

a=11

b=24

11 - 24 = -13

 

 

문제에서 유도하려고 했던 swap 기능을 정상적으로 기능하도록 하기 위해서는

1. main() 함수에서 swap()을 호출할 때 각 변수의 주소를 인수(Argument)로 전달해야 한다.

2. swap() 함수의 매개변수를 포인터 변수(Parameter)로 선언하여 주소를 전달받아야 한다.

3. 함수 내에서 변수에 접근할 때 포인터 역참조(Dereference)를 통해 원본 변수의 값을 변경해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
void swap(int *a, int *b) {
    int t = *a;
    *= *b;
    *= t;
}
int main() {
    int a = 11;
    int b = 19;
    
    swap(&a, &b);
    
    switch (a) {
        case 1:
            b += 1;
        case 11:
            b += 2;
        default:
            b += 3;
            break// Added break statement here
    }
    
    printf("%d", a - b);
}
cs

 

이렇게 하면, 의도대로 swap 함수가 정상적으로 기능하여

5 라는 실행 결과가 나온다.

 

원본 변수(a, b)의 주소를 swap() 함수에 인수로 전달한다.

swap() 함수는 전달받은 변수의 주소를 역참조하여 실제 값에 접근하고 변경한다.

변수 t 에 *a (a가 가리키는 값)를 저장한다.

*a(a가 가리키는 값)에 *b(b가 가리키는 값)를 저장한다.

*b(b가 가리키는 값)에 t를 저장한다.

 

즉, a와 b가 가리키는 값이 서로 바뀌게된다.

참고로, a와 b가 저장하고 있는 주소는 변하지 않는다.