2012-03-01 6 views
1

가능한 중복은 :
Unsigned and signed comparison
A riddle (in C)비교 연산

#include<stdio.h> 
#define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0])) 
int array[] = {23,34,12,17,204,99,16}; 
int main() 
{ 
    int d = -1; 
    if (d < TOTAL_ELEMENTS) 
     printf("of course -1 is less than %d",TOTAL_ELEMENTS); 
    else 
     printf("how on earth"); 
    return 0; 
} 

대답은 위의 프로그램의 출력은 :::입니다 : 도대체 어떻게

+1

무엇이 당신의 질문입니까?! –

+0

참고 사항 : http://stackoverflow.com/questions/950051/confused-about-c-macro-expansion-and-integer- arithmetic – Mat

답변

3

때를 혼합 된 부호 대 서명되지 않은 비교를 수행합니다 (여기서 s igned 타입이 부호없는 것보다 크지 않은 경우), 비교는 부호없는 도메인에서 수행된다. 즉, 부호있는 피연산자가 암시 적으로 부호없는 타입으로 변환된다.

TOTAL_ELEMENTS에는 부호가없는 size_t 유형이 있습니다. 즉, d도 암시 적으로 size_t 유형으로 변환됩니다. 따라서 d < TOTAL_ELEMENTS은 실제로 (size_t) d < TOTAL_ELEMENTS 또는 (size_t) -1 < TOTAL_ELEMENTS으로 해석됩니다.

(size_t) -1은 매우 큰 양수 값입니다. 실제로는 size_t 유형의 가능한 최대 값입니다. 따라서 결과는 얻을 수 있습니다.

귀하의 경우에는 분명히 서명 된 비교가 필요합니다. 이를 위해 명시 적으로 부호없는 값을 부호있는 유형으로 변환해야합니다 (오버플로가 발생하지 않도록 세심한주의).

if (d < (int) TOTAL_ELEMENTS) 
    ... 
2

sizeof_t부호없는 긴 유형에 매핑 때문이다 "예상대로"예를 들어,이 때문에 -10xFFFFFFFFFFFFFFFF, 오히려 큰 긍정적 정수되고, 작동합니다. 이 시도 :

#include<stdio.h> 
#define TOTAL_ELEMENTS(a) ((int)(sizeof((a))/sizeof(*(a)))) 
int array[] = {23,34,12,17,204,99,16}; 
int main() { 
    int d = -1; 
    if (d < TOTAL_ELEMENTS(array)) { 
     printf("of course -1 is less than %d",TOTAL_ELEMENTS(array)); 
    } else { 
     printf("how on earth"); 
    } 
    return 0; 
} 

주 내가 어떻게 그 매개 변수로 array을 참조하는 매크로를 다시 쓰고, -1에 비교하는 것은 예상 된 결과를 가져다 줄 수 있도록 int에 깁스를했다.