C 为什么编译程序时最大和最小int不起作用?

C 为什么编译程序时最大和最小int不起作用?,c,gcc,C,Gcc,我不明白为什么会出现错误: ~/SecureSoftware$ gcc AddNumTest.c AddNumTest.c:11:0: warning: "INT_MAX" redefined [enabled by default] /usr/lib/gcc/x86_64-linux-gnu/4.6/include-fixed/limits.h:121:0: note: this is the location of the previous definition 我正在寻找一种方法,在命令

我不明白为什么会出现错误:

~/SecureSoftware$ gcc AddNumTest.c
AddNumTest.c:11:0: warning: "INT_MAX" redefined [enabled by default]
/usr/lib/gcc/x86_64-linux-gnu/4.6/include-fixed/limits.h:121:0: note: this is the location of the previous definition
我正在寻找一种方法,在命令行中添加一个大数字时,不会使程序崩溃

#include<stdio.h>
#include <stdlib.h>
#include <limits.h>
#define INT_MAX  (2147483647)
#define INT_MIN  (-2147483647)

int main(int argc, char** argv)
{
   int i, TotalOfNumbers = 0;


   for (i = 1; i < argc; i++)
   {
      TotalOfNumbers += atoi(argv[i]);
      printf("Total of numbers entered = %d\n", TotalOfNumbers);
   }
   return 0;
}
#包括
#包括
#包括
#定义整数最大值(2147483647)
#定义整数最小值(-2147483647)
int main(int argc,字符**argv)
{
整数i,总数=0;
对于(i=1;i
重新定义
INT\u MIN
INT\u MAX
不会改变实际限制,只会使描述它们的常数不准确

限制基于平台的整数大小/宽度。要有真正不同的限制,您需要使用不同的数据类型(例如,
long
,而不是
int

如果
long
不够大,您可能需要进一步上移到
long
;请注意,这些在C99标准之前没有指定,因此您需要有一个合理的现代编译器


将程序更改为使用
long
s而不是
int
s将如下所示:

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

int main(int argc, char** argv)
{
   long long i, TotalOfNumbers = 0;

   for (i = 1; i < argc; i++)
   {
      TotalOfNumbers += atoll(argv[i]);
      printf("Total of numbers entered = %lld\n", TotalOfNumbers);
   }
   return 0;
}
#包括
#包括
#包括
int main(int argc,字符**argv)
{
长i,总数量=0;
对于(i=1;i这是在C语言中将文本转换为整数的正确方法:
atoi
与之不同,
strtol
实际上会告诉您数字是否太大,尽管有点尴尬

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

long
reliable_atol(const char *s)
{
    char *endp;
    long rv;
    errno = 0;
    rv = strtol(s, &endp, 10);
    if (errno || endp == s || *endp) {
        fprintf(stderr, "number malformed or out of range: %s\n", s);
        exit(1);
    }
    return rv;
}
强制转换是必需的,因为有符号整数溢出会引发未定义的行为,但无符号整数溢出不会。从技术上讲,这段代码在非twos补码CPU上不起作用,但几十年来没有人生产过这种CPU,而C标准对这种可能性的持续规定无疑是愚蠢的

如果我将上述两个代码示例粘在一起,形成一个完整的程序,我将为您的测试用例得到以下结果:

$ gcc -O2 -Wall test.c       # default mode for this CPU+OS: long is 64 bits
$ ./a.out 22220020202 45
total 22220020247

$ gcc -O2 -Wall -m32 test.c  # alternative mode: long is 32 bits
$ ./a.out 22220020202 45 
number malformed or out of range: 22220020202

为什么要定义自己的
INT\u MAX
INT\u MIN
?正如警告所说,它们已经提供了——并且提供的值是您平台的正确值。@CharlesDuffy:因为他试图设置有效整数的范围,我想……每当我没有定义它们时,我就会抛出这个错误消息。AddNumTest.c:12:0:警告:“INT_MIN”重新定义[默认启用]/usr/lib/gcc/x86_64-linux-gnu/4.6/include fixed/limits.h:119:0:注意:这是上一个definition@Derk原谅只有在两个地方定义了某些内容时,才会出现该错误消息。其中一个位置将位于
limits.h
(或它调用的东西)内。另一个是当您添加显式的
#define
时。答案是去掉
#define
s,让
#include
完成它的工作。我现在可以编译我的程序,但是当我运行一个整数,比如“220202020”时,我的程序将显示它返回为“输入的数字总数=-95124572”,我将我的值改为longs@Derk,在x86_64系统上非常适合我(使用该特定数字;当然不能超过MAX_LONG)@Derk…也就是说,我将其修改为使用
long-long
s——尽管使用64位编译器,这应该是不必要的。如果您能够重现问题,请提供生成问题时使用的确切整数。好的,当我添加long-long时,我的程序会编译,但它不会读取正确的数字。这正是我所做的I’我输入了“./a.out 222020202 45输入的数字总数=745183722输入的数字总数=745183767”我的程序会加上45,但我不知道为什么我会得到第一个数字?你可能想要循环后的
printf
?不过我不确定745183722是从哪里来的,除非你的
long
实际上不是64位。我不会把它放在Microsoft之前,但你的错误消息看起来像GCC,所以不是这样的。W当我试图检测溢出时,我抛出了这个错误消息。“AddNumTest.c:在函数'main':AddNumTest.c:16:2:error:'for'循环初始声明只允许在C99模式下使用AddNumTest.c:16:2:注意:使用选项-std=C99或-std=gnu99编译代码”对不起,我太草率了。只需将
int
中取出即可(int i=1;…
好的,当我现在尝试编译它时,我收到这个错误消息“gcc AddNumTest.c/tmp/cc96bWF7.o:In function
main”:AddNumTest.c:(.text+0x3c):对
reliable\u atol'collect2:ld返回1退出状态的未定义引用”一个完整的程序需要两个代码片段,你甚至都没有试图理解错误消息在说什么——是的,它们简明扼要,但很有意义。
$ gcc -O2 -Wall test.c       # default mode for this CPU+OS: long is 64 bits
$ ./a.out 22220020202 45
total 22220020247

$ gcc -O2 -Wall -m32 test.c  # alternative mode: long is 32 bits
$ ./a.out 22220020202 45 
number malformed or out of range: 22220020202