2
int a=5;
float b=3.5;
printf("%d",b);
printf("\n%f",a);

谁能告诉我为什么这段代码显示出意外的输出(垃圾\n3.5)

4

4 回答 4

4

您正在float%d格式字符串传递 a ,但printf需要一个int.

printf是一个可变参数列表函数:printf(const char *format_string,...);

这意味着格式字符串之后的其余参数可以是任何类型和数字,编译器不知道它们应该是什么。由程序员提供printf预期类型的​​参数。printf期望的内容由格式字符串决定。当您%d在格式字符串中给出 a 时,printf 函数将期望下一个参数是一个int. 由于您正在通过 a float,因此可能会发生一些奇怪的事情。例如,构成浮点数的那些字节可能会被视为一个int,这不会给您任何有意义的值。

实际上它比这更复杂一些。关于如何将参数传递给可变参数函数有一些特殊规则。规则之一是值作为sfloat传递。double这意味着您的float值首先转换为 a double,然后再传递给printf. 在您的平台上, a 很可能double是 8 个字节,而 anint只有 4 个。因此,该printf函数可以将double值的前四个字节视为int.

更糟糕的是,在下一行,an在预期int的地方被传递。double这意味着该printf函数可以将您的前四个字节int视为 的一部分double,然后再读取四个甚至不属于您的参数的字节。

实际发生的细节是特定于平台的。该语言只是声明您不应该传递错误类型的参数,并且不保证如果您这样做会发生。

于 2013-07-27T13:13:39.453 回答
4

根据您对 and 的声明,格式化字符串不正确的a错误b

printf("%d",b); <-- "b is float"     Wrong!
printf("\n%f",a); <-- "a is an int"   Wrong! -- Undefined behavior 

应该:

printf("%f",b);
printf("\n%d",a);

问:- 为什么你得到那个输出?

这是由于您的代码的未定义行为:

来自国际标准 ©ISO/IEC ISO/IEC 9899:201x

7.16.1 变量参数列表访问宏

(第 270 页)

7.16.1.1va_arg

[...]如果没有实际的下一个参数,或者类型与实际的下一个参数的类型不兼容(根据默认参数提升),则behavior is undefined,除了以下情况:
- 一种类型是a signed integer type,另一个类型是对应的unsigned integer 类型,值在两种类型中都是可表示的;
— 一种类型是指向的指针,void另一种是指向字符类型的指针

于 2013-07-27T13:14:41.953 回答
1
int main()
{

int a=5;
float b=3.5;
printf("%f",b); //Use %f
printf("\n%d",a); // Use %d

}

参考:printf

在大多数情况下,错误的格式说明符会printf导致未定义的行为。

然而,sinceprintf是一个可变参数函数,可变参数函数的参数经过默认参数转换。就像,一个 char 被转换为一个 int。

于 2013-07-27T13:15:27.283 回答
1

因为a变量是 int 类型,而您正在为 float 类型指定格式字符串,反之亦然b

笔记 :

%d用于整数类型

%f用于浮点

你应该使用:

int a=5;
float b=3.5;
printf("%f",b);
printf("\n%d",a);
于 2013-07-27T13:14:02.773 回答