上次我总结到C语言的词法符号时提及过C语言的32个关键字,但并未详细介绍过现在我就来详细的介绍下32个关键字的一部分。在介绍关键词之前我们要明确这32个关键词在C语言中的地位,可以这样形容吧,这32个关键词就像我们在学习英语时的26个字母一样,它是构成C语言这一语言体系的基本元素。那么熟练的掌握它就很有必要了。今天我就详细的介绍下32个关键词中的第一大类中的前两类(共9个关键字),他们是:基本数据类型(void、char、int、float、double)、修饰类型(short、long、signed、unsigned)。

首先我们还是整体的了解下C语言中常见的数据类型:

192144813.png

这里有一点争议需要指出的是在谭浩强老师的C语言书中将枚举类型列为基本类型,而在陈正冲老师的《C语言深度解剖》中将枚举类型列为构造类型。在这里我还是赞成谭浩强老师的分类,等下说到枚举类型我将解释原因。

这里先看看基本数据类型。

基本数据类型:基本类型是C语言程序设计的最小单元,又被称为原子数据类型,其它的复杂数据类型都可以由基本数据类型进行构造。

一、整型数据家族:

整型数据类型最基本的关键词是:int 。它能被另外的4种修饰类型的关键字所修饰因此一共可以组成6中类型的整型:

类型字节数(byte)比特数(bit)取值范围
[signed] int432

2147483648~2147483647

unsigned int432

0~4294967295

[signed] short [int]216

32768~32767

unsigned short [int]2160~65535
long [int]432

2147483648~2147483647

unsigned long [int]4320~4294967295

说明:上表中的[]内的关键字可以省略;

为了表明我上表中每种整型数据类型的正确性,我将在下面做一个很简单的小实验,其中要接用关键字sizeof,这里又要着重的说明下:sizeof不是函数名,更不能把sizeof()看成是一个函数,它的作用是等到特定类型或特定类型变量所占字节的大小。

195656189.png

其结果如下:

195727903.png

这里需要指出的是不同的计算机的体系结构中这些类型在内存中所占的字节数有可能不同。若想查看当前机器的各数据类型所占的字节数(取值范围),可以查看文件"limits.h"(通常在编译器相关的目录下:/usr/include/limits.h),如下所示:

200900693.png

还有点小的技巧需要指出:

在嵌入式开发中,经常需要考虑的一点就是可移植性的问题。通常把存储于int型的变量的值限制于signed int和unsigned int的交集中,这样可以获得最大的可移植性又不牺牲效率。

整型常量可以八进制、十进制、十六进制3中表示方式表示。

1.1、十进制 :用0~9 十个数表示,满十进一;


十进制数是日常生活中使用最广的计数制。组成十进制数的符号有0123456789等共十个数码
  在十进制中,每一位有09共十个数码,所以计数的基数10。超过9就必须用多位数来表示。


十进制数的运算遵循:加法时:逢十进一;减法时:借一当十
  十进制数中,数码的位置不同,所表示的值就不相同(与位权有关)


  每个对应的数码有一个系数1000,100,10,1与之相对应,这个系数就叫做权或位权。十进制数的位权一般表示为:10n - 110为十进制的进位基数;10i次为第i位的权;n表示相对于小数点的位置,取整数;当n位于小数点的左边时,依次取n=123……n。位于小数点的右边时,依次取n=-1-2-3……因此,634.27可以写为:634.27=6×102+3×101+4×100+2×10^-1+7×10^-2;在正常书写时,各数码的位权隐含在数位之中,即个位、十位、百位等。


1.2、二进制 :


二进制计算法的特点:


二进制数只有01两个数码,基数是2,最大的数字是1


采用逢二进一的原则。


  二进制的位权一般表示为:2^n-1。各位的权为以2为底的幂。例如,(01101010)各位的权自至在依次为2^72^62^52^42^32^22^12^0


  二进制数的算术四则运算规则,除进、借位外与十进制数相同。
二进制加法规则
00=0 10=1
01=1 11=10(红色为进位位)
二进制减法规则
0-0=0 0-1=1-借位
1-0=1 1-1=0
二进制乘法规则
0×0=0 1×0=0
0×1=0 1×1=1


为了区别于十进制数,在书写时二进制数可以用两种方法表示:例如:(1011.01)21011.1B


例如:写出(1011.01)2的十进制数表达式。
(1011.01)2=1×23+0×22+1×21+1×20+0×2-1+1×2-2=(11.25)10


  二进制的优点是:
二进制只有01两数字,很容易表示。电压的高和低、 晶体管的截止与饱和、磁性材料的磁化方向等都可以表示为01两种状态。
二进制数的每一位只有01两状态,只需要两种设备就能表示, 所以二进制数节省设备。由于状态简单,所以抗干扰力强,可靠性高。


二进制的主要缺点是:

数位太长,不便阅读和书写,人们也不习惯。为此常用八进制和十六进制作为二进制的缩写方式。为了适应人们的习惯,通常在计算机内都采用二进制数,输入和输出采用十进制数,由计算机自己完成二进制与十进制之间的相互转换。


应用 : 1、用于电子计算机信息处理


2、编码;


注:在C语言中一般不用二进制数表示;



3、八进制 :用0 ~ 8 八个数表示,满8进一;


注:八进制以0作为前导;


有八个不同的计算符号01234567,这八个符号称为数码。
  采用逢八进一的原则。对应于十进制数012345678,八进制数分别记作01234567810



4、十六进制 : 以0 ~ 9 ,a(A), b(B), c(C) , d(D), e(E), f(F)十六个数码表示,满十六进一;


注:十六进制数以0x/X做前导;


二进制数在计算机系统中处理很方便,但当位数较多时,比较难记忆及书写,为了减小位数,通常将二进制数用十六进制表示。
  十六进制是计算机系统中除二进制数之外使用较多的进制。

  十六进制数的位权一般表示为:16^n-1。其中16是十六进制的进位基数,n表示相对小数点的位置。在书写时,用加注16H的方式表示十六进制数,例如:(8FA.5)168FA.5H例如:写出(8FA.5)16的十进制数表达式。
(8FA.5)16=8×162+15×161+10×160+5×16-1=(2298.3125)10



进制间的相互转换应该结合1、三位二进制数可以转换成一位八进制数;2、四位二进制数可以转换成一位十六进制数;

详细如何进行转换在这里我就不详叙。


二、实型家族:

所谓实型也就是常说的浮点型,其基本类型的关键字有:float、double;修饰的关键字只有:long一个,一共组成3种实型:

类型比特数有效数字取值范围
float(单精度)326~7

3.4×10^38~3.4×10^38

double(双精度)6415~16

1.7×10^308~1.7×10^308

long double6418~19

1.2×10^308~1.2×10^308

这里我就不再累赘的去叙序它们之所以占的字节数了。

如果你观察仔细你一定会有这种质疑:为什么float与int类型中的众多类型所占的字节数是相同的,但它们的取值范围为什么不一样呢?

呵呵,如果有这个疑问就说明你还没彻底的了解数据在计算机内存中的存储方式了。

其实它们的取值范围不同是由于在内存中的存储方式不同造成的。

对于整型类型的数据:

如果是无符号的整型数据则在内存中是以原码的形式储存的,不存在符号位,如果该机器位整型数据分配4个字节则最大可表示为:(二进制形式)1111 1111 1111 1111 1111 1111 1111 1111,其十进制表示为:4294967295 ;最小的当然是全零了,即为零。所以int类型的数据的取值范围就为:0~ 4294967295。其它的无符号整型依次类推即可得到其取值范围。

如果是有符号类型的整型数据,则在内存中以补码的形式存储。在每个内存单元的最高位(最左边的那一位)用于存储符号位:其中若为正,则符号位是:0;若为负,则最高位的符号位为:0。为了简化理解过程和叙述简单起见我们可以这样理解,在有符号类型的int类型数据的有效位只有31bit,则其能表示的最大二进制数位:111 1111 1111 1111 1111 1111 1111 1111;其十进制数表示为:2147483647。当符号位为:0时,则表示最大十进制数为:2147483647;当符号为:1时,表示该整型数据为负,当这里有一点需要注意,计算机存储的补码:1000 0000 0000 0000 0000 0000 0000 0000计算机是默认其值:- 2^32 = 2147483648。如果有兴趣可以想想这是为什么。所以signed int范围为:2147483648 ~ 2147483647。其它的有符号类型可以照此类推。


对于实型数据:

实型常量的表示:在C语言中实型常量只以十进制的计数法来表示。但其有两种形式:

一种就是我们习惯用的十进制形式表示:由数码0 ~ 9和小数点一起表示,如:0.;.25; 5.13;50;等;

另一种就是用指数形式表示:<尾数>E(或e)<整型指数>,如:.12E-2; -4.e10;6.7E23等;


实型数据在内存中的存储形式:一律都用指数的形式存储。

无论是单精度还是双精度在存储中都分为三个部分:


1 符号位(Sign) : 0代表正,1代表为负


2 指数位(Exponent:用于存储科学计数法中的指数数据,并且采用移位存储 指数部分也有符号位,故其取值范围是-127~ 128


3 尾数部分(Mantissa):尾数部分(小数点后面的部分)


单精度浮点数:1位符号位,8位指数位,23位有效数字。
双精度浮点数:1位符号位,11位指数位,52位有效数字。
计算规则数字 = 有效数字*2^指数*符号


其中float的存储方式如下图所示:

230043127.gif

而双精度的存储方式为:


230124973.gif

结合前面我提到过的推导方法和上图我们不难推导出单精度和双精度的表示范围比整型的表示范围更广。

也有以下规律:

小数部分所占的位数(bit)越多越,数的精度就越高;


指数部分所占的位(bit)数越多,数据所表示的范围越大;


三、字符型家族

字符型数据可以看成是特殊的整型数据(整型数据的一部分),可以这样理解,字符型数据最终在计算机中是以字符对应的ASCII值来存放的,如果稍稍学过C语言的人应该知道ASCII值是整型数据吧。呵呵。。。不信的话我来亮亮证据:

214544501.png

214757849.png

我这里还有个网址可以查看ASCII表:http://www.weste.net/tools/ASCII.asp

表示字符类型的关键字:char ;修饰的关键字:signed 、unsigned;

所以用只有两种类型:

类型字节数(byte)比特数(bit)取值范围
(signed)char18-128 ~ 127
unsigned char180 ~ 255

这里有一个经典的实例,可以对char的变量范围进行理解:

221241838.png

其结果为:

221307896.png

从这里可以清楚的看出无符号的char类型数据的范围了。

对于有符号的数据类型一样的可以推导,这里还是不坠叙了。


字符常量是指用单括号括起来的一个字符,如’a’、’D’、’+’、’?’等都是字符常量 。


五、空类型

定义空类型的关键字是:void,没有修饰类型的关键字修饰它。

空类型是所有数据类型的基础。不要故名思议的认为空类型就是无数据类型,它本身就是一种数据结构,常用于数据的转换和和参数的传递过程。


六、枚举类型

在枚举类型的定义中列举出所有可能的取值,被定义为该枚举类型的变量取值不能超过定义的范围。枚举类型是一个基本数据类型的原因是因为它不再可分解成任何基本类型。



七 C99标准扩展的基本数据类型:

1、bool类型 非零表示为真、零表示为假


注:a、在不支持C99的机器体系结构中C语言不支持bool类型,但可以自己定义:

typedef char bool;
#define TRUE 1
#define FALSE 0

借助char的原因,因为char类型的数据在内存中占一个字节,所以可以做到内存更省;

b、在使用bool类型时一定要在头文件中包含"stdbool.h"。


2、long long int 类型 在内存中占64位,表示的范围更加地广,由int 范围的推导,我们可以推导出其所表示的范围



介绍到这里相信你对C语言的基本数据类型有个全面的了解吧!^-^