变量声明、定义、初始化、赋值小结

来源:互联网 发布:网上邻居输入网络凭证 编辑:程序博客网 时间:2024/06/05 23:41

几个名词:

声明:可以称为“描述”,是告诉编译器有这么一个符号,这个变量符号是个什么类型,整形?还是浮点?等等

定义:就是分配内存,并且初始化(即使是系统填充的,如局部变量0xcccccccc,也可以称为初始化,暂叫做广义初始化吧)

初始化:顾名思义,初始化是从无到有,所以初始化必然和分配内存联为一体的,只不过我们叫的初始化是狭义初始化,即用户在定义的时候指定初值才叫初始化。(事实上在定义的时候即使不指定初值,系统也会填充一些值的,可能为0,可能为随机值,也可能如VC中0xcccccccc)

赋值:在分配内存之后对该内存的值进行修改

 

几个原则:

(1)在作用域内,同一个变量可以声明多次,但只能定义一次(伴随着定义相应的初始化也只能一次,要么是广义初始化,要么是(狭义)初始化),并可以赋值多次

(2)关于变量声明,声明只是表明有这么一个东西,如果不去使用它,无视它的存在,那么编译链接运行都不会报错。成员函数的声明定义另说。

几个联系:

(1)在C++中,extern int i是纯粹声明,int i是声明加定义加广义初始化三者的结合体,int i=0是声明加定义加(狭义)初始化的结合体,extern int i=0也是声明加定义加(狭义)初始化的结合体,后两者效果一样

(2)严格来说,不存在纯粹的定义和初始化(当然这根据不同的解释说法不同,毕竟声明可以多次,定义的时候不也是声明么)。

(3)既然int i是声明定义初始化三者结合体,为什么还要声明。从原则(1)可以看出,独立声明是原则(1)的前提,因为编译时是以翻译单元tu为单位进行独立编译的,如果多个源文件需要同一个i,直接使用又不认识它,那么只需要在各个源文件中使用i之前告诉一下编译器,有i这个东东即可(extern int i),在链接阶段各个obj自然会知道对方的i实际信息的

 

几个纠正:

(1)int i放在头文件是声明,放在源文件是定义。这句话就是错的,int i放在哪里都是声明定义广义初始化三合体,如果该头文件被多个源文件包含,链接肯定会出错。(加个const就没事了?另述)

(2)如果变量i被多个其他源文件使用,应把extern int i放在头文件中去,然后在自己源文件中int i。根据原则(2)这个是对的,但能不这样做就不建议这样做,因为不灵活,并且随便对头文件添加东西绝不是一件好方法,哪个源文件使用i,在那个源文件中extern int i独立声明,如果该源文件只有某个函数需要i,可在该函数内extern int i(虽然这样做函数外面依然不能自定义i,但对代码自注释有一定帮助)

 

本来声明定义在使用内建类型定义变量的时候理解不难,但加上自定义类型后,又多了一个实例化名词,和声明定义混在一起,很是头疼。

现在隐隐约约感觉到,在使用内建类型定义变量的时候,“定义”这个词是不准确的,更统一一般的说法是“实例化了一个整形变量”,虽然有点怪怪的,但这样才好和类声明定义实例化统一起来,也就是说,对于int这种内建类型,“定义”这个词应该代表的意思是“指定int这种类型是4个/8个字节“,而不是在内存中又分配了一个实例变量i。不知道想的对不对

因此,先随便写几句所谓的”感觉“以便下次能够快速回想起来这次的想法:

(1)内建类型分配内存,只有”声明“,”实例化“,而”定义“应该是编译器或者C98做好的事情。如int i;

(2)自定义类型分配内存,有”声明“,”定义“,”实例化“。如class A{......} A a;

(3)函数,有”声明“,”定义“,但没有”实例化“,因为函数不会在数据区分配内存。void fun(int i); void fun(int i){......}

所以回归最开始的语文词义和顺序,声明=”有这么一个东西“;定义=”详细描述“;实例化=”分配内存,产生一个变量或对象“。

未完待续中......

原创粉丝点击