2.2 C++语言基本要素
程序设计语言的基本要素包括标识符、关键字、常量和变量等。本节将介绍C++语言的基本要素。如果读者熟悉C语言,可以跳过本节。
2.2.1 标识符
在C++语言中,变量、常量、函数、标签和用户定义的各种对象,被称为标识符。标识符由一个或多个字符构成。字符可以是字母、数字或下划线,但是标识符的首字符必须是字母或下划线,而不能是数字。例如,下面的标识符均是合法的。
而下面的标识符是非法的。
在C++语言中,标识符是区分大小写的。例如,“value”和“Value”是两个不同的标识符。此外,标识符不能与C/C++的关键字同名。
注意
C++语言中标识符的长度可以是任意的,但是通常情况下,前1024个字符是有意义的,这与C语言不同。在C语言中,标识符也可以是任意长度,但是在外部链接进程中调用该标识符时,通常前6个字符是有效的,如被多个文件共享的全局函数或变量。如果标识符不用于外部进程链接,通常前31个字符是有效的。
2.2.2 关键字
关键字是C++编译器内置的有特殊意义的标识符,用户不能定义与关键字相同的标识符。C++语言的关键字如表2.1所示。
表2.1 C++语言关键字
2.2.3 常量
常量,顾名思义,其值在运行时是不能改变的,但是在定义常量时可以设置初始值。在C++中,可以使用const关键字来定义一个常量。例如,下面的代码定义了一个MAX_VALUE常量。
对于常量,编译器会将其放置在一个只读的内存区域,其值不能被修改,但是可以应用在各种表达式中。如果用户试图修改常量,编译器将提示错误。
使用常量的最大好处是灵活。当程序中有多处需要使用一个常数值时,可以使用常量代替。当需要改动常数值时,只需要改动常量的值即可。此外,在定义函数时,如果在函数体中不需要修改参数值,建议将参数的类型定义为常量,这样当用户不小心在函数体内修改了参数值,编译器将提示错误信息。
2.2.4 变量
其值可以改变的量称为“变量”。变量提供了一个具有名称(变量名)的存储区域,使得开发人员可以通过名称来对存储区域进行读写。与常量不同的是,变量可以在程序中被随意赋值。对于每一个变量,都具有两个属性,也就是通常所说的左值和右值。所谓左值,是指变量的地址值,即存储变量值的内存地址。右值是指变量的数据值,即内存地址中存储的数据。
在程序中定义变量时,首先是变量的数据类型(2.3节将详细介绍),然后是变量名。如下面的代码定义了两个变量:
在定义变量时,可以对变量进行初始化,即为其设置初始值。例如,上面的代码定义了一个min整型变量,并将其初始化为0。在初始化变量时,可以将变量初始化为自身。例如:
这样做虽然是合法的,但也是“愚蠢”和不明智的。在初始化变量时,可以进行隐式初始化。例如:
当一条语句定义多个变量时,可以为多个变量同时指定初始值,并且后续变量可以利用之前变量作为初始值。例如:
说明
在用一条语句定义多个变量时,变量之间用逗号分隔,在最后一个变量定义结束后,以分号结束语句。
在定义变量时需要指定数据类型,对于C++内置的数据类型(2.3节将详细介绍)编译器会提供特殊的构造函数(第5章将详细介绍)。用户可以利用不同数据类型的构造函数来初始化变量。例如:
2.2.5 变量的存储类型
在C++语言中,变量通常有4种存储类型,分别为extern、static、register和auto,下面分别进行介绍。
1. extern存储类型
在介绍extern存储类型之前,先来澄清一个概念—变量的声明和定义。变量的声明是告知编译器变量的名称和数据类型;变量的定义将为变量分配存储区域。通常情况下,变量的声明也被认为是变量的定义,但是可以使用extern关键字只声明而不定义变量。例如:
那么只声明而不定义变量有何好处呢?通常应用程序可能包含许多文件,如果在一个文件中定义一个全局变量,可能需要在其他文件中进行访问,那么在其他文件中即可使用extern关键字只声明而不定义全局变量,extern关键字将告诉编译器变量的名称和类型,而变量的定义来源于前一个文件,这样即可在其他文件中共享全局变量。例如,在一个文件中定义一个整型的全局变量var。
而在另一个文件中通过使用extern关键字声明全局变量var,在该文件中即可访问全局变量var。
2. static存储类型
static存储类型表示变量在函数或文件内是“持久性”变量,通常也称之为静态变量。静态变量分为局部静态变量和全局静态变量。当使用static关键字标识一个局部变量(在函数内部定义的变量)时,该变量将被分派在一个持久的存储区域,当函数调用结束时,变量并不被释放,依然保留其值。当下一次调用函数时,将应用之前的变量值。这一点类似于全局变量,但是与全局变量不同的是,局部静态变量的作用域为当前的函数,它不能被外界函数或文件访问。可以认为局部静态变量是一个在函数调用后保留其值的局部变量。下面的代码演示了局部静态变量的作用。
【例2.1】 局部静态变量的作用。(实例位置:资源包\TM\sl\2\1)
说明
printf函数用于将格式化数据写入标准输出流。其语法格式如下:
int printf ( const char *format [, argument]... );
其中,format表示输出格式;argument表示要输出的变量,以逗号分隔变量。
执行上述代码,结果如图2.1所示。
上述代码3次调用了TestStaticVar函数,在每次函数调用结束后,局部静态变量slocal都将保留,并且对于局部静态变量只初始化一次,因此每次调用TestStaticVar函数输出的值都是不同的。
对于全局静态变量,其作用域仅限于当前定义的文件,不能够被其他文件使用extern关键字访问。可以认为全局静态变量只是半个全局变量(不能够被其他文件共享)。
图2.1 局部静态变量
3. register存储类型
在定义变量时,使用register关键字,表示变量将被放置在CPU的寄存器中。与普通变量不同的是,访问register变量要比访问普通变量快得多。register变量只能用于局部变量或作为函数的形式参数,而不能定义全局的register变量。如下面的代码定义了一个register变量。
4. auto存储类型
变量的存储方式主要有两种,即静态存储和动态存储。全局变量、静态变量均属于静态存储,而普通的局部变量属于动态存储。auto关键字表示变量将被动态存储。默认情况下的局部变量均属于auto变量(也被称为自动变量)。定义一个全局的auto变量是非法的,因为全局变量属于静态存储,与auto变量是相互冲突的。