从上一个问题:
如果你试图传递
float给printf它,它会double在printf收到它之前被提升
printf()是一个可变函数吧?可变参数函数在传递之前是否会提升float参数double?
我是初学者编程学生,只是想了解这背后的原因.
当我使用这段代码时:
#include <stdio.h>
int main()
{
double pi = 3.1415926535897932;
printf("%lf",pi);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器发出此警告.ISO C90不支持'%lf'gnu_printf格式[-Wformat]
我在ubuntu终端使用gcc编译器(-o -Wall -ansi -pedantic-errors)
这背后的原因是什么?我搜索了网页,发现在C99中允许使用.为什么C90不允许在printf中使用%lf?我可以使用%.16lf或%.16f并且都以相同的精度打印,那么在C90中导致%lf坏的问题是什么?
在给定的程序中,为什么每个printfs 得到不同的结果?
#include <stdio.h>
int main()
{
float c = 4.4e10;
printf("%f\n", c);
printf("%f\n", 4.4e10);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它显示以下输出:
44000002048.000000
44000000000.000000
Run Code Online (Sandbox Code Playgroud) 你好,我在C#中有这个代码:
float n = 2.99499989f;
MessageBox.Show("n = " + n.ToString("f2", CultureInfo.InvariantCulture));
Run Code Online (Sandbox Code Playgroud)
而这个C++代码:
float n = 2.99499989f;
printf("n = %.2f", n);
Run Code Online (Sandbox Code Playgroud)
第一个输出3.00.
第二个输出2.99.
我不知道为什么会这样.
更新:
我也尝试了Objective-C NSLog,输出为2.99.
我需要快速修复它,所以我使用以下方法:
float n = 2.99499989f;
float round = (float)Math.Round(n, 2);
MessageBox.Show("round = " + round.ToString(CultureInfo.InvariantCulture));
Run Code Online (Sandbox Code Playgroud)
此代码显示2.99,但以双精度计算舍入.我找不到Math.RoundF.
当变量与union相关联时,编译器会通过考虑最大内存的大小来分配内存.因此,union的大小等于最大成员的大小.所以这意味着改变任何成员的值将改变其他成员的价值.但是当我执行以下代码时
output: 4 5 7.000000
union job
{
int a;
struct data
{
double b;
int x
}q;
} w;
w.q.b=7;
w.a=4;
w.q.x=5;
printf("%d %d %f",w.a,w.q.x,w.q.b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
问题是,首先我分配a的值然后修改qx的值,然后a的值将被qx覆盖但是在输出中它仍然显示a的原始值以及qx的原始值我不能了解它为什么会发生?
直到最近,我才想到:
printf("%f",x) 将尝试从堆栈中读取4字节的浮点值.
printf("%lf",x) 会尝试从堆栈中读取一个8字节的浮点值.
但是,下面的代码似乎产生了正确的输出:
float f = 1234.5;
double d = 12345678.9;
printf("Output = %u %u\n",sizeof(f),sizeof(d)); // Output = 4 8
printf("Output = %.1f %.1f\n",f,d); // Output = 1234.5 12345678.9
Run Code Online (Sandbox Code Playgroud)
我相信它证明printf("%f",x)从堆栈读取一个8字节的浮点值.
这是因为两个值都正确打印,但12345678.9太大而无法放入4字节变量.
现在我的问题是:当printf使用4字节float变量调用时,编译器如何知道double在将其推入堆栈并调用之前应将其转换为8字节值printf?
在调用带浮点参数的函数时,这是标准的一部分吗?
谢谢