함수 매개변수의 평가순서
간단한 코드의 실행결과를 맞춰보시라
[문제] 자주 하는 실수 1
#include <stdio.h>
int add_ten(void)
{
static int number = 0;
number += 10;
return number;
}
int main(void)
{
printf("%d %d %d\n", add_ten(), add_ten(), add_ten());
return 0;
}
1. 10 20 30
2. 30 20 10
3. 알 수 없음
정답은.... 알 수 없음!!
엥? Visual Stdio에서 돌리니까 30 20 10 나오던데요?
C표준에서는 함수 매개변수 안에 함수를 줄줄이 넣었을 때 어떤 함수부터 호출되는지는 명시하지 않았다.(어떻게 하던지 컴파일러 마음이다)
이런 매개변수 안에 있는 계산들을 누구부터 할지 정하는 것은 평가순서라고 한다.
평가순서는 시퀀스 포인트(sequence point)만이 정한다.
예를 들면 세미콜론(;)이 시퀀스 포인트이다. 그렇기 때문에 C언어가 한 줄 한 줄씩 실행이 된다.
그리고 신기한 것은 시퀀스 포인트에 ||, &&, 삼항연산자(? !)도 포함이 된다.
그렇다면 다음 문제를 풀어보자
자주 하는 실수 2 (평가 순서)
int check_bag = 0;
int checking_bag(void)
{
/* 만약에 가방이 있으면 check_bag 를 1로 바꾸는 로직 */
check_bag = 1;
return check_bag;
}
int checking_things(void)
{
/* 가방이 있으면 1을 반환하는 로직 */
if (check_bag == 1) {
return 1;
} else {
return 0;
}
}
int main(void)
{
/* 다른 코드 생략 */
if ( checking_bag() + checking_things() == 2) {
printf("가방안에 물건이 있습니다.\n");
}
return 0;
}
이 코드를 개발한 사람의 로직
- 메인함수 안에 조건문에서 checking_bag()가 실행이 되고 checking_things()이 실행이 될 거야
- checking_bag()가 먼저 실행이 돼서 가방이 있으면 check_bag = 1로 하고 check_bag를 반환해
- 그다음 checking_things() 함수가 실행이 돼서 check_bag가 1인지 체크를 해서 1이면 1을 반환하고 아니면 0을 반환해
- checking_bag()가 0 이면 checking_things() 도 0이니 조건문이 실행이 안될 거야
- checking_bag()가 1 이면 checking_things() 도 1이니 조건문이 실행되겠지?
하지만 아까 전에 말한 것처럼 평가순서는 무조건 시퀀스 포인트만이 정하는 것이므로 어느 함수가 먼저 실행이 될지는 모른다.
그래서 checking_things() 함수가 먼저 실행이 돼서 체크를 하니 check_bag가 0이어서 0을 반환하고 checking_bag() 함수가 이후에 실행이 돼서 1을 반환하게 되면 조건문이 실행되지 않게 된다.
즉, checking_things() 함수가 먼저 호출(평가)될 보장이 없다는 뜻이다.
해결책
두 함수를 두줄에 따로 호출할 것
연산자 우선순위와 평가순서의 관계?
자주 하는 실수 3
int result = add(num1, num2) + subtract(num1, num2) * divide(num1, num2);
어떤 함수가 먼저 호출(평가)될까?
subtract() -> divide() -> add()
add() -> subtract() -> divid()
알 수 없음
이 문제의 답은 또 '알 수 없음'이다.
엥? 곱셈부터 계산하고 덧셈계산해야 되니 subtract(), divide() 하고 add()해야 되는 거 아닌가요?
평가순서랑 연산자 우선순위는 아무런 연관이 없다!
+ * 모두 시퀀스 포인트가 아니다
그렇기에 함수는 아무 순서로 호출해도 상관이 없고 그 결과를 연산자 우선법칙으로 계산하는 것이다.
정리
- 한 줄에 있는 피연산자들은 기본적으로 평가순서가 보장 안됨
- ||, &&, 삼항연산자(? !), ;(세미콜론)은 평가순서가 보장됨(시퀀스 포인트)
- 연산자 우선법칙이랑 평가순서는 아무런 관련이 없음
출처 : POCU Academy COMP2200
'C언어 > C언어' 카테고리의 다른 글
[C언어]강제 형변환 (0) | 2023.02.17 |
---|---|
[C언어]스택(Stack) 메모리 (0) | 2023.02.17 |
[C언어]링크(Link) 단계 (컴파일과 링크가 따로 되어있는 이유) (0) | 2023.02.16 |
[C언어][Hex]헥스편집기 HxD editor 다운로드 방법 (0) | 2023.02.16 |
[C언어]어셈블(Assemble) 단계 (0) | 2023.02.16 |
댓글