首页 文章

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

提问于
浏览
0

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

例如 . 当n> 0时,程序计算f(n)=(1 2 3 ... n)有效

#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)> 2147483648时 - 也就是有符号int的最大值 .

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

为签名的int运行程序产生了预期的结果 - 在65535,当整数溢出时,非常大的正数变为非常大的负数 .

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

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

非常感谢!

1 回答

  • 4

    您忘了将最终的 printf 格式从已签名更改为无符号 .

    更改:

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

    至:

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

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

相关问题