C 为什么此代码正在打印0?
实际上,C 为什么此代码正在打印0?,c,C,实际上,%d告诉printf在某个地方查找整数参数。但是您传递了一个float参数,该参数放在不同的位置。C标准没有指定执行此操作时会发生什么。在这种情况下,可能是在printf查找整数参数的地方有一个零,所以它打印了“0”。在其他情况下,可能会发生一些不同的情况。试试看 void main() { clrscr(); float f = 3.3; /* In printf() I intentionaly put %d format specifier to see
%d
告诉printf
在某个地方查找整数参数。但是您传递了一个float
参数,该参数放在不同的位置。C标准没有指定执行此操作时会发生什么。在这种情况下,可能是在printf
查找整数参数的地方有一个零,所以它打印了“0”。在其他情况下,可能会发生一些不同的情况。试试看
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();
}
这就是打印浮点数的方式。
也许您只想打印x位f,例如:
这将打印点后有3位数字的浮点数。
请仔细阅读此列表:
%c字符
%d或%i-有符号十进制整数
%e-使用e字符的科学记数法(尾数/指数)
%E-使用E字符的科学记数法(尾数/指数)
%f-十进制浮点
%g-使用%e或%f中的较短者
%G-使用%E或%f中的较短者
%o-符号八进制
%s字符串
%u-无符号十进制整数
%x-无符号十六进制整数
%X-无符号十六进制整数(大写字母)
%p指针地址
%n-未打印任何内容代码正在打印0,因为您使用的是格式标记%d,它表示有符号十进制整数() 你能试试吗
printf("... %.3f" f);
使用无效的格式说明符来
printf
调用。本规范第7.21.6.1p9节对此进行了规定:
如果转换规范无效,则行为无效
未定义。282)如果任何参数不是
对应的转换规范,行为未定义
这意味着您无法可靠地预测程序的输出。例如,我的系统上的相同代码将-1554224520打印为值
至于最可能发生的情况,
%d
格式说明符正在寻找一个int
作为参数。假设在堆栈上传递了int
,并且int
的长度为4个字节,那么printf
函数将查看堆栈上下一个4个字节的给定值。许多实现不在堆栈上传递浮点值,而是在寄存器中传递,因此它会看到出现的任何垃圾值。即使float
在堆栈上传递,float
和int
也有非常不同的表示形式,因此将float
的字节打印为int
很可能不会给出相同的值。让我们看一个不同的示例。假设我写信
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();
}
你可能认为同样的事情也会发生。您传递了一个float
,但是%d
需要一个int
,所以会发生自动转换,对吗
错。让我再说一遍:错了
也许令人惊讶的事实是,printf
是不同的<代码>打印F是特殊的。编译器不一定知道传递给printf
的参数的正确类型,因为它取决于格式字符串中隐藏的%
-说明符的详细信息。因此,没有自动转换为正确的类型。您的工作是确保实际传递的参数类型完全适合格式说明符。如果它们不匹配,编译器不会自动执行相应的转换。如果它们不匹配,结果就是你得到了疯狂、错误的结果
(用于printf
的原型函数声明是什么样子的?它实际上是这样的:extern int printf(const char*,…);
。这三个点…
表示可变长度的参数列表或“varargs”,它们告诉编译器它不知道还有多少个参数,或者它们的类型应该是什么。因此编译器执行一些基本的转换——例如将类型char
和short int int
向上转换为int
,并将float
向上转换为double
,然后保持不变。)
我说“编译器不一定知道传递给
printf
的参数的正确类型应该是什么”,但是现在,好的编译器会付出更多的努力,如果可以的话,无论如何都会尝试找出它。它们仍然不会执行自动转换(根据语言规则,它们实际上是不允许的),但它们至少可以警告您。例如,我在两个不同的编译器下尝试了您的代码。两人都说了类似于警告的话:format指定类型为“int”,但参数的类型为“float”。如果你的编译器不给你这样的警告,我鼓励你找出这些警告是否可以启用,或者考虑切换到一个更好的编译器。因为<代码> %f>代码>是打印代码>格式化< /代码>的格式说明符。请注意,你的学校正在教你一个C的非标准味道,C已经过时了25年,因为它假定使用完全过时的Turbo C编译器来编译完全过时的MS DOS。考虑一个诉讼。<代码> %D/<代码>格式说明符与<代码> f>代码>的类型不匹配,因此程序的行为是未定义的。作为可能的DUP,编译器允许对<代码> PrtTf< /C> >的正确类型进行自动转换。根据C 2018 7.1.4,C标准没有定义这种情况下的行为,因此实现可以随心所欲。@Neelam很高兴我能提供帮助。如果你觉得它有用的话,请随意使用。
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();
}
#include <string.h>
char buf[10];
float f = 3.3;
memset(buf, 'x', f);
printf("value of variable f is: %d", f);