Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么此代码正在打印0?_C - Fatal编程技术网

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);