C++中变量,函数的作用域和生命周期?

来源:互联网 发布:知网检测数据库 编辑:程序博客网 时间:2024/03/29 17:09

编程中需要深刻理解的最基础的东西就是:

1、变量的作用域和生命周期;

2、函数的作用域和生命周期;


C++程序执行时,内存块的划分。

1、栈区:编译器自动分配内存,回收内存。存放函数参数值,局部变量值。操作方式类似于数据结构中的栈。它不是数据结构中的栈,是因为数据结构中的栈是一个数据类型,它存储一些数据之后,然后就放入到了内存块的栈区,或者堆区等。


2、堆区:通常由程序员分配内存,程序员释放内存。它分配内存的方式类似于链表,和数据结构中堆不同(数据结构中的堆是完全二叉树,满足一定规则,分为大顶堆和小顶堆)。为什么是通常,(因为java中的堆的内存释放是又垃圾回收器完成的)。暂时说这么多,因为这里是为了澄清一些内容的概念。


3、全局区(静态区):编译器编译时分配内存,程序中的全局变量和静态变量就存储在这里面。(二者未初始化时放在相邻的区域,初始化后放在同一块区域)。它的内存由系统释放。而且存在于程序运行期间的始终。


4、文字常量区:存储常量字符串。有人说const修饰的常量存储在哪个区,是不是在常量区,const只是起修饰作用,在函数体外的就是存储在全局区,在函数体内的就是存储在栈区,const static修饰的,在函数体内,也是存储在全局区。(我自己认为)。释放由系统。


5、代码区:不解释,没必要解释。


全局变量的作用作用域:

在一个文件中:

在定义全局变量的开始,到文件结尾处。

在其他的文件中:

从引用这个全局变量的地方开始,到文件的结尾处。

全局变量的生命周期:

从程序执行开始,到程序执行结束;


局部变量的作用域:

在一个局部的作用域范围内。

局部变量的生命周期:

出作用范围死亡。


静态全局变量作用范围:

定义的变量只存在于一个本文件中。其它的文件无法引用和修改它。(因为它对外是封闭的)

静态全局变量的生命周期:

从程序开始到程序结束。


局部静态变量的作用范围:

在局部作用域范围内。

局部静态变量的生命周期:

从程序开始到程序结束。


//看我完整的犯一个错误:

a.h文件

a.cpp文件

b.h

b.cpp

这里看似是修改a的值,


main.cpp


实验的结果告诉我,一个文件中的静态全局变量如果可以修改的话,那么在main函数中执行了 “修改A()”函数后,在“SayA()”函数下,打印的因该是“1000000000”,但是结果表明,没有出现这样的结果。所以不能修改。


可是呢?在主函数的开头添加了 "extern int  a";这又是什么意思呢?它的意思就是说,a这个变量可以使用,但是不在这个模块中,而是在其它的模块中。我们这里,这样做,这个a和  a.h文件中的static int a  中的a不是   同一个a,此a 非彼a。至于为什么,我现在回答不了,


但是如果你在main中把a修改了其它,比如b吧,就是在main的开头写上“extern int b”

,在main函数体中,进行修改,又找不到b。说明了什么呢?我觉得是,

在一个文件中 static全局变量存在的情况下,如果其它的文件引入了该文件,并且添加extern 这个生命周期修饰符,编译器可以识别这个变量,但是呢?你不能贸然的修改,你想修改,那我就是给你复制一个,你自己随便修改着玩,但是真实的这个静态变量,它是不向外公开让你访问的,所以它的值,还是在原来文件中的值,如果原来文件中没有修改它的函数存在的话。


稍微总结一下:

静态的全局变量的作用域只存在于这个定义全局变量的文件当中。其它的文件中的函数根本无法修改它。

静态的局部的变量作用域只是在该文件局部的作用域范围内。更没法再提其它事。



下面证明 全局变量的作用域:请看下图

a.h

a.cpp


b.h


b.cpp


main.cpp


再总结一下:

全局变量的作用域是所有的文件,也就是同一个解决方案的所有文件都可以访问它。


全局的静态函数和全局的函数用法是一样的,我不想多说了。


注意上面所说的,

extern修饰的是在其它模块可以调用,static修饰的只能在本模块使用。



下面再说一下 extern关键字的作用。

extern是关键字,在C中,有extren,static,auto,local。

它的意思就是:1、告诉编译器存在这样的一个变量或者函数,如果在当前模块找不到,那就是在其它的模块中,一定要引入其它包含该函数或者变量的头文件。

2、extern "C"{


}

表示这里面的内容是C语言实现的,你C++在编译的时候,还用C语言的方式,否则你编译或者调用时会出错。  它既是说,这些是外部的用C实现的内容,编译的时候注意些,不要破坏它的格式。


先描述这么多,后面还要努力才是!

0 0