我在简单的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 回答
您忘了将最终的
printf
格式从已签名更改为无符号 .更改:
至:
请注意,启用编译器警告(例如
gcc -Wall ...
)会提醒您这一点 . 始终启用编译器警告并始终注意它们 .