任务描述
由于不同类型的数据的存储方式是不同的,所以C语言中的数据是分不同类型的。本任务介绍整型、浮点型和字符型3 大数据类型,以及它们在计算机中如何存储、表示和计算。3大数据类型在使用的时候要区分常量和变量,本任务同时还介绍3 大数据类型在程序中各自所需要的常量和变量的使用。
知识学习
(1)数据类型
数据是计算机程序处理的所有信息的总称,例如整数、实数、字母、单词、一段文章、一个企业的员工信息等。在C语言中,将各数据分为不同的类型处理,不同类型的数据在计算机中分配的内存空间大小不同,能够参与的运算也是有所区别的。
C语言中共有9 种数据类型,分别是整型、实型(浮点型)、字符型、枚举型、数组类型、指针类型、结构体类型、共用体类型和空类型。其中整型、实数型和字符型是C语言中最基本的数据类型,也是后续学习中将经常使用到的。9 种数据类型的分类情况如图2.1所示。

图2.1 C语言中的数据类型
在C语言中,基本数据类型按照其值在程序执行中是否改变可以分为常量和变量两种。在程序执行过程中,其值不发生改变的量成为常量,其值可变得量成为变量。两者通常跟数据类型结合起来分类,如整型常量和整型变量,浮点常量和浮点变量,字符常量和字符变量等。
(2)常量
在程序中,有些数据是不需要改变的,也不能改变。来看下面这段代码:

该段程序中的128,13.14,‘a’,“Hello”在程序执行中始终是保持不变的,都称为常量。其中,128 为整数常量,13.14 为实数常量,‘a’为字符常量,“Hello”为字符串常量,这都是最基本的常量类型。
1)整型常量
C语言的整数可以使用3 种数制表示,即十进制、八进制和十六进制。为了对它们加以区别,C语言中规定八进制整数以0 开头,后面的数字范围为0 ~7,十六进制整数以0x 或0X 开头,后面的数字取值范围为0 ~9 和A ~F(a ~f),十进制整数与传统数学方式表达无异。其中整数实例举例如下:
十进制整数:128、1314、-520;
八进制整数:06(6)、0106(70)、0256(174);
十六进制数:0x123(291)、0X0D(13)、0xff(255)。
2)实型常量
实数常量只有十进制一种数制,但是可以用一般和指数两种形式表示。其中一般形式是由整数部分、小数点、小数部分和符号组成。比如0.78, -6.20,30.0。如果小数点后面全是0,可以省略0 但是小数点必须在,如30.。对于指数形式则是由数字、小数点、字母E(或e)和正负号组成,如123e3(123*103)、-3.168E -6( -3.168*10 -6)、0.458e +2(0.458*102)。有人曾这么总结实型常量的特点:浮点小数莫忘点,指数E(e)挑两边全,E(e)后必须是整数,前后两边紧相连。
举例:

运行结果如图2.2所示:

图2.2 指数与浮点数
3)字符常量
在C语言中,字符常量一般是指单引号里面的单个字符,如‘a’‘1’‘A’,注意‘A’和‘a’是不同的常量。除此之外,还有一种特殊的字符常量,称为转义字符,以反斜杠“\”开头的字符序列,表示反斜杠后面的字符被转换成其他意义,如上段程序中的‘\n’,其中字母n 被作为换行符。C语言中常见一些转义字符及功能见表2.2。
表2.2 C语言中常见的转义字符

在C语言中,5 和‘5’的含义是不一样的,5 是数值,可运算;‘5’是字符,一个符号。
举例:

运行结果如图2.3所示:

图2.3 printf 演示
4)字符串常量
字符串常量是用一对双引号括起来的字符序列,如“welcome”“a”“abc\n”。这里要说明一下,字符串在内存中存储时,存放的是每一个字符对应的ASCII 码值。因此一个字符只需要一个字节,但是字符串为了区别普通的字符序列,C语言会为每个字符串多分配一个字节,该空间中存放固定的字符‘\0’,用以表示字符串的结束。所以‘a’和“a”是两个不同的常量类型,前者是字符,在内存中只占1 个字节,后者是字符串,在内存中占2 个字节。
如程序:

运行结果如图2.4所示。

图2.4 数据类型的字节
5)符号常量
在C语言中,用一个标识符来表示的常量成为符号常量。其定义格式如下:
#define 标识符常量
其中,#define 是一条预处理命令(预处理命令都以#开头),称为宏定义命令(在后续章节详细介绍),功能是把该标识符定义为其后的常量值,一旦定义,以后程序中所有出现该标识符的地方用常量值替代。如:
#define PI 3.14159
上面的代码表示用符号PI 替代3.14159。在编译之前,系统会自动把程序中出现的PI 全部替换成3.14159,也就是说在编译运行时系统中只有3.14159,没有符号。
下面代码使用符号常量计算圆的周长和面积。

运行结果如图2.5所示。

图2.5 圆的周长和面积
该程序经过系统预处理,程序在编译运行之前就将“,2*PI*r”变成了“2*3.14159*r”,将“PI*r*r”变成了“3.14159*r*r”。代码运行后,当用户在键盘上输出半径10 后,按下回车键,程序会输出圆的周长和面积。
符号常量跟其他常量是一致的,在作用域内其值不能改变,也不能再赋值。使用符号常量的好处在于修改定义处即可实现全部修改。习惯上符号常量的标识符用大写字母表示,方便与变量标识符的小写字母进行区分。
(3)变量
程序中的变量是用来存储数据的,在程序执行的过程中,其值是可以改变的。有人把变量比作一个抽屉,知道了抽屉的名字(变量名),就能找到抽屉的位置(变量的存储单元)以及抽屉里面的东西(变量的值),抽屉里面存放的东西和变量一样,也是可以变化的。有4 个概念与变量相关:
①变量名:一个符合规则的标识符,其命名规则与标识符的命名规则一致。
②变量的类型:C语言中的数据类型或者自定义的数据类型。
③变量的地址:数据在内存中的位置。
④变量值:存放在内存空间中的值。
程序编译时,会给每一个变量分配存储空间和位置,程序读取数据的过程,其实就是根据变量名查找内存中对应的存储空间,然后从中取值的过程。通过下面这个例子先来看变量的输出问题,运行结果如图2.6所示。


图2.6 变量的演示
C语言中的变量也分为不同的数据类型,用于存储不同类型的数据。例如,使用整型变量存储整数,使用实型变量存储实数。C语言规定,在使用一个变量前,都要对这个变量进行定义。其目的在于程序运行前,告诉编译器程序使用的变量,以及与这些变量相关的属性(变量名、类型和长度等),编译器根据这些信息对变量分配合适的内存空间。
1)变量的定义
变量定义的一般格式:
类型声明符 变量名[,变量名,…];
方括号的内容表示可选的,类型声明符用来说明变量的数据类型,变量名必须遵守标识符命名规则。例如:

2)变量的赋值
用赋值语句把计算得到的表达式的值赋给一个变量。例如:

3)变量的初始化
在定义变量时,给变量赋值称为变量的初始化。例如:
int x=3,y;∥在定义变量x,y 的同时给变量x 赋值为3,是对变量x 进行初始化。
需要注意的是,在定义是初始化时,如果多个变量初始化为相同的值,是不能按照下面代码书写的,int a=b=c=9;正确的操作方式是先定义,然后再赋值:int a,b,c;a=b=c=9。
4)变量的数据类型
在C语言中,数据类型可分为4 类,即基本数据类型、构造数据类型、指针类型和空类型,在此介绍基本数据类型,其余类型在以后章节中陆续介绍。(https://www.xing528.com)
①整型变量。整型变量可以分为基本整数型、短整数型和长整数型3 种,分别用int、short int 和long int 作为类型标识符,不同类型的整数型变量占用的空间不同,能够存储的数字范围也不同。整数型变量又分为有符号和无符号,用signed 和unsigned 说明。有符号整数存储时,其存储空间的最高位是符号位,其他位是数值位;无符号整数所有的位数都是数值位。整型数据分类情况表见表2.3。
表2.3 整型的常见表达方式

每一个类型所占的字节数可以用下列代码进行验证,结果如图2.7所示。



图2.7 各整型所占的字节数
在使用时需要注意数据的溢出问题,也就是超出了能表达的数据范围。比如一个短整型量赋初值为32767,让其做加1 运算,预期的结果应该是32768,但是在程序执行时得到的确是负数结果。根据前面内容知道short 型能表达的数据范围为-32768 ~32767。这有点类似于在环形跑道上跑步,终点又是起点。程序如下,其结果如图2.8所示。
![]()


图2.8 整型量的溢出
后面再使用选择变量的数据类型时,读者一定要提前考虑空间存储数据的大小范围,由于这种情况C语言是不提供任何警告和提示的,只是会出现不正确的结果。
②实型变量:实型变量用来存储小数数值。实型数据分类及长度见表2.4。
表2.4 浮点型的种类

浮点型变量是由有限的存储单元组成的,因此能提供的有效数字总是有限的,在其有效位数以外的数字将被舍弃。因此会产生一些误差,称为舍入误差,在运算时需要注意,一般不要对两个差别较大的数值进行求和运算,因为求和后,较小的数据对求和结果并没有什么影响,程序如下,其结果如图2.9所示。

图2.9 浮点型的误差


根据前面的知识可以知道,float 类型表达数据有效数字位数为6 ~7 位,double 类型的有效数字位数为16 ~17 位,当有效数字超出这些时,其值也会出现误差。比如下面这个案例,结果如图2.10所示。


图2.10 单精度与双精度
从结果中可以看出,a 变量是单精度浮点型,有效数字最多是7 位,而整数部分已经占了5 位,那么小数点两位之后的数字均为无效数字。不过系统还是会按照小数点后6 位进行输出。读者如果演示该程序,出来的结果不一定跟这里是一样的。b 变量是双精度浮点型,有效位数为16 位,但是默认情况下小数点后依然保存6 位,其余部分被舍去。要想看到多余6 位的小数部分,可以按照“%.nlf”的方式书写。n 是指小数点后的位数,%后的点不能省略,结果如图2.11所示。

③字符型变量:C语言字符是语言的最基本的元素,由字母、数字、空白符、标点和特殊字符组成。在机器中,字符型也是一种整型,以1 个字节(8 位)的ASCII 存储。

图2.11 格式控制符控制小数点
可以将存储在字符变量中的值解释成一个有符号的值,也可以解释为无符号的值。字符型数据分类及长度见表2.5。
表2.5 字符类型

字符变量可以像数值型变量一样参与运算,比如一个比较经典的案例:实现字符的大小写转换,程序如下,运行结果如图2.12所示。


图2.12 字符类型的变化
前面提到了字符串常量,但是在C语言中不能像前面3 种变量一样去定义字符串变量,需要借助数组的知识进行,将在后续项目中进行讲解。
(4)类型转换
不同的数据类型之间可以进行混合运算,编译器是如何处理的呢? 当遇到该情况时,编译器一般是尝试转换成同类型,转换成功继续运算,转换失败程序报错终止运行。数据类型的转换有两种方式:自动类型转换和强制类型转换。
1)自动类型转换(隐式转换)
在C语言中,设定了不同数据类型参与运算时需要遵循以下规则:
①若参与运算的量类型不同,则先转换成同一类型,然后再运算。
②转换时按照数据长度增加的方向进行,以保证精度不降低。比如long 和int 型运算,先将int 型转换成long 型之后进行运算。
③所有浮点数运算都是以双精度进行的,也就是说全部是float 型量进行运算,程序依然会先转换成double 型再运算。
④在char 和short 类型参与运算时,必须先将它们转换成int 型。
⑤如果是在赋值运算中,赋值符号的两边类型不一致时,赋值符号右边的类型将转换为左边的类型。如果右边比左边的数据类型长度大,此时会按照舍入的方式丢失一部分数据,这样会降低精度。
一般自动类型转换如图2.13所示:

图2.13 自动转换的方向
以下是求圆面积的例子,运行结果如图2.14所示。


图2.14 自动转换
在这个转换过程中,可以借助编译环境的调试功能,观察程序执行过程中变量之间的变化。图2.15(a)显示各变量在未赋初值时的数据,为内存中的随机值,即执行第4 行语句前。图2.15(b)执行了pi 赋值后的结果,执行完第4 行语句,此时也可以看出单精度浮点型存在误差问题。图2.15(c)执行了整数r 赋值语句,即第6 行代码。图2.15(d)执行了第7 行求圆的面积,此时t 还是浮点型。图2.15(e)执行了第8 行代码,完成由浮点型向整型的转换。

图2.15 程序调试显示步骤
2)强制类型转换
在C语言中,可以把一种类型的数据通过强制类型转换为另一种类型的数据。
强制类型转换一般格式为:
(类型声明符)(表达式)
功能:把表达式的运算结果强制转换成类型声明符所表示的类型。例如:

在使用强制转换时应注意以下问题:
①类型声明符和表达式都必须加括号(变量可不加),如把(float)(a +b)写成(float)a +b则成了把a 转换成float 型之后再和b 相加。
②将实数转换为整数时,直接截断,不是四舍五入,如(int)5.8 结果为5。
注意:强制转换和自动转换只是为了本次运算的需要而对变量的数据长度进行的临时性转换,而不改变原来对该变量定义的类型。如(int)x 只是将x 的值转换成一个int 型,x 本身还是它原有的数据类型。
下面这个例子综合演示这两种转换,在阅读该程序时,请注意自动类型转换是否丢失了数据,以及强制类型转换的对象类型问题,如图2.16所示。


图2.16 自动和强制类型转换
任务总结
对于变量必须先定义,再使用。根据定义变量时指定的类型,编译系统为变量分配相应的存储单元;凡未被先定义的,系统不把它作为变量名,保证程序中变量名使用正确;指定了每一变量属于一个类型,就便于在编译时据此检查在程序中要求对该变量进行的运算是否合法。
变量与内存的关系:每一个变量有名字、类型、值、位置和大小。当一个新的值赋予变量时,新值会替换原值;从内存中读取变量的值,其值不会改变。
实型数据的舍入误差:实型变量是由有限的存储单元组成的,能提供的有效数字总是有限的,在有效位以外的数字将被舍去,会产生一些误差。
字符型数据和整型数据是通用的:它们之间可以直接进行运算,也可以用字符形式输入与输出,还可以用整型形式输入与输出。
不同类型的数据进行计算时,首先应该将其转换成相同的数据类型,然后再进行计算。转换的方式有两种:自动类型转换和强制类型转换。其中自动类型转换的原则是将存储空间小的转换为存储空间大的,或者是精度低的转换为精度高的。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。
