第三章 常量与变量、代码文件后缀名

一 常量

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)字符串字面值     

        以双引号括起来的零个或多个字符的常量值,其中也可包括不可打印的字符。
       同时,为了兼容C语言,其所有字符串字面值都会由编译器自动添加一个空字符('\0'),比如“A”实际上就是'A'和'\0'两个字符的合集,而“”也是表示了'\0',下面来看看例子:
        "Hello World!"
        "大家好!"
        ""
        "\nhello\tfile\n"
        另外,字符串的存储也有宽字符串字面值,在内存中的存储是以整型存储(wchar_t与字符的编码方式是不同的概念,以后详细说明编码问题),同样是在前面加L(大写),如:
        L"a wide string!"
        这是一串常量宽字符,以宽空字符结束。

二 变量

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关键字进行声明,也可以光声明变量名而不定义它,但是程序内却不能使用它,否则编译会报错。例如:
        extern int i;
        不过,如果在声明中赋了值,例如:
        extern int i = 20;
        在这里,声明就转变成了定义,程序中也就可以使用它了,不过如果再进行同名定义就会编译报错了。
        

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其实质就是文字替换,所以甚至可以将常量名完全替换成某段代码,这时要注意使用之前提到的换行符\了。


猜你喜欢

转载自blog.csdn.net/rsp19801226/article/details/80700394