C 为什么不是';t%d能否在printf()中将浮点值自动转换为int?

C 为什么不是';t%d能否在printf()中将浮点值自动转换为int?,c,printf,C,Printf,我正在阅读《用C开始为傻瓜编程》一书。我遇到了一段我不懂的代码 #include <stdio.h> int main(void) { printf("The total is %d\n", 16.0 + 17); } 我认为首先16.0+17将自动键入cast to16.0+17.0=33.0,然后在打印其值时截断分数,最终输出为: The total is 33 你能解释一下为什么输出结果是0:C(也是C++)有未定义行为(UB)的概念。根据语言规则,有些事情是不

我正在阅读《用C开始为傻瓜编程》一书。我遇到了一段我不懂的代码

#include <stdio.h>

int main(void) 
{
    printf("The total is %d\n", 16.0 + 17);
}
我认为首先
16.0+17
将自动键入cast to
16.0+17.0=33.0
,然后在打印其值时截断分数,最终输出为:

The total is 33
你能解释一下为什么输出结果是
0

C(也是C++)有未定义行为(UB)的概念。根据语言规则,有些事情是不允许你做的。如果你违反了这些规则,那么你就不能期待任何合理的结果。
%d
需要
int
,如果您将
浮点值传递给它(或者说
double
),您将进入未定义行为的区域。 熟悉

最后,您需要熟悉所有导致UB的规则(标准中有100多种导致UB的因素);但既然你们现在正在学习C语言,你们不需要了解所有的语言,只要知道UB这样的东西是存在的

C(也是C++)有未定义行为(UB)的概念。根据语言规则,有些事情是不允许你做的。如果你违反了这些规则,那么你就不能期待任何合理的结果。
%d
需要
int
,如果您将
浮点值传递给它(或者说
double
),您将进入未定义行为的区域。 熟悉


最后,您需要熟悉所有导致UB的规则(标准中有100多种导致UB的因素);但既然你们现在正在学习C语言,你们不需要了解所有的语言,只要知道UB这样的东西是存在的

printf的声明如下所示:

int printf(const char *format, ...);
它采用可变长度参数,其中第一个
format
是必需的。但是它不能预先知道后面参数的类型,也就是在编译时。因此,为了确定后面参数的类型,即要知道它必须从内存中读取多少字节,如何解释这些字节等,这完全取决于格式字符串中的格式说明符


这就是格式说明符和实际类型必须匹配的原因。否则它将是未定义的行为,在这种情况下可能会发生任何事情。

printf的声明如下:

int printf(const char *format, ...);
它采用可变长度参数,其中第一个
format
是必需的。但是它不能预先知道后面参数的类型,也就是在编译时。因此,为了确定后面参数的类型,即要知道它必须从内存中读取多少字节,如何解释这些字节等,这完全取决于格式字符串中的格式说明符


这就是格式说明符和实际类型必须匹配的原因。否则它将是未定义的行为,在这种情况下任何事情都可能发生。

@JayPatel是的,它可能发生。@JayPatel它也是UB,以同样的方式。这就是重点,你需要熟悉和学习这些规则,没有其他办法。有时候,它们可能看起来不合乎逻辑,但“我个人认为,UB对于C和C++来说是一个缺点,因为你需要记住很多规则,编译器不能总是检测到违反。有明显的原因有UB,但是从安全的角度来看,它们使得C和C++编程变得复杂。”你是认真的吗?@GiorgiMoniava“下次你可能还想直接提出你的反驳意见”这里没有评论,我只是想问你是否真的是认真的,如果你想争论,请到C室来。博客文章和你所说的以及你链接的博客都是基于主要观点的,不应该写在答案上。@GiorgiMoniava“博客文章已经足够清楚了”所以你不是在争论,你只是假设博客是对的,不想讨论它,所以“下次你可能还想直接提出你的反驳”事实上你不在乎。“语言规则越多,使用起来就越麻烦,如果我违反了某个SO政策”这不是一项政策,但不要惊讶,像我这样的人会对此争论,这就是为什么SO建议避免它。若要和博客文章争论,只需阅读评论。@JayPatel是的,它可以。@JayPatel它也是UB的。这就是重点,你需要熟悉和学习这些规则,没有其他办法。有时候,它们可能看起来不合乎逻辑,但“我个人认为,UB对于C和C++来说是一个缺点,因为你需要记住很多规则,编译器不能总是检测到违反。有明显的原因有UB,但是从安全的角度来看,它们使得C和C++编程变得复杂。”你是认真的吗?@GiorgiMoniava“下次你可能还想直接提出你的反驳意见”这里没有评论,我只是想问你是否真的是认真的,如果你想争论,请到C室来。博客文章和你所说的以及你链接的博客都是基于主要观点的,不应该写在答案上。@GiorgiMoniava“博客文章已经足够清楚了”所以你不是在争论,你只是假设博客是对的,不想讨论它,所以“下次你可能还想直接提出你的反驳”事实上你不在乎。“语言规则越多,使用起来就越麻烦,如果我违反了某个SO政策”这不是一项政策,但不要惊讶,像我这样的人会对此争论,这就是为什么SO建议避免它。要与这篇博文争论,请阅读评论。如果你看到
printf
的签名,编译器怎么知道可能需要进行转换?请注意符号
不是百分比
%
符号。它是C/0而不是0/0。您应该在编译器中启用所有警告。使用
gcc-Wall-Wextra-g
时,您将收到警告(b