您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 市场营销 > 第二节数据存储与变量
2.1变量的声明与定义1.如程序清单2.1所示会不会报错?为什么?如果不会报错,又是输出什么结果?程序清单2.1变量的声明与定义#includestdio.hstaticinta;staticintb[];intmain(intargc,char*argv[]){printf(%d%d\n,a,b[0]);return0;}staticinta=8;staticintb[4];这个程序是不会报错的,并且连警告都不会出现。输出的结果是:80staticinta,这句程序是声明全局变量a;staticintb[],这句程序是声明全局数组变量b,并且是不完全声明,也就是可以省略数组下标。staticinta=8,这里才是定义全局变量a,staticintb[4],这里是定义全局变量b。2.2局部变量与全局变量的较量1.请问如程序清单2.2所示输出什么?程序清单2.2局部变量与全局变量#includestdio.hstaticinta=8;intmain(intargc,char*argv[]){inta=4;printf(%d\n,a);return0;}C语言规定,局部变量在自己的可见范围内会“挡住”同名的全局变量,让同名的全局变量临时不可见。即在局部变量的可见范围内不能访问同名的全局变量。因此本程序输出为:4。2.3char、int、float、double的数据存储1.请问如程序清单2.3所示,i和j输出什么?程序清单2.3数据存储floati=3;intj=*(int*)(&i);printf(i=%f\n,i);printf(j=%#x\n,j);i是毋庸置疑是:3.000000。但是j呢?3.000000?答案是否定的,j是输出:0x40400000。有人会问了,难道j是随机输出?瞎说,j输出0x40400000是有依据,是一个定值!由于i是float数据类型,而j是int数据类型。理论上说,j是取了i的地址然后再去地址,应该得到的就是i的值:3。但是问题的关键就是float数据类型的存储方式和int数据类型不一样,float是占用4个字节(32位),但是float存储是使用科学计数法存储,最高位是存储数符(负数的数符是0,正数的数符是1);接下来8位是存储阶码;剩下的23位是存储尾数。上面i=3.000000,那么3.000000(10进制)=11(2进制)=v:shapeid=_x0000_i1027style=WIDTH:40.5pt;HEIGHT:21.75ptequationxml='121.1脳21'type=#_x0000_t75(二进制)。数据在电脑中存储都是二进制,这个应该都没有疑问。那么这里的数符为:0,阶码为:E–127=1,那么阶码为:E=128即为:10000000(2进制),尾数为:10000000000000000000000。那么存储形式就是:01000000010000000000000000000000。这个数据转换成16进制就是0x40400000。char、int、float、double的存储方式如图2.1所示。提问:如果i=-3.5的话,请问j输出多少?i=-3.500000j=0xc0600000这个希望读者自行分析。再问:如果如程序清单2.4所示。程序清单2.4数据存储doublei=3;intj=*(int*)(&i);printf(i=%lf\n,i);printf(j=%#x\n,j);这样的话,j又输出多少呢?提示:double(8个字节(64位))的存储方式是:最高位存储数符,接下来11位存储阶码,剩下52位存储尾数。是不是得不到你想要的结果?double是8个字节,int是4个字节。一定别忘记了这个。用这个方法也同时可以验证大小端模式!2.4容易忽略char的范围1.如程序清单2.5所示,假设&b=0x12ff54,请问三个输出分别为多少?程序清单2.5char的范围unsignedintb=0x12ff60;printf(((int)(&b)+1)=%#x\n,((int)(&b)+1));printf(*((int*)((int)(&b)+1))=%#x\n,*((int*)((int)(&b)+1)));printf(*((char*)((int)(&b)+1))=%#x\n,*((char*)((int)(&b)+1)));很显然,&b是取无符号整型b变量的地址,那么(int)(&b)是强制转换为整型变量,那么加1即为0x12ff54+1=0x12ff55。所以((int)(&b)+1)是0x12ff55。由于((int)(&b)+1)是整型数据类型,通过(int*)((int)(&b)+1)转化为了整型指针类型,说明要占4个字节,即为:0x12ff55、0x12ff56、0x12ff57、0x12ff58,再去地址*((int*)((int)(&b)+1))得到存储在这4个字节中的数据。但是很遗憾,0x12ff58我们并不知道存储的是什么,所以我们只能写出0x**0012ff。**表示存储在0x12ff58中的数据。如图2.2所示。以此类推,*((char*)((int)(&b)+1))=0xff。如图2.3所示。但是,*((char*)((int)(&b)+1))输出的却是:0xffffffff!问题出现了,为什么*((char*)((int)(&b)+1))不是0xff,而是0xffffffff?char型数据应该占用1个字节,为什么会输出0xffffffff?使用%d输出,printf(*((char*)((int)(&b)+1))=%d\n,*((char*)((int)(&b)+1)));结果为-1???问题出在signedchar的范围是:-128~127,这样肯定无法储存0xff,出现溢出。所以将printf(*((char*)((int)(&b)+1))=%#x\n,*((char*)((int)(&b)+1)));改成printf(*((unsignedchar*)((int)(&b)+1))=%#x\n,*((unsignedchar*)((int)(&b)+1)));就可以输出0xff,因为unsignedchar的范围是:0~255(0xff)。图2.1数据存储方式图2.2指针加1取整型数据图2.3指针加1取字符型数据
本文标题:第二节数据存储与变量
链接地址:https://www.777doc.com/doc-2187882 .html