词法记号
- 关键字
关键字是C++预先声明的单词,它们在程序中有不同的使用目的。下面列出C++中的关键字。
asm | auto | bool | break | case | catch | char |
---|---|---|---|---|---|---|
class | const | const_cast | continue | default | delete | do |
double | dynamic_cast | else | enum | explicit | export | extern |
false | float | for | friend | goto | if | inline |
int | long | mutable | namespace | new | operator | private |
protected | public | register | reinterpret_cast | return | short | signed |
sizeof | static | static_cast | struct | switch | template | this |
throw | true | try | typedef | typeid | typename | union |
unsigned | using | virtual | void | volatile | wchar_t | while |
- 标识符
标识符是程序员定义的单词,它命名程序正文中的一些实体,如函数名、变量名、类名、对象名等。C++标识符的构成规则如下。
- 以大写字母、小写字母或下划线(_)开始。
- 可以由大写字母、小写字母、下划线(_)或数字0~9组成。
- 大写字母和小写字母代表不同的标识符。
- 不能是C++关键字。
例如:Rectangle,Draw_line,_No1都是合法的标识符,而No.1,1st则是不合法的标识符。
- 操作符(运算符)
操作符是用于实现各种运算的符号,例如:+,-,*,/,… - 分隔符
分隔符用于分隔各个词法记号或程序正文,C++分隔符是( ) { } , : ;这些分隔符不表示任何实际的操作,仅用于构造程序。 - 注释
在C++中,有两种给出注释的方法。一种是沿用C语言的方法,使用“/*” 和“*/”括起注释文字(可以是多行注释)。另一种方法是使用“//”,从“//”开始,直到它所在行的行尾,所有字符都被称为注释处理。
基本数据类型和表达式
基本数据类型
类型名 | 长度(字节) | 取值范围 |
---|---|---|
bool | 1 | false,true |
char | 1 | -27~ (27 -1) |
signed char | 1 | -27~ (27 -1) |
unsigned char | 1 | 0~28 -1 |
(signed) short | 2 | -215~ (215 -1) |
unsigned short | 2 | 0~216 -1 |
(signed) int | 4 | -231~ (231 -1) |
unsigned int | 4 | 0~232 -1 |
(signed) long | 4 | -231~ (231 -1) |
unsigned long | 4 | 0~232 -1 |
(signed) long long | 8 | -263~ (263 -1) |
unsigned long long | 8 | 0~ (264 -1) |
float | 4 | 3.4×10-38~3.4×1038 |
double | 8 | 1.7×10-308~1.7×10308 |
long double | 16 | 我的编译器sizeof(long double)输出是16字节 |
细节:char与int,short,long有所不同,ISO C++标准并没有规定它在默认情况下是有符号的还是无符号的,它会因不同的编译环境而异。因此,char,signed char和unsigned char是3种不同的数据类型。
常量
所谓常量是指在程序运行的整个过程中其值始终不可改变的量,也就是直接使用符号(文字)标识的值。
- 整型常量
整型常量即以文字形式出现的整数,包括正整数、负整数和零。整型常量的表示形式有十进制[±]若干个0~9的数字、八进制0若干个0~7的数字和十六进制0x若干个0~9的数字及A~F的字母(大小写均可)。由于八进制和十六进制形式的整型常量一般用来表示无符号整数,所以前面不应带正负号。 - 实型常量
实型常量即以文字形式出现的实数,实数有两种表现形式:一般形式和指数形式。
一般形式:例如,12.5, -12.5等。
指数形式:例如,0.345E+2表示0.345×102, -34.4E-3表示-34.4×10-3。其中,字母E可以大写或小写。当以指数形式表现一个实数时,整数部分和小数部分可以省略其一,但不能都省略。例如: .123E-1, 12.E2, 1.E-3都是正确的,但不能写成E-3这种形式。
实型常量默认为double型,如果后缀F(或f)可以使其成为float型,例如:12.3f。 - 字符常量
字符常量是单引号括起来的一个字符,如:‘a’, ‘D’, ‘?’, ‘$’ 等。另外,C++提供一种称为转义序列的表示方法来表示无法通过键盘输入的不可显示字符,如下表。
字符常量形式 | 含义 |
---|---|
\a | 响铃 |
\n | 换行 |
\t | 水平制表符 |
\v | 垂直制表符 |
\b | 退格 |
\r | 回车 |
\f | 换页 |
\\ | 字符"\" |
\" | 双引号 |
\’ | 单引号 |
- 字符串常量
字符串常量简称字符串,是用一对双引号括起来的字符序列。例如:“abcd”,“This is a string.” 都是字符串常量。由于双引号是字符串的界限符,所以字符串中间的双引号就要用转义序列来表示。例如:
“Please enter \“Yes\” or \“no\””
表示的是下列文字:
Please enter “Yes” or “no”
字符串与字符是不同的,它在内存中的存放形式是:按串中字符的排列次序顺序存放,每个字符占一个字节,并在末尾添加 ‘\0’ 作为结尾标记。字符串 "a"的存储形式是a\0,字符 ‘a’ 的存储形式是a,两者不同。 - 布尔常量
布尔常量只有两个:false(假)和true(真)。
变量
在程序的执行过程中其值可以变化的量称为变量,变量是需要用名字来标识的。
- 变量的声明和定义
变量在使用之前需要首先声明其类型和名称。变量名也是一种标识符,因而给变量命名时,应该遵循标识符构成规则,在同一语句中可以声明同一类型的多个变量。变量声明语句的形式如下:
数据类型 变量名1,变量名2,…,变量名n;
在定义一个变量的同时,也可以给它赋予初值,而这实质上就是给对应的内存单元赋值,例如int a= 3;
在定义变量的同时赋初值还有另一种形式,例如int a(3);
- 变量的存储类型
auto存储类型:采用堆栈方式分配内存空间,属于暂时性存储,其存储空间可以被若干变量多次重复覆盖使用。
register存储类型:存放在通用寄存器中。
extern存储类型:在所有函数和程序段中都可引用。
static存储类型:在内存中是以固定地址存放的,在整个程序运行期间都有效。
符号常量
除了前面讲过的直接用文字表示常量外,也可以为常量命名,这就是符号常量。符号常量在使用之前一定要首先声明,且声明时一定要赋初值,在程序中间不能改变其值。符号常量声明语句的形式为:
const 数据类型说明符 常量名=常量值;
或数据类型说明符 const 常量名=常量值;
例如,可以声明一个代表圆周率的符号常量:const float PI=3.1415926;
使用符号常量,由于只在声明时赋予初值,修改起来十分简单,因而可以避免因修改常量值带来的不一致性。
运算符与表达式
- 算术运算符与算术表达式
C++中的算术运算符包括基本算术运算符和自增自减运算符。由算术运算符、操作数和括号构成的表达式称为算术表达式。
基本算术运算符有:+(加或正号)、-(减或负号)、*(乘)、/(除)、%(取余)。
“%”是取余运算,只能用于整型操作数,表达式a%b的结果是a被b除的余数。“%”的优先级与“/”相同。
当“/”用于两个整型数据相除时,其结果取商的整数部分,小数部分被自动舍弃。因此,表达式1/2的结果为0,这一点需要特别注意。
另外,C++中的++(自增)、–(自减)都是一元运算符。这两个运算符都有前置和后置两种使用形式,它们的作用都是将操作数的值增1(减1)后,重新写回该操作数在内存中原有的位置。但是,当自增、自减运算的结果要被用来参与其他操作时,前置与后置时的情况就完全不同了。例如,如果i的值为1,则下列两条语句的执行效果是不一样的:
cout<<i++; //首先使i自增为2,然后输出i自增前的值1
cout<<++i; //首先使i自增为2,然后输出i的当前值2
- 赋值运算符与赋值表达式
C++提供了几个赋值运算符,最简单的赋值运算符就是“=”。带有赋值运算符的表达式被称为赋值表达式。赋值表达式的作用就是将等号右边表达式的值赋给等号左边的对象。赋值表达式的类型为等号左边对象的类型,其结果值为等号左边对象被赋值后的值,运算的结合性为自右向左。
除了“=”以外,C++还提供了10种复合的赋值运算符:+=,-=,*=,/=,%=,<<=,>>=,&=,^=,|=。其中前5个是由赋值运算符与算术运算符复合而成的,后5个是赋值运算符与位运算符复合而成的。这10种复合后的赋值运算符都是二元运算符,优先级与“=”相同,结合性也是自右向左。例如:
a+=3 等价于 a=a+3
x*=y+8 等价于 x=x*(y+8)
a+=a-=a\*a 等价于 a=a+(a=a-a*a)
- 逗号运算和逗号表达式
在C++中,逗号也是一个运算符,它的使用形式为:表达式1,表达式2
求解顺序为先求解1,再求解2,最终结果为表达式2的值。
例如:a=3\*5,a*4 //最终结果为60
- 逻辑运算与逻辑表达式
在解决许多问题时都需要进行情况判断,对复杂的条件进行逻辑分析。C++提供了同于比较、判断的关系运算符和用于逻辑分析的逻辑运算符。
关系运算是比较简单的一种逻辑运算,关系运算符及其优先次序为:
<(小于),<=(小于或等于),>(大于),>=(大于或等于),==(等于),!=(不等于)
前四个运算符优先级相同(较高),后两个运算符优先级相同(较低)。
用关系运算符将两个表达式连接起来,就是关系表达式。关系表达式是一种最简单的逻辑表达式,其结果类型为bool,值只能为true或false。
若只有简单的关系比较是远不能满足编程需要的,我们还需要用逻辑运算符将简单的关系表达式连接起来,构成较复杂的逻辑表达式。逻辑表达式的结果类型为bool,值只能为true或false。C++中的逻辑运算符及其优先次序为:!(非) &&(与) ||(或)
优先级次序从左到右依次降低。
“!”是一元运算符,使用形式是:!操作数,作用是对操作数取反。
“&&”和“||”都是二元运算符。“&&”运算的作用是求两个操作数的逻辑“与”,只有当两个操作数的值都为true时,“与”运算结果才为true。其他情况下“与”运算结果均为false。“||”运算的作用是求两个操作数的逻辑“或”,只有当两个操作数的值都为false时,“或”运算结果才为false。其他情况下“或”运算结果均为true。
注意:“&&”和“||”运算符具有“短路”特性。这种特性是指:对于“&&”,运行时先对第一个操作数求值,如果其值为false,则不再对第二个操作数求值,因为这时无论第二个操作数的值是多少,“&&”表达式的值都是false;类似地,对于“||”,运行时先对第一个操作数求值,如果其值为true,则不再对第二个操作数求值。 - 条件运算符与条件表达式
C++中唯一的一个三元运算符是条件运算符“?”,它能够实现简单的选择功能。条件表达式的形式是:
表达式1? 表达式2: 表达式3
其中表达式1必须是bool类型,表达式2,3可以是任何类型,且类型可以不同。
条件表达式的执行顺序为:先求解表达式1。若表达式1的值为true,则求解表达式2,表达式2的值为最终结果;若表达式1的值为false,则求解表达式3,表达式3的值为最终结果。
注意,条件运算符优先级高于赋值运算符,低于逻辑运算符。 - sizeof运算符
sizeof运算符用于计算某种类型的对象在内存中所占的字节数。 该操作符使用的语法形式为:
sizeof(类型名)
或sizeof 表达式
运算结果值为“类型名”所指定的类型或“表达式”的结果类型所占的字节数。 - 位运算
在C++中提供了6个位运算符,可以对整数进行位操作。
(1)按位与(&)
按位与操作的作用是将两个操作数对应的每一位分别进行逻辑与操作。使用按位与操作可以将操作数中的若干位置0(其他位不变);或者取操作数中的若干指定位。例如:
①下列语句将char型变量a的最低位置0:a=a & 0xfe;
②假设有char c;int a;下列语句取出a的低字节,置于c中:c=a & 0xff;
(2)按位或(|)
按位或操作的作用是将两个操作数对应的每一位分别进行逻辑或操作。
使用按位或操作可以将操作数中的若干位置1(其他位不变)。例如:
将int型变量a的低字节置1:a=a | 0xff;
(3)按位异或(^)
按位异或操作的作用是将两个操作数对应的每一个位进行异或,具体运算规则是:若对应位相同,则该位的运算结果为0;若对应位不同,则该位的运算结果为1。
使用按位异或操作可以将操作数中的若干指定位翻转。如果使某位与0异或,结果是该位的原值。如果使某位与1异或,则结果与该位原来的值相反。例如:要使01111010低4位翻转,可以与00001111进行异或。
(4)按位取反(~)
按位取反是一个单目运算符,其作用是对一个二进制数的每一位取反。
(5)移位
C++中有两个移位运算符,左移运算(<<)和右移运算(>>),都是二元运算符。移位运算符左边的操作数是需要移位的数值,右边的操作数是左移或右移的位数。
左移是按照指定的位数将一个数的二进制向左移位。左移后,低位补0,溢出的高位舍弃。
右移是按照指定的位数将一个数的二进制值向右移位。右移后,溢出的低位舍弃。如果是无符号数则高位补0;如果是有符号数,则高位补符号位。 - 混合运算时数据类型的转换
(1)隐含转换
在算术运算和关系运算中如果参与运算的操作数类型不一致,编译系统会自动对数据进行转换(即隐含转换)。转换的基本原则是将低类型数据转换为高类型数据 。各种类型的高低顺序如下,从左向右依次增高:
char short int unsigned int long unsigned long float double
(2)显式转换
显示类型转换的作用是将表达式的结果类型转换为另一种指定的类型。
在标准C++之前,显示类型转换语法形式有两种:类型说明符(表达式)
或(类型说明符)表达式
,这两种写法只是形式上有所不同,功能完全相同。
标准C++又定义了4种类型转换操作符:static_cast,dynamic_cast,const_cast和reinterpret_cast,语法形式如下:
const_cast<类型说明符>(表达式)
dynamic_cast<类型说明符>(表达式)
reinterpret_cast<类型说明符>(表达式)
static_cast<类型说明符>(表达式)
由于目前掌握的知识有限,无法分析透彻,具体用法将在后续内容中陆续介绍。