首页 > 解决方案 > 这个值是多少?

问题描述

printf("%d", "10+10");

然后我也得到“17661648”和类似的东西

printf("%d", "Hello");

这个值是多少?"1,0,+,1,0" "H,e,l,l,o"十进制数作为ASCII码的总和?还是只是一个垃圾值?

标签: c

解决方案


根据 C11 标准n1570(参见其 §7.21.6.1),您有未定义的行为(UB),这也记录在此处printf(3)中。所以要非常 害怕,因为可能会发生任意坏事。因此,请养成阅读您正在使用的每个函数的文档的习惯。

如果您要求编译器反汇编程序的生成形式(例如,gcc -S -O -fverbose-asm如果您在 Linux/x86-64 上使用GCC,则通过编译)您会发现字符串文字的地址"10+10"被传递(在 64 位上),然后截断(在 内部printf,因为%d)到int. 因此 17661648 可能对应于该地址的最低 32 位。

细节当然是特定于实现的(并且可能会因ASLR而从一次运行到下一次运行有所不同,取决于编译器和ABI以及目标系统)。要真正理解和解释行为需要深入了解许多细节(您的特定计算机、特定编译器优化标志、特定操作系统、编译器生成的汇编器和机器代码、特定C 标准库等......)和您不想这样做(因为可能需要数年时间)。

你应该花几个小时来阅读更多关于 UB的信息。在用 C 编程时,理解它是一个基本概念,你应该避免它。

任何好的编译器都会警告你,然后你应该改进你的代码以不收到警告。如果使用 GCC,请务必编译gcc -Wall -Wextra -g以获取所有警告和调试信息。然后使用gdb调试器了解程序在系统上的实际行为。在所有情况下,请务必配置您的 C 编译器以启用所有警告和调试信息,并学习使用您的调试器。阅读如何调试小程序


推荐阅读