2014-10-14 13 views
0

간단한 C 프로그램에서 서명되지 않은 int 데이터 형식과 기본 메서드 매개 변수를 모두 실험하고 있습니다. 실험으로 저는 명령 행에서 정수를 주 메소드에 대한 매개 변수로 취하고 그 수와 0 사이의 모든 정수를 합한 프로그램을 작성했습니다.C 부호없는 삽입 조작 - 정수 오버플로

예 : 프로그램은 F (N) = (1 + 2 + 3 ... + n)의 유효 N> 0

#include <stdio.h> 
#include <stdlib.h> 

const unsigned int MAX_NUM = 92681; //Max input that will avoid int overflow later on 

unsigned int sum(unsigned int x); 

int main(int argc, char *argv[]) { 

    unsigned int input = atoi(argv[1]); 

    if (input < 0 || input > MAX_NUM) { 
     printf("Invalid input! Input must be less than 92682\n"); 
     exit(0); //If input > MAX_NUM, quit program 
    } 

    unsigned int result = sum(input); 

    printf("Sum to %d = %d\n", input, result); 

    return 0; 
} 

unsigned int sum(unsigned int x) { 
    unsigned int sum = 0; 
    unsigned int y; 
    for (y = 0; y <= x; y++) { 
     sum += y; 
     printf("Current sum:\t%u\n",sum); 
    } 
    return sum; 
} 

I 통지하기 시작 먼저 정수 오버플 하였다 계산할 때 F (N)> 2147483648 - 일명 서명 된 int의 최대 값

내 프로그램에서 생성 된 결과가 부호있는 int의 경우 65535이고 unsigned int의 경우 92681이되도록 정수로 오버플로하기 전에 유효한 최대 값을 수작업으로 찾았습니다.

부호있는 int에 대한 프로그램을 실행하면 예상되는 결과가 나타났습니다. 65535에서 정수가 넘치면 매우 큰 양수가 매우 큰 음수가됩니다.

그런 다음 모든 "int"를 "unsigned int"로 변경했습니다. 이 정수 오버플로에도 불구하고 int가 부호가 있고 부호가없는 것처럼 발생합니다.

제 질문은 a) 이유가 무엇입니까? b) 내 대답에서 부호없는 int의 모든 범위, 즉 0부터 (2^32) - 1까지를 사용할 수 있도록 어떻게 만들 수 있습니까 (음수 값이 필요하지 않음).

대단히 감사합니다.

+1

가우스의 팁 : n * (n-1)/2. –

+1

그게 어떻게 최대 값을 계산 즉. 2^32 = n * (n-1)/2 – davidhood2

답변

4

최종 printf 형식을 서명 됨에서 서명되지 않은 형식으로 변경하는 것을 잊었습니다.

변경 :

printf("Sum to %d = %d\n", input, result); 

에 : 수 있도록 컴파일러 경고 (예를 들어, gcc -Wall ...)이이 당신을 경고 한 것이다

printf("Sum to %u = %u\n", input, result); 
       ^^ ^^ 

참고. 항상 컴파일러 경고를 활성화하고 항상주의를 기울이십시오.

+1

오우 와우 - 나는 어리 석다! 고맙습니다. – davidhood2

+0

글쎄, 이것이 컴파일러 경고를 항상 가능케한다면, 그럴 가치가있을 것입니다. ;-) –

+1

@PaulR OP가 사용하고 있는지는 모르지만 MSVC가 마침내이 경고를 내기 시작했으면 좋겠다. "/ analyze"좀 그렇지만이 특별한 경우 (서명/서명되지 않은 불일치). 오 잘, 적어도 우리는 마침내 C99 (sn)'printf'를 "14"버전에서 한숨을 쉬게 할 것입니다. ;;) – user2802841