2.1 数据及数据类型
数据类型是一种开发语言最基础的部分,本节从全局入手介绍C语言的数据类型及其特点。
2.1.1 C语言常见的数据类型介绍
若用C语言处理一批数据,首先要考虑的是数据在内存中的存放问题。在C语言中,这个工作是由数据类型实现的。C语言要求每个数据在使用之前都必须明确其数据类型,这是因为程序中涉及到的各种数据,都必须存放在内存里,而数据类型决定了数据在内存中的存放形式以及数据可以进行何种运算。C语言中各种数据类型的基本情况如表2.1所示。
表2.1 常见的数据类型
◆ 基本数据类型:整型、实型、字符型、枚举型属于基本数据类型。其最主要的特点是,其值不可以再分解为其他类型。
◆ 构造数据类型:构造数据类型是根据已定义的一个或多个数据类型用构造的方法来定义的。也就是说,一个构造类型的值可以分解成若干个“成员”或“元素”,每个“成员”都是一个基本数据类型,也可以是一个构造类型。在C语言中,构造类型有以下3种:数组类型、结构体类型、共用体(联合)类型。
◆ 指针类型:指针是一种特殊的,同时又是具有重要作用的数据类型。其值用来表示某个变量在内存中的地址。虽然指针变量的取值类似于整型量,但这是两个类型完全不同的量,因此不能混为一谈。
◆ 空类型:一般作为函数的返回值,表示调用结束后,没有任何数据被带回。
说明
各种类型数据所分配的内存,不同的系统有不同的规定,表2.1所示的分配的内存的字节数仅在Turbo C系统下有效,可用运算符sizeof()进行测试。另外,构造数据类型的数据分配的内存由具体的成员类型决定。
2.1.2 常量
数据是组成程序的必要元素,因此在计算机处理的程序中,不免经常与数据打交道。根据在程序中值能否变化,在C语言程序中以常量和变量两种形式表示数据。所谓“常量”,就是指在程序执行过程中,其值不能改变的量。一个常量的类型,由它的书写格式确定,无须事先说明。使用时,在程序需要的地方直接写出来即可。在C语言中常量出现的形式一般有两种。直接常量和符号常量。
2.1.2.1 直接常量
从字面上可以看出数据的值,同时可以分析出数据的类型,则称之为直接常量。从基本数据类型上看出直接常量分为4种:整型常量、实型常量、字符常量和字符串常量。
在后面的内容中将分别介绍其使用方法。
2.1.2.2 符号常量
在C语言中,可以用一个标识符来表示一个常量,称之为符号常量。符号常量在使用之前必须先定义,其一般形式为:
#define 标识符 常量
如果在程序中多次出现一些很大的数字或很长的字符串,为了改进代码的可读性和可维护性,这时便可采用符号常量。符号常量有点像变量,但不能像对变量那样修改符号常量,也不能对符号常量赋以新值。
可以对第1章的程序进行修改,例如求圆面积和周长使用到的π值,为了改进代码的可读性则可定义成符号常量。代码2.1改进了求圆面积和周长的程序。
代码2.1 求圆面积和周长:fiIe1.c
#include "stdio.h" #define PI 3.1415926 /* 定义符号常量PI,其值为3.1415926 */ main() /* 说明符号常量的使用 */ { float r,l,area; scanf("%f",&r); /* 输入圆的半径 */ l=2*PI*r; /* PI为符号常量 */ area=PI*r*r; printf("\n l=%f, area=%f\n",l,area); }
从该例中可以看出,程序用#define命令行定义PI代表常量3.1415926,程序在编译时将用3.1415926替代PI,有关#define命令的用法将在后面的章节中进行详细介绍。
注意
◆ 符号常量不同于变量,它的值在其作用域(本例中为主函数)内不能改变,也不能再被赋值,例如在程序中出现下面的语句就是错误的:PI=3.14;
◆ 习惯上,符号常量名用大写,变量名用小写。
◆ 使用符号常量的好处有两个:一是含义清楚,如在本例中,可以看出PI代表圆周率。二是在需要修改常量值时比较方便,例如可以用#define PI 3.14替代原有命令行以达到修改圆周率的目的。
2.1.3 变量
在程序的执行过程中值可以发生变化的量称为变量。用户应该为程序中用到的每一个变量起一个名字,称为“变量名”。在C语言中,为变量起名应符合标识符的命名规则,因此,变量名只能以字母或下划线开头。
在程序中声明了一个变量之后,内存就会有一个存储区与之对应。由于变量所表示的数据可以是除void以外的任意类型的数据,所以变量在内存中所占的存储空间根据数据类型的不同而不同。每一个变量有且只有一种类型,变量的类型决定了该变量在内存中所占的字节数。在变量进行相关运算时,变量的类型是编译系统检查运算是否合法的依据。每一个变量存储区的第一个字节的地址,称为是该变量的“地址”。C语言中,一个变量的地址只能通过在变量前加“&”符号来得到,称其为“取地址符”。
变量定义后,虽然没有给它赋值,但由于变量占据一定的内存空间,所以此时变量实际上是有值的,但是该值是一个“不确定”的值。如果用该不确定的值参与运算,所得到的值也是不确定的。所以在使用变量之前,应首先为变量赋一个确定的值。
说明
变量中的“变”体现的是这个存储单元可以存放不同的数据,但每一时刻只具有唯一的值,即新放入的数据将覆盖原有的数据。
变量的数据类型决定了变量的取值范围和占用内存空间的字节数,变量名表示具有同一数据类型变量的集合。在声明变量的时候,这两点是必须要说明的。变量的使用一定要本着“先声明,再使用”的原则,否则程序会产生错误。定义变量的一般形式为:
数据类型 变量名1, 变量名2, 变量名3, … ;
这样要求的目的是:凡是未被事先定义的标识符,不能作为变量名,这样做能保证程序中变量名的正确使用。例如在定义部分写成:
float total; /*定义变量total*/
而下面的使用语句中错写成t0taI,在编译时会检查出t0taI未被定义,不能作为变量名,这样便于发现错误,避免变量名在使用时出错。
每个变量被定义为一个确定数据类型,在编译时就能为其分配相应的存储空间。例如定义num为int型,则编译程序将为变量num分配两个字节的存储空间,并按照整型方式存储。每个变量属于一定的数据类型,便于编译时据此检查该变量所进行运算的合法性。例如,整型变量x和y可以进行求模运算x%y,%是求模运算符,得到x除以y的整余数。如果将x和y定义为浮点型变量,则不允许进行“求模”运算,在编译阶段就会指出有关的出错信息。
代码2.2体现了常量和变量的使用方法。
代码2.2 常量和变量的使用:fiIe2.c
# include <stdio.h> #define PRICE 12.8 /*定义符号常量 PRICE*/ void main() { int num; /*定义变量num*/ float total; num=20; /*为变量num赋初值20*/ total=num*PRICE; printf("The Total is %f\n", total); /*输出变量的值*/ }
由例题可以看出,常量使用时只要注意其书写形式,编译系统知道它的值和数据类型即可。符号常量在定义处更改,就可更改整个程序中此符号常量的值。变量在使用前必须定义,编译系统根据数据类型为其分配存储空间。在实际使用时必须用变量或表达式为其赋值,否则结果是不确定的值。