C printf(“%d\n”,4294967296);犯了一些奇怪的错误
4294967296=2^32 我想用printf%u,%d打印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 +
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定义良好。这里没有带符号整数溢出。这里没有带符号整数溢出。