现在的位置: 首页 > 综合 > 正文

【原创】C++数据类型(一)

2012年11月24日 ⁄ 综合 ⁄ 共 1978字 ⁄ 字号 评论关闭

今天终于开始拜读被称为C++圣典的《C++ Primer》,讲得挺细挺全的,由于在大学时没有把C++基础打牢,刚出来工作就使用C++进行开发,所以觉得蛮苦的,别人比自己先走一步,自己只能通过挤时间恶补一下。

言归正传。直接入题。

c++的内置类型int、char、float等与其在计算机的存储器中的表示方式紧相关。计算机以位序列存储数据,每一位存储0或者1.在位这一级上看,存储器没有结构和意义。现在大部分的计算机都使用特定位数的块来处理存储,块的位数一般是2的幂,所以可以一次处理8位、16位或者32位。

这里还得先说说无符号类型和有符号类型,无符号类型表示是正数或者0,而有符号类型顾名思义可以有正负符号的,有符号类型通过变量的二进制表示方式的最高位是0表示该变量为正数,如果为1该变量为负数,而其他除最高位外的位值表示真正的值,例如有符号类型的"0111 1111"表示为正的127,最高位0表示为正数嘛。而有符号的"0111 1111"表示为负的127,最高位1表示该变量为负数嘛。而无符号类型每一个位都用来表示变量的值,例如无符号的"1111 1111"表示为255,因为编译器把它的最高为也作为位值了。

其实无论是有符号类型也好,无符号类型也好,在计算机中对它们的存储还是一样的。例如有符号类型的"1111 1111"和无符号类型"1111 1111",它们在计算机中都是以这么一种二进制的方式存储,区别就在于是否把最高位算入位值的计算并将其作为正负的判断依据。

但是要特别注意的一点是,在计算机中,负数以其正值的补码形式来表达的。而补码是正值的反码加1而得的。例如int a= -2;那么a在计算机的表示如下:

a的正值的二进制如下0000 0000 0000 0000 0000 0000 0000 0010;

a的正值的反码如下  1111 1111 1111 1111 1111 1111 1111 1101;

a的补码1111 1111 1111 1111 1111 1111 1111 1101+1=1111 1111 1111 1111 1111 1111 1111 1110;

而正数的源码原码和补码是一样的。

做了一个简单的测试:

unsigned short a=32769;

short b=a;

unsigned short(216的范围是从0~65535,而short(215)的范围是从-32767~32767,这样的话a的值赋给b时很明显会超出b的范围,那么编译器将会如何处理呢?上面说过,无论是有符号类型或者无符号类型,变量在计算机中的存储方式不会变。好,那就先看看a在计算机中的存储是怎样的,用微软的计算器算出为1000 0000 0000 0001,在这里打叉一下,微软的计算器从计算机码转换为十进制时好像都是转换为无符号类型也就是正数的,但微软的计算器能够通过二进制表示一个负数,表示的方式也是以补码的形式来表示的。说到a的存储为1000 0000 0000 0001,从最高位1可以看出a赋值给一个有符号的变量时,一定会为负数,好,那通过求补码的逆过程推出真正的二进制值。首先,1000 0000 0000 0001-1为1000 0000 0000 0000,取其反码0111 1111 1111 1111,再次用微软的计算器,发现值为32767,所以a如果以有符号类型那么a的值就为-32767,调试中发现b的值为-32767,Ok通过验证。

现在假如有这么一种情况:

short a=-2;

unsigned int b=a;

先来看一下a在计算机是怎样存储的,1111 1111 1111 1110,但是整型类型的b在内存中最少分配了32位,a赋值给b的过程当中,由低位开始一位一位的赋值过去,后面的剩下的位都以a的最高位上的值来赋值,所以此时b就为1111 1111 1111 1111 1111 1111 1111 1110,位数小的转换为位数大的,这里有一个总结:对无符号数据,低位字节不变,高位字节补0;对有符号数据,若符号位为0,与无符号数据转换规则相同,若符号位为1,则低位字节不变,高位字节全部置1。故a转为无符号整型时,short为有符号,而且为负,故8位以上的位全为1。但如果赋值过程中出现越界情况时,例如《c++ Primer》中的一个Demo, 8位的unsigned char类型变量c范围为0~255,但是假如现在把336赋值给c时,很明显越界了,这是将采取336对该类型范围的取值个数求模之后的值存入c中,例如该Demo存入的值为336%256=80,故c为80,可是具体机器码是怎么一个赋值转换过程有待以后的补充。

下面再补上一张图片,是借用别人的图片,不同类型间运算编译器自动进行隐式转换的图片:


抱歉!评论已关闭.