c - 这个值是多少?
问题描述
printf("%d", "10+10");
然后我也得到“17661648”和类似的东西
printf("%d", "Hello");
这个值是多少?"1,0,+,1,0"
"H,e,l,l,o"
十进制数作为ASCII码的总和?还是只是一个垃圾值?
解决方案
根据 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 编译器以启用所有警告和调试信息,并学习使用您的调试器。阅读如何调试小程序。
推荐阅读
- flutter - Flutter中的Api自动完成搜索
- python - Amazon cdk and boto3 difference
- exponentiation - Forth 中的分数求幂
- python - 如何在python中的条件内执行脚本
- neo4j - 在neo4j中使用cypher命令创建两个节点之间通过另一个节点的路径?
- c# - C# 拆分列表
价值 - django - django rest-auth 登录令牌使用方法
- ios - 在 Switch 语句中根据模型数据返回单元格
- python - 使用 statsmodel (pandas/matplotlib) 在散点图上绘制 p 值
- ros - 如何完全擦除/删除 catkin 工作区?