무민은귀여워

같은 자료형인 두 값을 교환하는 함수 형식 매크로 ( swap 매크로 ) 본문

IT/c, c++

같은 자료형인 두 값을 교환하는 함수 형식 매크로 ( swap 매크로 )

moomini 2021. 5. 18. 00:09
반응형
1
2
3
4
5
6
7
8
9
10
/*-- type형 x와 y의 값을 교환 */
#define swap(type, x, y) do{ type t = x; x = y; y = t;}while(0)
 
/*-- 요소 개수가 n인 배열 a의 요소를 역순으로 정렬 --*/
void ary_reverse(int a[], int n)
{
    int i;
    for (i = 0; i < n / 2; i++)
        swap(int, a[i], a[n - i - 1]); 
}
cs

Q. 같은 자료형의 두 값을 교환하는 함수 형식 매크로 swap의 정의에서 { } 블록이 do문으로 둘러싸인 이유

A-1. 잘못된 정의(블록을 do문으로 둘러싸고 있지 않은 경우)

1
2
3
4
if(a > b)
    swap(int, a, b);
else
    swap(int, a, c); 
cs

 

이렇게 정의하면 컴파일 오류가 발생한다.

 

매크로 치환 후의 프로그램을 보자. 

a > b를 만족한다고 가정하면 if의 { }블록이 실행된다. 그러면 바로 뒤에 else가 와야 하는데 치환한 자리 다음에 불필요한 세미콜론 ;이 나온다. 이렇게 되면 else에 대응하는if가 세미콜론에 의해 끊어진다.

1
2
3
4
if(a > b)
    { type t = a; a = b; b = t; } ; // if문 종료! 
else
    { type t = a; a = c; c = t; } ;
cs

이 문제를 해결하기 위해 아래와 같이 세미콜론을 없애면 매크로가 치환한 다음의 컴파일 오류는 피할 수 있다.

하지만 이러한 코드는 C언어 프로그램답지 않다. 또한 실수로 세미콜론을 붙이는 것만으로 오류가 발생할 수도 있는 호출 방법을 사용자에게 권할 수는 없다.

1
2
3
4
if(a > b)
    swap(int, a, b)
else
    swap(int, a, c)
cs

 

A-2. 올바른 정의(블록을 do문으로 둘러싸는 경우)

1
2
3
4
5
6
#define swap(type, x, y) do{ type t = x; x = y; y = t; } while(0)
 
if(a > b)
    do { type t = a; a = b; b = t; } while(0);
else
    do { type t = a; a = c; c = t; } while(0);
cs

이렇게 해야 치환한 다음의 전체 코드가 올바른 if문이 된다. 왜냐하면 do문의 구문 표기법은 'do문 while(식);'이기 때문이다.

반응형
Comments