看到结果,会感觉非常奇怪。1处怎么会输出0呢?2又为何会显示这么大的一个数呢? 解释: 下面是转自网上的一篇博客的解释 1,之所以没输出5,这是C语言设计的原因。 具体来说: printf函数不会进行任何类型转换,它只是从内存中读出你所提供的元素的值(按照%d,%f等控制字符提示的格式)。C语言设计中,int类型一般是32bit或者16bit,而float一般是64bit,并且有可能使用科学计数保存。这点就和huhugo88所说一样,5在内存中为00000000,00000101。而且5一般都在静态区,程序的静态存储区默认是0,那么当用%f来读时,就会读64bit,也就是会读之前的很多位0,最后按照(有效数字)×(基数2)pow(指数)的方式来取数,自然结果是0 之所以Vc中不允许这种情况,而有些编译器就允许这么输出就是编译器设置的问题。按理说,这样访问内存是属于越界访问,应该禁止。不过只是读,伤害性不大而已。 对于单精度浮点数(32bit),不少c语言编译系统以24位表示小数部分(包括1bit符号位),以8位表示指数部分。 ==========================printf("%d\n",5.01); 为什么输出一个大数?在讲这个题目之前,预备知识,讲一下,printf函数,输入参数是读入缓冲区保存,再按照%?的格式从缓冲区中读出数据,并据此格式解释数据。 有了这个知识之后,在讲程序员面试宝典上看到一个题:
#include "stdio.h" 5.01是double类型,内存中占8个字节,保存在缓冲区。而%d为整型,占4个字节,printf从缓冲区中读入4字节,先读到低32位的数据。也就是说printf输出的应该是5.01以double类型保存数剧的低32位。为了检验此结果是否正确,对比5.01在内存中的表示与输出。
#include "stdio.h" 事情看似也就完成了。 我又想,如果输入是浮点类型的5.01f,又会发生什么呢?
#include "stdio.h" 然后看到一个说法,是printf会把%f按double类型输出,也就是说会把参数float型的转成double型在输出。 但现在并不是%f,当然用%f显示的是正确的结果。于是我猜测,printf是将所在float型读入的数据都自动的转化为double型了,然后%f就按double处理,而我们这是%d,所以显示的为float转化为double型后的低4字节。 验证此想法:
#include "stdio.h" 5.01d的默认的表示为:0x40140a3d70a3d70a,在上面已经说明了
#include "stdio.h" 接着就是看这两个值是否都是为5.01了: view plaincopy to clipboardprint? #include "stdio.h" 总结:printf将输的浮点型参数全都自动转化为双精度型,且与默认的双精度的表示方法是不同的。最重要一点,printf不安全,类型不安全,要是类型不对了,也许我们就挂了^_^
======================================================================================================================= 通过以上解释,我们大致明白: 1. printf输出float型时,会自动转化成double型; 2. 由于存储时,都是先低位,再高位,同时经过转化成double,前面会取很多0(越界访问); 3. 5.01,打印时按照int来取,只取前四个字节。 http://blog.csdn.net/yahohi/article/details/7701434 |
|
来自: taohongyong > 《专业》