void main()
{
clrscr();
float f = 3.3;
/* In printf() I intentionaly put %d format specifier to see
what type of output I may get */
printf("value of variable a is: %d", f);
getch();
}
答案 0 :(得分:7)
实际上,%d
告诉printf
在某个位置查找整数参数。但是您传递了一个float
参数,该参数放在另一个位置。 C标准未指定执行此操作时将发生的情况。在这种情况下,printf
查找整数参数的位置可能为零,因此它显示为“ 0”。在其他情况下,可能会发生一些不同的事情。
答案 1 :(得分:2)
对printf
使用无效的格式说明符将调用undefined behavior。 C standard的第7.21.6.1p9节对此进行了指定:
如果转换规范无效,则行为为 282)如果任何参数不是正确的类型 相应的转换规范,其行为是不确定的。
这意味着您无法可靠地预测程序的输出。例如,我系统上的相同代码将-1554224520打印为该值。
关于最有可能发生的事情,%d
格式说明符正在寻找int
作为参数。假设在堆栈上传递了int
,并且int
的长度为4个字节,则printf
函数将在堆栈的后4个字节中查找给定的值。许多实现都没有在堆栈上传递浮点值,而是在寄存器中传递浮点值,因此它可以看到任何垃圾值。即使在堆栈上传递了float
,float
和int
的表示形式也非常不同,因此将float
的字节打印为int
可能不会给您相同的价值。
答案 2 :(得分:0)
让我们看一下另一个例子。假设我写
#include <string.h>
char buf[10];
float f = 3.3;
memset(buf, 'x', f);
memset
的第三个参数应该是整数(实际上是类型为size_t
的值),它告诉memset
but
的多少个字符要设置为{{ 1}}。但是我改为传递了一个'x'
值。怎么了?好的,编译器知道第三个参数应该是整数,因此它会自动执行适当的转换,并且代码最终会设置{{1的前三个(三点零)字符}}到float
。
(重要的是,编译器知道buf
的第三个参数应该是整数的方式基于'x'
的原型函数声明标头memset
的内容。)
现在,当您打电话
memset
您可能会认为同一件事也会发生。您通过了<string.h>
,但是printf("value of variable f is: %d", f);
期望有float
,所以会发生自动转换,对吧?
错误。让我再说一遍:错误。
也许令人惊讶的事实是%d
是不同的。 int
很特殊。编译器不一定知道传递给printf
的参数的正确类型,因为它取决于掩埋在格式字符串中的printf
指定符的详细信息。因此,不会自动转换为正确的类型。确保您实际传递的参数类型完全适合格式说明符,这是您的工作。如果它们不匹配,则编译器会 not 自动执行相应的转换。如果它们不匹配,那将导致您发疯,错误的结果。
(printf
的原型函数声明是什么样的?从字面上看起来是这样的:%
。这三个点printf
表示一个可变长度参数列表< / em>或“ varargs”,它们告诉编译器它不知道还有多少个参数,或者它们的类型应该是什么。因此,编译器执行一些基本的转换-例如上转换类型{{1 }}和extern int printf(const char *, ...);
到...
,以及char
到short int
,然后将其保留。)
我说过:“编译器不一定知道传递给int
的参数的正确类型是什么”,但是如今,好的编译器会付出更多努力并尝试找出答案,如果可以的话。他们仍然不会执行自动转换(根据语言规则,他们实际上是不允许这样做的),但是它们至少可以警告您。例如,我在两种不同的编译器下尝试过您的代码。双方都说了float
。如果您的编译器没有给您这样的警告,建议您查明是否可以启用这些警告,或者考虑切换到更好的编译器。
答案 3 :(得分:-4)
尝试
printf("... %f",f);
这就是您打印浮动数字的方式。 也许您只想打印 f 的x位数字,例如:
printf("... %.3f" f);
这将在点后用3位数字打印您的浮点数。 请仔细阅读以下列表:
%c-字符
%d或%i-有符号十进制整数
%e-使用e字符的科学计数法(尾数/指数)
%E-使用E字符的科学计数法(尾数/指数)
%f-十进制浮点数
%g-使用%e或%f的较短者
%G-使用%E或%f中的较短者
%o-八进制签名
%s-字符串
%u-无符号十进制整数
%x-无符号十六进制整数
%X-无符号十六进制整数(大写字母)
%p-指针地址
%n-什么都没打印
答案 4 :(得分:-4)
代码正在打印0,因为您使用的是格式标记%d,它表示带符号的十进制整数(http://devdocs.io)。
请您尝试
void main() {
clrscr();
float f=3.3;
/* In printf() I intentionaly put %d format specifier to see what type of output I may get */
printf("value of variable a is: %f",f);
getch();
}