基本数据类型
C语言中的基本数据类型包括字符类型、整型类型、浮点类型和布尔类型,下面分别对这几种基本类型进行详细讲解。
1、字符类型
在C语言中,字符类型用关键字char表示,即使用char定义字符类型变量。字符类型变量用于存储一个单一字符,每个字符变量都会占用1个字节。
为字符类型变量赋值时,需要用一对英文半角格式的单引号('')把字符括起来,定义字符变量的示例代码如下所示:
char ch1 = 'A'; //定义字符变量ch1,其值为字符'A'
char ch2 = '3'; //定义定义变量ch2,其值为字符'3'
上述代码中,对于字符变量ch1,将字符常量‘A’存放到字符变量ch1中,实际上并不是把该字符本身存放到变量的内存单元中去,而是将该字符对应的ASCII编码存放到变量的存储单元中。ASCII编码表使用编号65来表示大写字母“A”,因此变量ch存储的是整数65,而不是字母“A”本身。同理,字符变量ch2存储的是字符‘3’的ASCII码值83。
需要注意的是,除了可以直接从键盘上输入的字符(如英文字母,标点符号,数字,数学运算符等)以外,还有一些字符是无法用键盘直接输入的,比如,“回车”,此时需要采用一种新的定义方式——转义字符,它以反斜杠\开头,随后接特定的字符。表1列举了C语言常见的转义字符。
表1 C语言常见转义字符表
转义字符 | 对应字符 | ASCII**码表中的值** |
---|---|---|
\t | 制表符(Tab键) | 9 |
\n | 换行 | 10 |
\r | 回车 | 13 |
" | 双引号 | 34 |
' | 单引号 | 39 |
\ | 反斜杠 | 92 |
在程序中定义转义字符的示例代码如下所示:
char ch2 = '\n'; //转义字符\将字符n转义,两者合起来功能为换行
char ch4 = '\\'; //如果要使用字符\,则需要使用它自身进行一次转义
2、整型
在程序开发中,经常会遇到0、-100、1024等数字,这些数字都可称为整型数据,整型数据就是一个不包含小数部分的数。在C语言中,根据数值的取值范围,可以将整型定义为短整型(short int)、基本整型(int)和长整型(long int),long int也可简写为long。
整型数据可以被修饰符signed和unsigned修饰。其中,被signed修饰的整型称为有符号的整型,被unsigned修饰的整型称为无符号的整型,它们之间最大的区别是:无符号整型可以存放的正数范围比有符号整型的大一倍。例如,int的取值范围是-231~231-1,而unsigned int的取值范围是0~232-1。默认情况下,整型数据都是有符号的,因此signed修饰符可以省略。
表2列举了各种整型占用的空间大小及其取值范围。
表2 整型占用空间及其取值范围
修饰符 | 数据类型 | 占用空间 | 取值范围 |
---|---|---|---|
[signed] | short [int] | 16位(2个字节) | -32768到32767 (-215 ~ 215-1) |
int | 32位(4个字节) | -2147483648到2147483647 (-231 ~ 231-1) | |
long [int] | 32位(4个字节) | -2147483648到2147483647 (-231 ~ 231-1) | |
unsigned | short [int] | 16位(2个字节) | 0到65535 (0 ~ 216-1) |
int | 32位(4个字节) | 0到4294967295 (0 ~ 232-1) | |
long [int] | 32位(4个字节) | 0到4294967295 (0 ~ 232-1) |
由表2可知,short类型占用2个字节的内存空间,int与long占用4个字节的内存空间,在取值范围上,short的取值范围小于int和long。
需要注意的是,整型数据在内存中占的字节数与所选择的操作系统有关,例如,在16位操作系统中,int类型占2个字节,而在32位和64位操作系统中,int类型占4个字节。虽然C语言标准中没有明确规定整型数据的长度,但long类型整数的长度不能短于int类型,short类型整数的长度不能长于int类型。
3、浮点类型
浮点类型又称实型,是指包含小数部分的数据类型。C语言中将浮点数分为float(单精度浮点数)、double(双精度浮点数)和long double(长双精度浮点数)三种,其中,double和long double类型变量所表示的浮点数比float类型变量更精确。
表3列举了三种不同浮点类型占用的存储空间大小及取值范围。
表3 浮点类型长度及其取值范围
类型名 | 占用空间 | 取值范围 |
---|---|---|
float | 32位(4个字节) | 1.4E-45 ~ 3.4E+38,-1.4E-45 ~ -3.4E+38 |
double | 64位(8个字节) | 4.9E-324 ~ 1.7E+308, -4.9E-324 ~ -1.7E+308 |
long double | 64位(8个字节) | 4.9E-324 ~ 1.7E+308, -4.9E-324 ~ -1.7E+308 |
表3中,列出了三种浮点类型变量所占的空间大小和取值范围。在取值范围中,E表示以10为底的指数,E后面的“+”号和“-”号代表正指数和负指数,例如,1.4E-45表示1.4*10-45。
为了让读者更好地理解浮点类型数据在内存中的存储方式,接下来以单精度浮点数3.14159为例讲解浮点类型数据在内存中的存储方式。编译器在存储浮点类型数据3.14159时,会将浮点数分成符号位、小数位和指数位三部分,分别存储到内存单元中,如图1所示。
图1 单精度浮点数存储方式
在图1中,小数3.14159在内存中的符号位为“+”,小数部分为.31415,指数位为1,连接在一起即为“+0.314159 * 101 = 3.14159”。
在定义浮点类型变量时,可以在float类型变量所赋值的后面加上大写字母“F”或小写字母“f”,在double类型变量所赋值后面加上大写字母“D”或小写字母“d”,具体示例如下:
float f1 = 123.4f; //为一个float类型的变量赋值,后面可以加上字母f
float f2 = 123.4; //为一个float类型的变量赋值,后面可以省略字母f
double d2 = 199.3d; //为一个double类型的变量赋值,后面可以加上字母d
double d1 = 100.1; //为一个double类型的变量赋值,后面可以省略字母d
浮点类型常量默认是double类型,如2.56,它默认为double类型常量,占据8字节内存。在浮点类型常量后面加上F或f,该数据就是float类型,如2.56f,它为float类型,占据4字节内存。
脚下留心:float和double精确度
由于浮点型变量所占据的内存空间大小有限,因此只能提供有限个数的有效数字。有效位以外的数字将不精确。双精度浮点数的有效位数更多,比单精度浮点数更能精确表达数据,它能提供15~16位有效位数,而单精度浮点数只能提供6~7位有效位数。
将1.12345678910111213赋值给一个float类型变量和一个dobule类型变量,该数据小数点后面有17位数,将这17位数全部输出,可以观察float类型变量与double类型变量的精确位数,示例代码如例1所示。
例1 accuracy.c*
1 #include <stdio.h>
2 int main()
3 {
4 float f = 1.12345678910111213; //float类型变量
5 double d = 1.12345678910111213; //double类型变量
6 printf("f = %.17f\n", f);
7 printf("d = %.17f\n", d);
8 return 0;
9 }
例1运行结果如图2所示。
图2 例1运行结果
由图2可知,变量f精确到小数点后6位,变量d精确到小数点后15后,其后进行了四舍五入。这说明,double类型的精确度比float类型要高。
在上述代码中,%.17f指输出小数点后面17位数,如果不指定小数点后面的输出位数,float与double类型变量默认输出到小数点后6位。*
4、Bool类型
C99标准增加了一个新的数据类型:Bool,称为布尔类型。Bool类型的变量用于表示一个布尔值,即逻辑值true和false。在C语言中,使用数值0表示false,用1表示true,实际上,Bool类型也是一种整数类型,但它只占1字节存储空间。
当为Bool类型变量赋值为0或NULL时,其值为0,即false,而赋予其他非0或非NULL值时,其值为1,即true。使用Bool类型定义一些变量,示例代码如下:*
_Bool b1 = 10; //为_Bool类型的变量赋值为10,b1的值为1,即true
_Bool b2 = NULL; //为_Bool类型的变量赋值为NULL,b2的值为0,即false
_Bool b3 = 0; //为_Bool类型的变量赋值为0,b3的值为0,即false
_Bool b4 = -28; //为_Bool类型的变量赋值为-28,b4的值为1,即true
_Bool b5 = ""; //为_Bool类型的变量赋值为空字符串,b5的值为1,即true