对编译顺序的理解,特别是预编译指令
编译器对于cpp文件的编译永远都是从整个文件的第一行开始编译,对于预编译指令也都是一条一条的执行,而不会说编译器会选择所有的预编译指令先执行,然后再一条一条编译。所有的预编译指令的作用域同其他C++语句一样(即按照是局部定义的还是全局定义的,也都是从该条语句开始,到生命周期结束)。只不过预编译指令具有一些特殊能力,比如对于宏定义的常量,拥有直接将其所定义位置开始,至文件结束(
注意是文件结束,即使是定义在一个函数中也是如此,因为宏定义具有跳出函数作用域的能力
)中所有用到该宏定义常量的地方替换成相应数值的能力。但是如果在后面每个位置又重复宏定义了该常量,同样会替换,不过此时其作用范围也是从它所定义的位置开始,至文件结束,这样它影响不了前面一个宏定义所在位置到该宏定义位置之间的常量值。
对编译单元,各种变量、函数编译的理解
一个cpp文件编译生成一个编译单元(.obj文件),一个编译单元=一个大仓库。一个编译单元里面有局部变量和全局变量(都是相对于这一个编译单元来说的)。除非各cpp文件互相include引用,各编译单元中的变量名、常量名互不影响,即这个仓库有什么和那个仓库有什么,即使名字一样也是是可以区分的。但函数不行,因为在链接阶段,一个编译单元用到了什么函数,会在所有编译单元中寻找该函数的定义,如果在不同cpp文件中重复定义了该函数,则会出现链接错误。如果将整个C++项目比作一个大工厂,工厂中有很多个仓库(即很多cpp文件),此时函数给我们的感觉就是工厂中拥有一个独一无二的大箱子,这个箱子可以在这个仓库中,也可以放在另一个仓库中,在链接的时候,那个仓库申请说用到了这个大箱子,此时只要在工厂中不同的仓库里去找这个大箱子就行。如果想要链接器同样对于一个编译单元中的变量值也去其他所有编译单元中去寻找该变量的定义,可以在该编译单元中声明该变量为extern,这样链接时就会去其他编译单元中寻找该变量的定义了,不过这样的话就要保证该变量名在其他不同编译单元中定义的唯一性。
同一个编译单元中变量、函数等可以重复声明,但不可以重复定义,注意宏是可以重复定义的,编译时按先后顺序,以位置靠后的宏定义为准。
变量的初始化
变量声明后,编译时就会给该变量分配内存空间,如果该变量在声明的时候没有赋初值的话,系统就会给定一个随机值,此时如果后面及时的给该变量又赋予数值的话还好,否则
的话如果不进行初始化,后面又直接读取了该变量的值的话,就有可能导致程序运行结果出错。
所以虽然变量的初始化工作不是必须的,但是建议对程序中的每个变量进行初始化。
对指针的一些理解
时刻记得,指针变量自身的值是地址,
只不过该地址指向了一些内存区域;正因为指针变量是一个地址,所以时刻记得要用地址值来给指针变量赋值,比如可用取地址运算符&获得一些变量的地址之后赋值给指针。
指针作为一个变量,也有自己的内存地址,其实每一个数据量都有自己的内存地址和存储的数据值,只不过指针变量存储的数据值也是一个内存地址。
对于输入输出流对象中插入符"<<"和提取符">>"的理解——方便记忆
注意此处要将程序作为本体,输入和输出都是相对于程序而言的,数据从外部到程序称为输入,数据从程序中产生到外部称为输出,一般通过cin和cout对象来分别控制输入和输出流。 可以将cin和cout理解为程序与外部数据交流的媒介,外部的数据都是存在于该媒介上(
统一将>>和<<两个操作符的左边都视作外部数据,右边视作程序中存储数据的变量或者程序中产生的数据
),如果想要从该媒介中提取出数据输入到程序中,则借用cin对象将数据>>(输入)到程序中;如果想要从程序中输出数据到程序中,则借用cout对象将数据<<(插入)到外部(如显示器)中。