Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C printf(“%d\n”,4294967296);犯了一些奇怪的错误_C_Visual Studio 2017 - Fatal编程技术网

C printf(“%d\n”,4294967296);犯了一些奇怪的错误

C printf(“%d\n”,4294967296);犯了一些奇怪的错误,c,visual-studio-2017,C,Visual Studio 2017,4294967296=2^32 我想用printf%u,%d打印4294967296,想看看会发生什么,但我得到了一些奇怪的结果 代码如下: printf("%d\n", 4294967296); printf("d = %u = %d = 0x%x \n", 4294967296, 4294967296, 4294967296);//this is strange printf("d = %u = %d = 0x%x \n", 4294967295 + 1, 4294967295 +

4294967296=2^32

我想用printf%u,%d打印4294967296,想看看会发生什么,但我得到了一些奇怪的结果

代码如下:

printf("%d\n", 4294967296);

printf("d = %u = %d = 0x%x  \n", 4294967296, 4294967296, 4294967296);//this is strange

printf("d = %u = %d = 0x%x  \n", 4294967295 + 1, 4294967295 + 1, 4294967295 + 1);
我的结果是

0

d = 0 = 1 = 0x0

d = 0 = 0 = 0x0

您可以在第二行中看到4294967296的二进制表达式是0x0,但当我打印4294967296使用%d时,它将显示1,我对此感到困惑。我希望1的输出为0。

如果支持,那么值4294967296是一个long-long,因为它不适合无符号int

格式%d是用于有符号整数的整数

值类型和格式说明符不匹配会导致未定义的行为


值4294967295不适合无符号整数,但添加1会使其溢出


32位无符号整数的范围为0到2到1(含2到1)。

如果支持,则值4294967296为长-长,因为它不适合无符号整数

格式%d是用于有符号整数的整数

值类型和格式说明符不匹配会导致未定义的行为


值4294967295不适合无符号整数,但添加1会使其溢出


32位无符号整数的范围为0到2-1(含0到2-1)。

无符号整数从不溢出:

C99,6.2.5p9涉及无符号操作数的计算永远无法执行 溢出,因为结果无法表示结果 无符号整数类型按大于一的数字的模减少 大于结果类型可以表示的最大值

但在C中,整数溢出是未定义的行为:

C99,6.5.5p5如果在测试过程中出现异常情况 表达式的求值,即,如果结果不是 数学定义的或不在可表示值范围内的 其类型、行为未定义

C99,3.4.3p3示例未定义行为的一个示例是 整数溢出的行为


我引用了一个问题的答案。

无符号整数从不溢出:

C99,6.2.5p9涉及无符号操作数的计算永远无法执行 溢出,因为结果无法表示结果 无符号整数类型按大于一的数字的模减少 大于结果类型可以表示的最大值

但在C中,整数溢出是未定义的行为:

C99,6.5.5p5如果在测试过程中出现异常情况 表达式的求值,即,如果结果不是 数学定义的或不在可表示值范围内的 其类型、行为未定义

C99,3.4.3p3示例未定义行为的一个示例是 整数溢出的行为

我引用了一篇文章中的这些话来回答我之前提出的一个问题

printf“%d\n”,4294967296;犯了一些奇怪的错误

是的,这是一个非常有趣的问题

这归结为4294967295和4294967296的类型是什么

是由以下配件确定的类型: int,long,无符号长C89 整型,长型,长型C99 int,long,无符号long,long-long,无符号long-long

注意:4294967295+1在任何情况下都不是有符号整数溢出

这是C89、C99或更高版本有所不同的地方之一,也是VS2017独树一帜的地方

对于兼容的C89,32位world 4294967295是无符号长十进制常量,加1表示无符号长0。C89 6.1.3.2

作为。。。参数、整型0和无符号0都适用于%u和%d,0的值都在范围内。然而,这是一个无符号的长0,因此是技术上未定义的行为。在32位系统上,此UB通常是良性的,其结果与打印无符号0相同

4294967296只是一个超出范围的常数

对于C99或更高版本-当然不是OP的情况,4294967295是一个长十进制常量1,加1就是长4294967296。4294967296是另一个长十进制常数

传递long long以匹配%d或%u是未定义的行为。在这两种情况下,相同的输出0、1、0将是预期的UB

然而OP使用的是VS2017,根据C89规则,4294967295是无符号长十进制常量,加1是无符号长0。使用%u打印,%d从技术上讲是UB,但如果32位无符号具有与32位无符号长相同的特性,则0,0,0输出是合理的

4294967296显然是一些64位类型,例如long long2,而每C99规则是UB。0,1,0的产出是合理的,但没有弹性

OP的结果可能因具体情况而异

1或64位长

2,我不能找到一个决定性的在线VS2017 REF,它是一个C十进制常数的类型,而不是C++的值大于4294967295。 printf“%d\n”,4294967296;犯了一些奇怪的错误

是的,这是一个非常有趣的问题

这归结为什么是t 4294967295和4294967296的类型

是由以下配件确定的类型: int,long,无符号长C89 整型,长型,长型C99 int,long,无符号long,long-long,无符号long-long

注意:4294967295+1在任何情况下都不是有符号整数溢出

这是C89、C99或更高版本有所不同的地方之一,也是VS2017独树一帜的地方

对于兼容的C89,32位world 4294967295是无符号长十进制常量,加1表示无符号长0。C89 6.1.3.2

作为。。。参数、整型0和无符号0都适用于%u和%d,0的值都在范围内。然而,这是一个无符号的长0,因此是技术上未定义的行为。在32位系统上,此UB通常是良性的,其结果与打印无符号0相同

4294967296只是一个超出范围的常数

对于C99或更高版本-当然不是OP的情况,4294967295是一个长十进制常量1,加1就是长4294967296。4294967296是另一个长十进制常数

传递long long以匹配%d或%u是未定义的行为。在这两种情况下,相同的输出0、1、0将是预期的UB

然而OP使用的是VS2017,根据C89规则,4294967295是无符号长十进制常量,加1是无符号长0。使用%u打印,%d从技术上讲是UB,但如果32位无符号具有与32位无符号长相同的特性,则0,0,0输出是合理的

4294967296显然是一些64位类型,例如long long2,而每C99规则是UB。0,1,0的产出是合理的,但没有弹性

OP的结果可能因具体情况而异

1或64位长


2,我不能找到一个决定性的在线VS2017 REF,它是一个C十进制常数的类型,而不是C++的值大于4294967295。调用未定义的行为。%d和%u格式化参数要求将32位参数传递给printf。但代码实际上传递了64位参数,十六进制格式为0x0000000100000000。因此%d使其读取该值的较低32位,即0。下一个%u使其读取该值的上32位,即1。顺便说一句,由于4294967295+1生成一个32位值,因此第二个语句中不会出现Little-endian机器。如果您的编译器没有对此发出警告,请确保更新或提高警告级别。@HansPassant 4294967295+1生成一个32位值->取决于C89与C99。对于现代C,4294967295也是一个长字符,4294967295+1是一个64位的值;调用未定义的行为。%d和%u格式化参数要求将32位参数传递给printf。但代码实际上传递了64位参数,十六进制格式为0x0000000100000000。因此%d使其读取该值的较低32位,即0。下一个%u使其读取该值的上32位,即1。顺便说一句,由于4294967295+1生成一个32位值,因此第二个语句中不会出现Little-endian机器。如果您的编译器没有对此发出警告,请确保更新或提高警告级别。@HansPassant 4294967295+1生成一个32位值->取决于C89与C99。对于现代C,4294967295也是一个长的,4294967295+1是一个64位的值。值4294967295确实适合于无符号整数,但4294967295自C99以来仍然是一个长的十进制常数。添加1使其溢出->否。该总和为长4294967296。对于C89,您的答案是有意义的,其中4294967295是无符号长,加1定义良好。值4294967295确实适合无符号整数,但4294967295仍然是自C99以来的长十进制常量。添加1使其溢出->否。该总和为长4294967296。对于C89,您的答案是有意义的,其中4294967295是无符号长字符,加1定义良好。这里没有带符号整数溢出。这里没有带符号整数溢出。