C';s格式说明符

C';s格式说明符,c,int,C,Int,我有C语言的代码- #include <stdio.h> void main(void) { int a=90; float b=4; printf("%f",90%4); } #包括 真空总管(真空) { INTA=90; 浮动b=4; printf(“%f”,90%4); } 它的输出为0.0000,我不明白为什么??? 我知道90%4返回2,指定的格式说明符是%f,表示double,但我期望的是- 它将给出一个错误,但它将0.0000显示为输出。 有

我有C语言的代码-

#include <stdio.h>
void main(void)
{
    int a=90;
    float b=4;
    printf("%f",90%4);
}
#包括
真空总管(真空)
{
INTA=90;
浮动b=4;
printf(“%f”,90%4);
}
它的输出为0.0000,我不明白为什么??? 我知道90%4返回2,指定的格式说明符是%f,表示double,但我期望的是- 它将给出一个错误,但它将0.0000显示为输出。
有人能解释一下原因吗?

简言之:检查格式说明符时没有错误。如果您的格式正在寻找一个double,那么您作为参数传递的任何内容(或者即使不传递任何内容)都将被解释为double。

90%4的类型将是
int

使用
%f
作为
int
的格式说明符的行为未定义


输出可以是2,也可以是0。编译器甚至可能吃掉你的猫。

这种差异的产生是因为编译器和库不就类型进行通信。发生的情况是,您的C编译器观察到printf是一个变量函数,它接受任意数量的参数,因此额外的参数会按其各自的类型传递。如果幸运的话,它还会解析格式字符串并警告您类型不匹配:

$ gcc -Wformat -o fmterr fmterr.c
fmterr.c: In function ‘main’:
fmterr.c:6:2: warning: format ‘%f’ expects argument of type ‘double’, 
but argument 2 has type ‘int’ [-Wformat=]
  printf("%f",90%4);
  ^

但这仍然只是一个警告;就编译器而言,您可能已经用具有不同行为的函数替换了printf。在运行时,浮点参数和整数参数甚至可能不会放在同一个位置,而且格式肯定也不相同,因此无法保证0.0的特定结果。真正发生的事情可能与平台ABI有关。通过将printf参数更改为类似于
(float)(90%4)
的值,可以获得指定的行为

%f
需要一个
double
,然后在
printf
中传递
int(90%4=2)
。因此,导致未定义的行为,并且可以给出任何输出

您需要显式地强制转换-

不要尝试此操作,因为编译器将生成错误(正如@chux Sir所指出的)-


printf
是一个可变函数。这些功能是模糊的,没有值得一提的类型安全性。这些函数所做的是隐式地将小整数类型提升为
int
类型,将
float
提升为
double
,但仅此而已。它不能做更微妙的事情,比如整数到浮点的转换

所以printf本身不能告诉您传递给它的是什么,它依赖于程序员指定正确的类型。整数文本,如
90
属于
int
类型。使用
%f
说明符,您告诉printf您传递了一个
double
,但实际上传递了一个
int
,因此您调用了未定义的行为。这意味着任何事情都可能发生:不正确的打印、正确的打印、程序崩溃等


显式强制转换
(双精度)(90%4)
将解决此问题。

默认情况下,
90%4
给出一个整数。 如果使用
%f
说明符打印整数,它将打印0

例如,
printf(“%f”,2)将打印0

你用float输入结果,你将得到2.00000

printf(“%f”,(float)(90%4))将打印2.00000


希望它能澄清。

为什么您认为它会抛出错误?另外,始终使用
int main()
返回0由于类型不匹配,格式说明符是%f,返回的值是int。如果它不会显示错误,那么为什么它不显示2.0000?这里无用的
a
b
有什么意义?你的意思是
printf(“%f”,a%b)?它甚至不会编译,因为
%
只能对整数类型进行操作
%f
在printf中查找
双精度
,而不是
浮点
。这并不能回答问题<代码>printf(“%f”,2)将调用未定义的行为,它可以打印任何内容。查看所有其他答案。我打赌它会打印0。你认为未定义的行为有多严重?你对我维护的完全符合标准的C编译器打赌多少?打印0?在你的机器上,使用你的编译器,它打印0。因为标准没有定义这种类型的参数不匹配会发生什么,所以不能保证另一个编译器会生成相同的结果。可能是这样,但你不能依赖于此。这两个版本是不等价的,因为第一个版本将对两个双精度执行模计算,如果适用,添加小数,但也可能会增加结果的浮点不精确性。而后一个版本将对整数执行计算。@Lundin
printf(“%f”,90%(双精度)4)
甚至不是合法的C代码。“二进制操作数无效%(有'int'和'double')”@chux我没有编译它。但结果会让人不高兴,我会解决的it@chux哦,对了,我忘了在%运算符的特定情况下,C标准强制使用int。您必须使用fmod()或类似的函数。
printf("%f",(double)(90%4));   
printf("%f",90%(double)4);