为什么printf()用%f输出double型,而scanf却用%lf呢?
转:https://blog.csdn.net/bat67/article/details/52056057
- 示例:double x;scanf(“%f”,&x);输入“123.4”,输出x的值结果为0,没有接收输入的数据,再输入别的数据,结果都为0。这是因为用户定义x为双精度型数据,而用“%f”格式输入数据,仍不能接收,应该使用“%lf”或“%le”,即scanf(“%lf”,&x);此时输入“123.4”即可接收。因此长整型数据和双精度型数据必须使用附加格式说明字符l,短整型数据必须使用附加格式说明字符h。
为什么printf()用%f输出double型,而scanf却用%lf呢?
答:printf的%f说明符的确既可以输出float型又可以输出double型。 根据"默认参数提升"规则(在printf这样的函数的可变参数列表中 ,不论作用域内有没有原型,都适用这一规则)float型会被提升为double型。因此printf()只会看到双精度数。
对于scanf,情况就完全不同了,它接受指针,这里没有类似的类型提升。(通过指针)向float存储和向double存储大不一样,因此,scanf区别%f和%lf。
下表列出了printf和scanf对于各种格式说明符可以接受的参数类型。
格式 |
printf |
scanf |
%c |
int |
char * |
%d, %i |
int |
int * |
%o, %u, %x |
unsigned int |
unsigned int * |
(续)
格式 |
printf |
scanf |
%ld, %li |
long int |
long int * |
%lo, %lu, %lx |
unsinged long int |
unsigned long int * |
%hd, %hi |
int |
short int * |
%ho, %hu, %hx |
unsigned int |
unsigned short int * |
%e, %f, %g |
double |
float * |
%le, %lf, %lg |
n/a |
double * |
%s |
char * |
char * |
%[...] |
n/a |
char * |
%p |
void |
void ** |
%n |
int * |
int * |
%% |
none |
none |
(严格地讲,%lf在printf下是未定义的,但是很多系统可能会接受它。要确保可移植性,就要坚持使用%f。)
PS: scanf 函数中只有“域宽”附加格式说明字符(指定输入数据所占列数),而没有“小数位数”附加格式说明字符(只有printf函数有)。
double a; //float a; // run time check failure #2 - Stack around the variable 'a' was corrupted // 运行时检查失败#2-变量'a'周围的堆栈已损坏 // 错误在于:输入的%lf是8字节double双精度,然后给float类型a变量4个字节会发生溢出损坏 // 一般输入使用 %f -> float类型,%lf -> double类型 scanf("%lf", &a); //scanf("%f", &a); // 一般输出使用 %f -> float类型或者double类型都可以 // ,只是现代编译器都扩展了 %f和%lf的输出方式,但是一般使用%f就可以了 printf("%d,%f", sizeof(a),a);