3.2 认识常量
在一段程序运行过程中,始终不发生改变的量,称之为常量。在C++语言中常量是个固定值,也就是说常量值在定义后不能进行修改。
3.2.1 什么是常量
在一些C++程序中,会见到以下类似的语句:
int a=5; char c='X';
这段语句中,“5”和“X”就是常量,在程序执行期间不会改变。为了解常量,下面看一个简单的例子。
【例3-1】编写程序,输出几个常量。
(1)在Visual Studio 2017中,新建名称为“3-1.cpp”的Project1文件。
(2)在代码编辑区域输入以下代码。
【程序分析】在本例中有5个常量,分别是字符串“How do you do?”、69、3.4、字符“'Y'”和字符串“Lets go to school”,它们在程序运行过程中就是最初输入时的数值,不会发生变化,输出时是原样输出。
在Visual Studio 2017中的运行结果如图3-1所示。
图3-1 常量
3.2.2 数值常量
数值常量就是通常所说的常数。在C++中,数值常量是区分类型的,从字面形式即可识别其类型。数值常量数据可以是正数,如33、8、0.68等,也可以是负数,如-5、-89、-98.76等,当然也可以是0。如果是负数,一定要带上符号“-”;如果是正数,可以不带符号“+”,当然也可以带上符号“+”。
1. 整型常量(整数)的类型
在C++语言中,整型数据即为整数,是不包含小数部分的数值型数据,以二进制形式进行存储。整型数据可分为有符号基本整型、无符号基本整型、有符号短整型、无符号短整型、有符号长整型以及无符号长整型。
例如:
注意:方括号中的关键字可以省略,例如[signed] int可以写成int。
整数常量也可以带一个后缀,后缀是U和L的组合,U表示无符号整数(unsigned),L表示长整数(long)。后缀可以是大写,也可以是小写,U和L的顺序任意。
【例3-2】编写程序,输出几个整型常量。
(1)在Visual Studio 2017中,新建名称为“3-2.cpp”的Project2文件。
(2)在代码编辑区域输入以下代码。
【程序分析】本例输出4个带后缀的整数常量以及每个常量的类型。
注意:不能重复后缀,例如:
032UU /*非法的*/
在Visual Studio 2017中的运行结果如图3-2所示。
图3-2 整数常量
整数常量可以是十进制、八进制或十六进制的常量。前缀指定基数:0x或0X表示十六进制,0表示八进制,不带前缀则默认表示十进制。
【例3-3】编写程序,输出几个整型常量。
(1)在Visual Studio 2017中,新建名称为“3-3.cpp”的Project3文件。
(2)在代码编辑区域输入以下代码。
【程序分析】本例输出一个十进制的85,八进制的0213,十六进制的0x4b和0XFeel。
注意:八进制数是逢八进一,所以在数据中不能有8,例如:
078 //非法的:8不是八进制的数字
在Visual Studio 2017中的运行结果如图3-3所示。
图3-3 整数常量
2. 浮点数类型的常量
浮点常量由整数部分、小数点、小数部分和指数部分组成。可以使用小数形式或者指数形式来表示浮点常量。
(1)十进制小数形式。
当使用小数形式表示时,必须包含整数部分、小数部分,或同时包含两者。
例如:
21.456 -7.98
C++编译系统把用这种形式表示的浮点数一律按双精度常量处理,在内存中占8字节。如果在实数的数字之后加字母F或f,表示此数为单精度浮点数,如1234F、-43f,占4字节。如果加字母L或l,表示此数为长双精度数(long double),在Visual Studio 2017中占8字节。
(2)指数形式。
一个浮点数可以写成指数形式,如6.28745可以表示为0.628745*101、6.28745*100等形式。在程序中应表示为:0.628745e1、6.28745e0、62.8745e-1、628.745e-2,用字母e或E表示其后的数是以10为底的幂,如e12表示10的12次方。
【例3-4】编写程序,输出浮点类型的常量。
(1)在Visual Studio 2017中,新建名称为“3-4.cpp”的Project4文件。
(2)在代码编辑区域输入以下代码。
【程序分析】本例中输出了三个浮点型的数值常量。第5行表示输出正实数53.21,第6行表示输出负实数-98.76,第7行表示输出正实数6.28745。
在Visual Studio 2017中的运行结果如图3-4所示。
图3-4 输出浮点型的常量
3.2.3 字符常量
字符常量就是把一个字符用单引号括起来。其中引号的作用是将字符与其他部分的分隔开来,并不是字符的一部分。
1. 普通的字符常量
用单引号括起来的一个字符就是字符型常量。如'x'、'&'、'5'、'Y'都是合法的字符常量,在内存中占1字节。
注意:
(1)字符常量只能包括一个字符,如'AB'是不合法的。
(2)字符常量区分大小写字母,如'X'和'x'是两个不同的字符常量。
(3)单引号“'”是定界符,而不属于字符常量的一部分。如cout<<'a';输出的是一个字母“a”,而不是3个字符“'a'”。
2. 转义字符常量
对于不可显示的或无法从键盘输入的字符,如回车符、换行符、制表符、响铃、退格等;另外,还有几个具有特殊含义的字符,如反斜杠、单引号和双引号等,C++提供了一种转义字符来表示。
例如,'\n'代表一个“换行符”。“cout<<'\n';”将输出一个换行,其作用与“cout<<endl;”相同。这种“控制字符”在屏幕上是不能显示的。在程序中也无法用一个一般形式的字符表示,只能采用特殊形式来表示。常用的转义字符见表3-2。
表3-2 常见转义字符表
3. 字符数据在内存中的存储形式及其使用方法
将一个字符常量存放到内存单元时,实际上并不是把该字符本身放到内存单元中去,而是将该字符相应的ASCII代码放到存储单元中。如果字符变量C1的值为'a',C2的值为'b',则在变量中存放的是'a'的ASCII码97,'b'的ASCII码98,如图3-5(a)所示,实际上在内存中是以二进制形式存放的,如图3-5(b)所示。
图3-5 字符数据在内存中的存储形式
既然字符数据是以ASCII码存储的,它的存储形式就与整数的存储形式类似。这样,在C++中字符型数据和整型数据之间就可以通用。一个字符数据可以赋给一个整型变量,反之,一个整型数据也可以赋给一个字符变量。也可以对字符数据进行算术运算,此时相当于对它们的ASCII码进行算术运算。
【例3-5】编写程序,字符变量与整型变量之间的转换。
(1)在Visual Studio 2017中,新建名称为“3-5.cpp”的Project5文件。
(2)在代码编辑区域输入以下代码。
【程序分析】本例中首先定义两个整型变量i和j,然后将字符型常量X与Y赋值给i和j。
第8行输出88和89,第9行输出字符A,第10行用转义形式输出ASCII码为十六进制表示的大小为42的字符,就是B,第12行用转义形式输出ASCII码为八进制数表示的大小为103的字符,就是C。
在Visual Studio 2017中的运行结果如图3-6所示。
图3-6 字符变量与整型变量之间的转换
3.2.4 字符串常量
C++的字符串常量是用双引号括起来的字符序列,也就是用双撇号括起来的部分。如"abc"、"Hello!"、"a+b"、"Happy Birthday"都是字符串常量。字符串常量"abc"在内存中占4字节(而不是3字节),如图3-7所示。
图3-7 字符串常量在内存中的存储大小
编译系统会在字符串最后自动加一个'\0'作为字符串结束标志。但'\0'并不是字符串的一部分,它只作为字符串的结束标志。字符串常量与字符常量除了所使用的引号不同以外,最重要的区别是存储形式不同。系统会在字符串的末尾自动添加1个空字符'\0',作为字符串的结束符,所以每个字符串的存储长度总是比其实际长度(字符个数)多1。
由双引号" "括起来的字符序列中的字符个数称为字符串的长度,字符串结束符'\0'并不计算在字符串的长度里(在定义字符串常量时,这个结束符不需要给出,C++语言会自动加上,但是存储时,空字符将会额外地占用1字节空间)。比较容易出错的是当字符串中出现转义字符时字符串长度的确定。
转义字符从形式上看是多个字符,而实际中它只代表一个字符,因此在计算字符串的长度时容易将它看成多个字符计入长度中。在控制台C++程序中为了使人机交互友好,一般会输出一些字符串常量起提示作用。
【例3-6】编写程序,计算三个数相乘的结果。
(1)在Visual Studio 2017中,新建名称为“3-6.cpp”的Project6文件。
(2)在代码编辑区域输入以下代码。
【程序分析】在代码中首先定义了4个变量x、y、z、m。然后使用cin给变量x、y、z赋值,通过公式“m=x*y*z;”。到第8行是将3个数相乘的结果赋值给m。第9行又是输出一个提示字符串,字符串中的第1个字符是一个转义字符换行,要不输出结果会与输入行紧连在一起。第11行输出3个数的乘积。
在Visual Studio 2017中的运行结果如图3-8所示。
图3-8 三个数的乘积
3.2.5 符号常量
为了能够方便阅读代码,在C++程序设计中,常用一个符号名代表一个常量,称为符号常量。即以标识符形式出现的常量,也就是分配一个符号给这个常量,在以后的引用中,这个符号就代表了实际的常量,即带名字的常量。
在C++语言中允许将程序中的常量定义为一个标识符,这个标识符称为符号常量。符号常量必须在使用前先定义,定义的格式为:
#define 符号常量 常量
该语句中,符号常量定义命令一般要放在主函数main()之前。
#define PRICE 30
上述意思是用符号PRICE代替30。在编译之前,系统会自动把所有的PRICE替换成30,也就是说编译运行时系统中只有30而没有符号。
【例3-7】编写程序,符号常量。
(1)在Visual Studio 2017中,新建名称为“3-7.cpp”的Project7文件。
(2)在代码编辑区域输入以下代码。
【程序分析】在代码中使用预处理命令#define指定PRICE在本程序单位中代表常量30,此后凡在本程序单位中出现的PRICE都代表30,可以和常量一样进行运算。请注意符号常量虽然有名字,但它不是变量。它的值在其作用域(在本例中为主函数)内是不能改变的,也不能被赋值。如用赋值语句“"PRICE=40;"”给PRICE赋值是错误的。使用符号常量的好处是含义清楚,在需要改变一个常量时能做到“一改全改”。
在Visual Studio 2017中的运行结果如图3-9所示。
图3-9 符号常量
符号常量的特点如下:
(1)符号常量不同于变量,它的值在其作用域内不能改变,也不能被赋值。
(2)习惯上,符号常量名用大写英文标识符,而变量名用小写英文标识符,以示区别。
(3)定义符号常量的目的是为了提高程序的可读性,便于程序的调试和修改。因此在定义符号常量名时,应尽量使其表达它所代表的常量的含义。
(4)对程序中用双引号括起来的字符串,即使与符号一样,预处理时也不做替换。