C 为什么此代码中每个printf的输出都不同?
可能重复:C 为什么此代码中每个printf的输出都不同?,c,C,可能重复: #包括 int main(int argc,const char*argv[]{ 浮球f1=125.2f; printf(“\n[%f][%d][%g]”,f1,f1,f1); printf(“\n[%f][%g][%d]”,f1,f1,f1); printf(“\n[%g][%f][%d]”,f1,f1,f1); printf(“\n[%g][%d][%f]”,f1,f1,f1); printf(“\n[%d][%g][%f]”,f1,f1,f1); printf(“\n[%d]
#包括
int main(int argc,const char*argv[]{
浮球f1=125.2f;
printf(“\n[%f][%d][%g]”,f1,f1,f1);
printf(“\n[%f][%g][%d]”,f1,f1,f1);
printf(“\n[%g][%f][%d]”,f1,f1,f1);
printf(“\n[%g][%d][%f]”,f1,f1,f1);
printf(“\n[%d][%g][%f]”,f1,f1,f1);
printf(“\n[%d][%f][%g]”,f1,f1,f1);
getchar();
}
我可以从每个printf看到不同的输出,尽管使用相同的格式标识符打印相同的变量 您的代码会导致未定义的行为。任何事情都有可能发生 根据规范第J.2节“未定义行为”: 调用其中一个格式化输入/输出函数时,没有足够的格式化参数,或者某个参数的类型不合适(7.19.6.1、7.19.6.2、7.24.2.1、7.24.2.2) 因此,您还可以查看参考部分以了解更多信息。在您的情况下,相关位是7.9.16.1
fprintf
函数,第9段:
如果转换规范无效,则行为未定义。如果任何参数不是相应转换规范的正确类型,则行为未定义
以及7.19.6.3printf
功能:
printf
函数相当于fprintf
,参数stdout
插入到printf
的参数之前
printf
不是类型安全的,因此使用不正确的格式描述符会导致未定义的行为
未定义的行为意味着任何可观察的行为都是可能的,因为代码不符合标准规定的规则。%d”
格式需要int
参数。传递float
参数(升级为double
)会导致未定义的行为
可能发生的情况是,printf
从堆栈中获取了错误的字节数,但是您最好花时间修复代码,而不是找出坏代码以特定方式错误行为的原因
并且
void main()
错误;使用intmain(void)
。如果某本教科书告诉您,void main()
是正确的,那么作者对该语言的了解还不够深入,无法就此进行写作。详细信息将根据机器和编译器的不同而有所不同,但假设浮点为4字节,双精度为8字节,整数为4字节
您在堆栈上放置了三个浮点数,它们被提升为8个字节,总共24个字节。然后,格式字符串从堆栈中提取不同数量的字节。所以
- %f、 %d,%g将提取8、4、8个字节
- %f、 %g,%d将提取8、8、4个字节
- %g、 %f,%d将提取8、8、4个字节
- %g、 %d,%f将提取8、4、8个字节
- %d、 %g,%f将提取4、8、8个字节
- %d、 %f,%g将提取4、8、8个字节
printf的vararg区域中的类型必须与转换运算符期望的类型匹配。此问题可以问多少次!?这些是格式字符串。您应该阅读
printf()
。首先,这不是C,因为main()不返回void,而是int。其次,clrsc()方法不是C标准的一部分。第三,这不是你正在处理的objective-c,而是纯c。第四,请在发帖之前处理好你的代码格式。@CarlNorum当人们开始编程时,会被问到很多次,而他们什么都不知道——包括如何做他们自己的基础研究(也包括知道他们可以/应该做他们自己的研究)。这是一个潜在的非常庞大的群体。不可观察的行为也是可能的。这完全取决于实现。例如,在Mac上尝试64位应用程序。注意我的第一句话:“详细信息将根据机器和编译器的不同而有所不同”。然后我为float、double和int声明了“假设”特定的大小。我的观点是假设大小是不够的。在Mac上(可能还有AMD/Linux 64位ABI的所有设备),浮点和整数变量都在独立的逻辑堆栈上。在这种情况下,谈论从单个堆栈中提取字节是毫无意义的。这是一个可能出错的示例,而不是如何正确处理的示例。因此,我关于为vararg匹配类型的最后声明仍然有效。但是你关于逻辑堆栈的观点是正确的。
#include<stdio.h>
int main(int argc, const char *argv[]){
float f1 = 125.2f;
printf("\n [%f] [%d] [%g]",f1,f1,f1);
printf("\n [%f] [%g] [%d]",f1,f1,f1);
printf("\n [%g] [%f] [%d]",f1,f1,f1);
printf("\n [%g] [%d] [%f]",f1,f1,f1);
printf("\n [%d] [%g] [%f]",f1,f1,f1);
printf("\n [%d] [%f] [%g]",f1,f1,f1);
getchar();
}