C操作无符号的Ints - 整数溢出

时间:2014-10-14 20:51:06

标签: c int integer-overflow atoi unsigned-integer

我在简单的C程序中试验unsigned int数据类型和main方法参数。作为一个实验,我编写了一个程序,它从命令行获取一个int数作为main方法的参数,并将该数字与0之间的每个整数相加。

E.g。当n> 1时,程序计算f(n)=(1 + 2 + 3 ... + 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;
}

我开始注意到的第一件事是f(n)&gt;时整数溢出。 2147483648 - 也就是已签名的int的最大值。

我手工数学地找到了最大值,我的程序生成的结果有效(例如在整数溢出之前)对于有符号整数是65535而对于无符号整数是92681。

运行有符号整数的程序产生预期的结果 - 在65535,当整数溢出时,非常大的正数变为非常大的负数。

然后我通过并将每个“int”更改为“unsigned int”。尽管出现这种整数溢出,就好像int是有符号的而不是无符号的。

我的问题是a)这是为什么? b)我怎样才能使我的答案可以使用整个范围的无符号整数,即0到(2 ^ 32) - 1(因为我不需要负值!)。

非常感谢!

1 个答案:

答案 0 :(得分:4)

您忘记将最终printf格式从已签名更改为无签名。

变化:

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

为:

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

请注意,启用编译器警告(例如gcc -Wall ...)会提醒您这一点。始终启用编译器警告并始终注意它们。