C/C++中静态元素 及Static的用法(整理自Thinking in C++)

来源:互联网 发布:四量指标公式源码 编辑:程序博客网 时间:2024/06/04 23:31

</pre>c/c++中static的两种用法:<p></p><p><span style="white-space:pre"></span>1).在固定的地址上进行存储分配,在<span style="color:#ff0000;">静态数据</span>区创建,而不是每次函数调用时在堆栈上创建,即静态存储;<span style="white-space:pre"></span></p><p><span style="white-space:pre"></span>2).对特定的编译单元是局部的,通过static控制名字的可见性,决定链接器能够看到哪些名字。</p><p></p><p>一、函数内部的静态变量</p><p></p><p>1.函数内部的静态变量:</p><p><span style="white-space:pre"></span>对于函数体内的局部变量,编译器每次调用函数时,堆栈指针下移一个适当位置,为这些局部变量分配内存。如果变量有一个初始化表达式,每次程序运行到这里都会进行初始化。</p><p><span style="white-space:pre"></span>当我们需要在两次函数调用之间保存一个变量的值,一种方法是通过定义一个全局变量来实现。但是这将导致该变量不仅仅只受这一个函数控制。c和c++都允许定义一个static对象,该对象存储在静态存储区,<span style="color:#ff0000;">而不是堆栈</span>。该对象在第一次调用函数的时候初始化一次,在两次调用期间保持它的值。如果没有为内建类型的静态变量提供一个初始值,编译器会在程序开始时它被初始化为0  。对一个静态对象的初始化(跟其他对象初始化一样)可以是任意的常量表达式。(常量表达式中可以出现常量以及在此之前声明过的变量和函数)。</p><p>2.函数内部的静态对象:</p><p><span style="white-space:pre"></span>静态变量的规则同样适用于静态对象,它同样必须有初始化操作。可以用带参数的构造函数,也可以用默认构造函数。如果定义一个静态对象时没有指定构造函数参数,这个类必须要有默认构造函数。下面的代码中,在f()内定义了两个静态对象,x1带初始化参数, x2调用默认构造函数。程序第一次转到对象的定义时(且只有第一次时)执行构造函数。</p><p><pre name="code" class="cpp">#include<iostream>using namespace std;class X{int i;public:X(int ii = 0):i(ii){}~X(){cout<<"X::~X()"<<endl;}};void f(){static X x1(47);static X x2;//调用默认构造函数}int main(){f();}//:~

二、控制连接

文件作用域内的名字(不嵌套在类或函数数中的名字),对程序的所有单元来说是可见的,即外部链接(external linkage)。在连接时这个名字对链接器是可见的,对单独翻译的单元,它是外部的。全局变量和普通函数都有外部链接。

如果要限制一个名字的可见性,使一个变量在文件范围内是可见的,这样这个文件中的所有韩寒苏都可以使用该变量,但文件外地函数无法看到或访问该变量,或者这个变量与外部的标识符冲突。此时可以使用static。

一个被明确声明为static的对象或函数的名字,对翻译单元来说是局部于该单元的,这些名字有内部链接(internal linkage)。这样别的单元就可以使用同样的名字而不发生冲突。例如常量,内联函数,在默认情况下都是内部链接的。与static相反的,extern声明声明一个名字对所有的翻译单元是可见的 。如果把局部变量声明为extern,这意味这某处已经存在一个存储区。对于函数名(非成员函数),static 和 extern 只改变函数的可见性。


三、其他存储类型说明符

static 和 extern用的比较多,另外两个用的较少的说明符是auto,register。auto告诉编译器该变量是局部变量,指明编译器自动为该变量分配存储空间。编译器实际上是可以从上下文分辨出是一个局部变量,所有auto是多余的。

register说明的也是局部变量,他告诉编译器该变量会经常用到,编译器应该尽可能的让他保存在寄存器中,应该避免用register变量,编译器在优化代码方面通常比我们要好。



0 0
原创粉丝点击