在计算机领域,
堆栈是一个不容忽视的概念,但是很多人甚至是计算机专业的人也没有明确堆栈其实是两种数据结构。
要点:
堆:顺序随意
栈:先进后出
堆和栈的区别
一、预备知识—程序的
内存分配
一个由c/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由
程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、
全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放
4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放
5、程序代码区—存放函数体的二进制代码
各种变量的作用域:
局部静态变量。在局部变量之前加上
关键字static,局部变量就被定义成为一个局部静态变量。
内存中的位置:静态存储区。
初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的值是任意的,除非被显式初始化)。
作用域:作用域指变量的有效范围,当定义它的函数或者语句块结束时,作用域随之结束。
注意:当static 用来修饰局部变量时,它就改变了局部变量的存储位置,从原来的栈中存放改为静态存储区。但是局部静态变量在离开作用域之后,并没有被销毁,而是仍然驻留在内存中,直到程序结束,只不过不能再对它进行操作了
全局静态变量。在全局变量之前加上关键字static,全局变量就被定义成为一个全局静态变量。
内存中的位置:静态存储区(静态存储区在整个程序运行期间都存在)。
初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的值是任意的,除非被显式初始化)。
作用域:全局静态变量在声明它的文件之外是不可见的,准确地讲,是从定义处开始到文件结尾。
注意:当static 用来修饰全局变量时,它就改变了全局变量的作用域(在声明它的文件之外是不可见的),但是没有改变它的存放位置,还是在静态存储区。
静态函数。在函数的返回类型前加上关键字static,该函数就被定义成为静态函数。
函数的定义和声明默认情况下是 extern 的,但静态函数只在声明它的文件中可见,不能被其他文件所用。
静态数据成员。
内存中的位置:静态存储区。
初始化和定义:
静态数据成员定义时要分配空间,不能在类声明中定义。
静态数据成员在程序中只能提供一个定义。静态数据成员的初始化不能在类的
头文件中。
访问:
类实例名.静态数据成员
类类型名::静态数据成员
说明:
static 数据成员和普通数据成员一样遵循public,protected,private 访问规则。
对于非静态数据成员,每个类实例都有自己的备份。静态数据成员被当做类的全局对象,无论这个类的对象被定义了多少个,静态数据成员在程序中也只有一个备份,由该类类型的所有对象共享访问。
同全局对象相比,使用静态数据成员有两个优势:
静态数据成员没有进入程序的全局
名字空间,因此不存在与程序中其他全局名字冲突的可能性。
静态数据成员可以实现信息隐藏。静态成员可以是 private 成员,而全局对象不可以。
静态数据成员的唯一性本质(独立于类的任何对象而存在的唯一实例),使它能够以独特的方式被使用,这些方式对于非static数据成员来说是非法的。
静态成员函数。在类的成员
函数返回值之前加上关键字static,它就被声明为一个静态成员函数。静态成员函数不能声明为const 或volatile,这与非静态成员函数不同。
定义:出现在类体外的函数定义不能指定关键字static。
作用域:主要用于对静态数据成员的操作。
静态成员函数与类相联系,不与类的对象相联系。
静态成员函数不能访问非静态数据成员,因为非静态数据成员属于特定的类实例。
静态成员函数没有this指针,因此在静态成员函数中隐式或显式地引用这个指针都将导致编译时刻
错误。试图访问隐式引用this指针的非静态数据成员也会导致编译时刻错误。
访问:可以用成员访问
caozuofu.html" target="_blank">操作符(.)和箭头(->)为一个类实例或指向类实例的指针调用静态成
员函数,也可以用限定修饰符名直接访问或调用静态成员函数,而无需声明类实例