题目描述
对于如下的代码:
#include <stdio.h>
int main()
{
float a[3]= {1143139122437582505939828736.0,76482007234779498639230238720.0,9.222452464e-39};
printf("%d\n", sizeof(float));
printf("%s\n",a);
return 0;
}
运行并分析这个程序,解释为什么会输出结果。 并编写代码,输入为一个长度小于 12 的字符串,输出其对应的浮点数组
运行结果
4
Hello world
分析
- 首先对字符串Hello World进行分析
该字符串中含有的字符为:H、e、l、l、o、空格、w、o、r、l、d、'\n',共12个字符
这些字符,在内存中是按照ASCII码保存的,对应的ASCII码分别是: 72,101,108,108,111,32,119,111,114,108,100,0
ASCII码对应的16进制数值,分别是: 0x48,0x65,0x6C,0x6C,0x6F,0x20,0x77,0x6F,0x72,0x6C,0x64,0x00
- 补充浮点数在计算机中的表示
将浮点数转换成对应的二进制数之后再将二进制数转换为规格化数
(图源网络:http://blog.scdn.net/CSDN1829,侵删)
1.这里的 s 为 0 则表示正数,为 1 则表示负数(s 相当于符号位)
2.E 为阶码,反映了小数点在数据中的位置
3.指数 e 是由 E 转换为来 公式为e = E + bias(bias=2^(8-1)-1)
4.f 位数不够向右补 0
由 printf("%d\n", sizeof(float)); 可知 float的大小是4字节,则a[3]的大小为12字节,每个浮点数的大小为4字节
因为Windows系统是小端表示法,所以高地址放数据的高位部分,低地址放数据的低位部分
- 按照内存地址从小到大显示
其中第一个数字1143139122437582505939828736.0, 它在内存中的数据是:0x48 0x65 0x6C 0x6C
第二个数字76482007234779498639230238720.0 ,它在内存中的数据是:0x6F 0x20 0x77 0x6F
第三个数字9.222452464e-39,它在内存中的数据是:0x72 0x6C 0x64 0x00
如果想打印出Hello world,就必须在内存中有一段连续的内存单元 ;数组a[3]的三个数字的内存单元是连续的,故将以数组a为索引的之后12个字节单元中表示的数据输出为字符串
以上就是一个浮点数组能够字符串的原因;
编写代码,输入为一个长度小于 12 的字符串,输出其对应的浮点数组
- 补充有关指针的一些知识点
- 指针指向的是一个数据,而它本身存储的是它所指向的数据在内存中的地址
- 假设有一个数组a[10],和一个指向整型数据的指针int *p,那么p=&a指的是p等于数组a的首地址,*p就是从数组首地址开始的四个字节表示的整型数据
-
(&a)+1相当于把a看成一个整体,再加一,即数组a的首地址+数组a的长度+1;&(a+1)是数组a的首地址加1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char str[20]={"Hello world"};
printf("%d\n",&str);
float *xp,*yp,*zp;
float a[3];
xp=str;yp=(str+4);zp=(str+8);//以str首地址+0,+4,+8得到的地址
a[0]=*xp;
a[1]=*yp;
a[2]=*zp;
printf("%f\n",a[0]);
printf("%f\n",a[1]);
printf("%f\n",a[2]);
return 0;
}
运行结果
最后一个数输出为0.000000可能是因为float的精度问题,用gdb调试观察的时候a[2]的输出是正确的
以上。