一 常量
1. 字面值常量
(1)整型字面值
整数字面值常量可以使用三种进制表示:十进制,八进制,十六进制,当然这些进制是不会改变其内存中的二进制值的。其中八进制以零(0)开头,十六进制以0x或0X开头。
例如,30这个数,分别表示成十进制,八进制,十六进制即是:
30 //十进制
036 //八进制
0x1e //十六进制(不区分大小写)
由上一章可知,整型按照其内存存储位数又分为unsigned,int,long型等分类,那么一个数字到底是分配到什么型呢?
首先,假如你的数字只是单纯的数字,并未加任何后缀,就像上面的那个数字,那么它的默认类型则是int类型,但是如果数字范围超过了int型,那么其默认类型就会是long型了。
其次,还要一种方式让你可以指定类型,一种是指定为unsigned类型,就是在数值后面添加U(不区分大小写),另一种就是指定为long型,即是在数值后添加L(同样不区分大小写),两种也可以组合,比如10UL,表示unsigned long型,U和L的组合顺序以及大小写都可随意,表示这个值是以该类型进行存储,而非默认的int型。
注意,在这里,没有short型的字面值常量。
(2)浮点型字面值
通常用十进制或是科学计数法表示浮点型字面值,使用科学计数法时,用E(不区分大小写)来表示底数10,指数部分用十进制,其中默认的浮点字面值为double型。如果想要使用float型,则需要在数值后面加上F(不区分大小写)来表示单精度,同样的,扩展精度型则需要在数值后面添加L(不区分大小写),如下:
6.15f(float 6.15) .001f (float 0.001) -1. (double -1) 7.54e0 (double 7.54e+0=7.54)
8.44e-3f(float 8.44e-3=0.00844) 1.23e1L(long double 1.23e+1=12.3) 0e0(double 0)
3.5e40f(超出float范围,编译时报警告,运行时直接打印出inf)
(3)布尔字面值
一共就两个值,true和false,但是布尔变量除了可赋值为布尔字面值外,还可以以非零值为true,零值为false。
(4)字符字面值
用单引号定义单个字符,都是char型,在字符前面加L(注意大写)就能够得到wchar_t类型的宽字符字面值。比如:
‘a’ ‘3’ ‘ ’ ‘,’ L'a'
注意:如果单引号内是一个中文字符,编译会报错的,不过如果在前面加一个L就没问题了,只是打印的时候,会变成了数字。
有些字符是不可打印的,比如退格符,控制符等,还有一些在C++中特殊的符号,比如单引号,双引号,反斜线符号等,这些字符都需要用到转义字符,C++中的转义字符都以反斜线符号开始(要区分大小写,非中文字符),如下:
换行符 \n 水平制表符 \t
纵向制表符 \v 退格符 \b
回车符 \r 进纸符 \f
报警(响铃)符 \a 反斜线 \\
疑问号 \? 单引号 \'
双引号 \"
另外我们可以将任何字符以三个八进制数字表示,这三个数字是字符的数字值,下面用ASCII码字符集表示字面值常量:
\7 (响铃符) \12 (换行符) \40 (空格符)
\0 (空字符) \062 ('2') \115 ('M')
其中的'\0'空字符有很特殊的意义,以后会使用到。
当然也可以用十六进制来表示,不同的是,八进制的数字前以0开头,而十六进制则是以x开头,与之前的描述相同。
(5)字符串字面值
二 变量
1. 什么是变量
程序提供的有名字的可操作存储区,就是变量,也可被称为“对象”(object)。C++中,每个变量都必须先指定特定的类型,该类型决定了变量的内存大小、布局、取值范围以及可应用在该变量上的操作集合。例如,int,long,float等。
变量的值通常是可以改变的。
2. 变量名
(1)规则
变量名,顾名思义就是变量的名称,即变量的标识符,可以由字母,数字和下划线组成,其开头必须以字母或下划线开头,并且大小写敏感,也就是说区分大小写。
注意,C++中保留了一些特殊的词组作为关键字,这些关键字也不能用作程序的标识符。另外,还有些词是用作各种操作符的替代名,这些替代名用于支持某些不支持标准C++操作符号集的字符集,也不能被用作标识符。如图1:
除了以上这些关键字外,还保留了一组标识符用于标准库。为了避免与那些标准库的标识符重合,应避免使用下面这些特殊的标识符。比如,不能包含两个连续的下划线,也不能以下划线开头,紧跟着一个大写字母,甚至有些标识符(在函数外定义的标识符)不能以下划线开头。
(2)命名习惯
变量名,最好以某种约定俗成的固定方式进行编写,这样可以提高程序的可读性(不同的语言,习惯也许有所不同,但最重要的只要是一致且易懂即可)。
- 变量名一般用小写字母,例如,index,而不写成Index或者INDEX;
- 标识符应使用便于记忆的名字,例如,salary;
- 如包含多个词的标识符,在每个词之间添加下划线,或者采用小驼峰命名方式,即,除首字母小写外,其他单词首字母大写等等;
- 区分开局部变量,全局变量,成员变量等类型,以求一目了然;
3. 变量的定义与声明
(1)定义
变量的定义用于为变量分配存储空间,还可以为变量指定初始值,在一个程序里,变量有且只有一个定义,采用语句(程序中以分号结尾的可执行单位)的方式进行定义,例如:
int a = 1;
float b;
double c = 3.4, d;
其中有三组定义,第一组定义了一个int整型的变量a,赋初始值为1;第二组定义了一个float单精度浮点型的变量b,没有赋初始值,那么如果是全局变量,默认为0.0,如果是局部变量则有可能是一个随机的数值;第三组则分别定义了一个double双精度浮点型的变量c,初值为3.4,和另一个双精度浮点型的变量d,其初值也是由其作用域(也即是作用的范围,以后详细介绍)而定的。
由上可知,在定义一个变量后,最好将它赋上初值,如果暂时没有确定其值,最好也赋值为0(特别是对于以后所学的指针而言),否则有可能它会是一个错乱的数据,当然有些编译器可能会帮你将它赋初值为0,但这却不是你侥幸不赋初值的理由。
总结起来有以下几点:
- 多个变量的定义用逗号分开;
- 都采用类型+至少一个空格+变量名(一个或多个变量名)+分号的形式定义变量;
- 内置类型赋初始值采用等号+数值的方式置于变量名后,其他较为复杂的类型赋初值的方式,以后用到时再提。
(2)声明
用于向程序表明变量的类型和名字,定义其实也可以作为一种声明,使用extern关键字进行声明,也可以光声明变量名而不定义它,但是程序内却不能使用它,否则编译会报错。例如:4. 变量的初始化与赋值
变量就是一段程序可使用的内存区域,而初始化,就是在定义变量的时候,便将指定值赋给它,例如:
int i = 20;
方式就是使用=号连接变量与数值,其间空格数不限,不过如果提行,那么就需要用到换行符\了。(换行符必须是头一行的最后一个字符,连接的是从下一行的第一个字符开始,所以这里特别要注意了,有些会不自觉地添加了tab键或者空格,如果是一个单词或数据内的话,可能会出错。)
而在定义之后,我们也可以赋值给变量,这时就不能带上类型符号了,例如:
int i;
i = 20;
这与之前赋初值的最终效果一致。而赋值的次数是不受限制的,最终结果以最后一次赋的值为准,不过,这种方式与直接初始化相比,步骤会多了一步,特别是对于以后的复杂变量,因此,如果有必要最好一步完成,减少不必要的程序开支。
三 代码文件后缀名
提到文件大家都知道,文件有名字和后缀名,不同的应用程序一般使用特定的后缀名文件,例如office的word可以打开后缀名为doc,docx等的文件,C++编译器也是以文件为单位来进行编译的,其中,编译器可识别的文件又分为头文件和源文件两大类。
一般来说,声明和接口都放在头文件中,而实现则放在源文件中,这么区分的主要用途,一是为了程序的易读性,二则是为了程序的保密性,其中头文件是方便众人阅读的,而源文件则是可以隐藏其内容的。
1. 头文件
以h为后缀名的文件。
2. 源文件
以cpp,cxx,cc,cp,c为后缀名的文件,其中c是C语言的源文件,而C++本就是由C语言发展出来的,基本的语法都是一致的,除了扩展出来的面向对象的部分,还有一些细微的差别,但是c++编译器,也是可以自动根据其后缀名,识别出c语言源文件,自动调用c编译器进行编译的。
而c++的源文件由你使用的编译器决定可识别的后缀名,一般是cpp。
C++语言中一般以文件为单位,头文件与源文件多为成对出现(名字相同),既方便程序查阅,又方便程序维护。
而源文件要使用其他文件,则需要使用include的方式(多include头文件,避免重复的问题),#include号是预编译命令,也就是在编译之前先对文件进行的处理命令,它相当于将文件内容拷贝到该文件的include处,因此,在这里,为了避免重复的问题,就需要在头文件中使用另一组预编译命令了,具体细看下面的define。
关于include的使用,它可以采用两种符号来包含头文件,一种是双引号,另一种则是使用尖括号的方式。
- 双引号
使用方式:#include "xxx.h",其中xxx为文件名,例如,stdio。
- 尖括号
使用方式:#include <xxx.h>,其中xxx也是文件名。
其中双引号用于引用非标准库文件,编译器从用户目录开始搜索文件(用户可以设置用户目录,否则使用默认的用户目录),如果未找到该文件,则会从标准库目录再次搜索,如果未找到,则会报错;而尖括号则用于标准库文件,编译器自标准库目录开始搜索文件(也可以设置标准库路径),如果未找到,则会报错。
也就是说,标准库的文件,其实也可以用双引号,但是效率会更低。
四 const与define定义的常量
得知了什么是变量和常量,这里再来提两种特殊的采用变量名的自定义常量。
1. const
在定义变量时,添加一个const,则该变量的值不能再被改变,因此在定义时应该初始化该值(此处const是修饰的一般的内置类型,以后需要修饰其他类型时,会再详细描写),定义的方式只有两种,即不论放在类型前后皆可。例如:
const int INDEX = 6;
int const INDEX = 6;
不过因为const定义的是常量,我们通常习惯使用大写字母作为其名,与普通变量以示区别。
2. define
预编译命令,有定义常量的作用,其实质是在编译前,将前者完全替换成后者,使用方式是:
#define 常量名 常量值
也就是说编译前,将编写的代码中,变量名与常量名相等的地方,全部替换为常量值。这也就会出现一个问题,如下:
#define index 4 + 5
在代码中某处为:
int result = 4 * index;
这里原意是想变成:
int result = 4 * (4 + 5);
可是被替换后却变成了:
int result = 4 * 4 + 5;
也就是说,它被替换时,只管其文字被替换,而不会留意其他,因此,在使用define时,最好在常量值那里添加一个括号,即:
#define index (4 + 5)
另外,define其实质就是文字替换,所以甚至可以将常量名完全替换成某段代码,这时要注意使用之前提到的换行符\了。