Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.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 为什么此代码中每个printf的输出都不同?_C - Fatal编程技术网

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.3
printf
功能:

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