C 大数字之间的比较不';好像不行

C 大数字之间的比较不';好像不行,c,if-statement,C,If Statement,我写的程序取两个数,进行除法和模运算 代码是 #define ADDRESS_SPACE 4294967295 int main (int argc, char *argv[]) { long int pagesize = atoi(argv[1]), virtaddr = atoi(argv[2]); if (virtaddr >= ADDRESS_SPACE) {puts("Address is too large"); return 1;} printf(

我写的程序取两个数,进行除法和模运算

代码是

#define ADDRESS_SPACE 4294967295
int main (int argc, char *argv[]) {
    long int pagesize = atoi(argv[1]), virtaddr = atoi(argv[2]);

    if (virtaddr >= ADDRESS_SPACE) {puts("Address is too large"); return 1;}

    printf("%lu\n", virtaddr);
    printf("%lu\n", ADDRESS_SPACE);
    printf("Page = %lu\nOffset = %lu\n", virtaddr/pagesize, virtaddr%pagesize);
    return 0;
}
执行
/page 1024 99999999999999999999999999999999999999999999999999999999
将给出以下输出

18446744073709551615
4294967295
Page = 0
Offset = 18446744073709551615

如果
virtaddr
大于
ADDRESS\u SPACE
,为什么If语句不能工作?我知道有溢出,但打印变量不会显示任何错误,它们仍然是数字(长整型可以接受的最大值).

因为
atoi
从ASCII转换为
int
,而不是
长int
,而且
99999999999999999999999999999
转换为
int
太大了


尝试使用字符串转换并尝试更合理的数字。

因为
atoi
将ASCII转换为
int
,而不是
长int
,而且
99999999999999999999999999999999999999999
转换为
int
要大得多


尝试使用进行字符串转换,并尝试更合理的数字。

atoi
当数字超出范围时返回
INT\u MAX
。将32位
int
4294967295
进行比较总是错误的,因为
int\u MAX
大约小两倍。如果使用而不是
atoi
,您的解决方案将有效,因为结果将在
long
范围内。或者,当数字超出范围时,可以使用
INT\u MAX
而不是
ADDRESS\u SPACE
atoi
返回
INT\u MAX
。将32位
int
4294967295
进行比较总是错误的,因为
int\u MAX
大约小两倍。如果使用而不是
atoi
,您的解决方案将有效,因为结果将在
long
范围内。或者,您可以使用
INT\u MAX
而不是
ADDRESS\u SPACE
18446744073709551615
是-1的未签名版本
virtaddr
已签名,但显示为未签名;当然-1将小于任何有效的正数。

18446744073709551615
是-1的未签名版本
virtaddr
已签名,但显示为未签名;当然-1将小于任何有效的正数。

嗯。。。可能是因为
99999999999999999999999999999999999999999999999999999999
太大,无法放入
无符号长字符串中
?您的变量是有符号的,但您打印它们时没有符号。(atoi返回一个int.)(提示:将virtaddr比较为零)它与无符号说明符一起工作。对不起,这个愚蠢的问题,我没有注意到。嗯。。。可能是因为
99999999999999999999999999999999999999999999999999999999
太大,无法放入
无符号长字符串中
?您的变量是有符号的,但您打印它们时没有符号。(atoi返回一个int.)(提示:将virtaddr比较为零)它与无符号说明符一起工作。对不起,这个愚蠢的问题,我没有注意到。这个数字是用来测试溢出情况下会发生什么。但看起来只是缺少了未签名的位。现在,即使使用了愚蠢的大数字,它也能工作。这个数字被用来测试在溢出的情况下会发生什么。但看起来只是缺少了未签名的位。现在它甚至可以处理愚蠢的大数字。实际上,
atoi
在溢出时调用了未定义的行为。永远不要使用此函数。@R。。不是根据:“如果正确的值超出了可表示值的范围,则返回INT_MAX或INT_MIN。”该站点不是“参考”。它是网络上C和C++错误信息的1来源。不要用它。阅读标准。7.20.1.2:“atoi、atol和atol函数分别将nptr指向的字符串的初始部分转换为int、long int和long long int表示。除了错误行为外,它们等效于…atoi:(int)strtol(nptr,(char**)NULL,10)”唯一有问题的部分是它的含义“除了出错时的行为“并且没有指定任何错误行为……但是,在等价的情况下,调用
strtol
并强制转换到
int
不会在
int
溢出时给出
int\u MAX
int\u MIN
的值。相反,它将提供一个实现定义的
long
转换。POSIX版本的规范(应该与C对齐)更明确:“如果无法表示值,则行为未定义。”()实际上
atoi
在溢出时调用了未定义的行为。永远不要使用此函数。@R。。不是根据:“如果正确的值超出了可表示值的范围,则返回INT_MAX或INT_MIN。”该站点不是“参考”。它是网络上C和C++错误信息的1来源。不要用它。阅读标准。7.20.1.2:“atoi、atol和atol函数分别将nptr指向的字符串的初始部分转换为int、long int和long long int表示。除了错误行为外,它们等效于…atoi:(int)strtol(nptr,(char**)NULL,10)”唯一有问题的部分是它的含义“除了出错时的行为“并且没有指定任何错误行为……但是,在等价的情况下,调用
strtol
并强制转换到
int
不会在
int
溢出时给出
int\u MAX
int\u MIN
的值。相反,它将提供一个实现定义的
long
转换。POSIX版本的规范(应该与C对齐)更明确:“如果无法表示值,则行为未定义。”()