C++之auto、static、extern、register

extern

extern 用来声明一个外部变量或是函数,表示该变量已经在其他的地方定义了,这里只是做一个引用而已,不会产生新的变量。对于extern修饰的变量,编译器会在所在的文件先看看有没有对该变量的定义,有的话,直接应用,没有的话再到其他的文件里面进行查找。由于变量已经在其他的地方定义了,所以extern int a = 10;这种写法是不对的,会造成重定义错误!

static

static可以用来修饰变量和函数。

修饰变量

static修饰的变量都存在静态数据区里面,由于静态数据区内存都是被系统初始化为0的,所以static修饰的变量默认初始值为0。
static修饰的变量的作用域只限制于该变量所在的文件,外面的文件不可以使用该变量,所以多个文件可以有相同的变量名(需要使用static修饰),只要在编译的最后链接阶段,在全局情况下,不出现相同的变量名就好。

修饰函数

static修饰的函数主要有两个作用:限定该函数的作用域为本文件可见以及static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝,因此对于static函数的调用会比普通函数快很多。

类中的static

在类中,static修饰的成员变量或是函数表明该变量或是函数是属于类的,所以没有对应的this指针。static修饰的函数只能访问类的static修饰的成员变量,并且static修饰的函数不能是虚函数。

auto

普通局部栈变量,是自动存储,这种对象会自动创建和销毁 ,建议这个变量要放在堆栈上面,调用函数时分配内存,函数结束时释放内存。一般隐藏auto默认为自动存储类别。我们程序都变量大多是自动变量。auto不能修饰全局变量,因为该变量的内存是放在栈上面的,有系统自动创建和销毁,所以不能用来修饰全局变量。在函数里面,一般所声明的变量都是直接的默认为auto的。

register

寄存器变量,请求编译器将这个变量保存在CPU的寄存器中,从而加快程序的运行。系统的寄存器是有限制的,声明变量时如:register int i.这种存储类型可以用于频繁使用的变量。实际上现在一般的编译器都忽略auto和register申明,现在的编译器自己能够区分最好将那些变量放置在寄存器中,那些放置在堆栈中;甚至于将一些变量有时存放在堆栈,有时存放在寄存器中。

使用register修饰符有几点限制

(1)register变量必须是能被CPU所接受的类型。这通常意味着register变量必须是一个单个的值,并且长度应该小于或者等于整型的长度。不过,有些机器的寄存器也能存放浮点数。最好不要这样去用

(2)因为register变量可能不存放在内存中,所以不能用“&”来获取register变量的地址。

(3)只有局部自动变量和形式参数可以作为寄存器变量,其它(如全局变量)不行。在调用一个函数时占用一些寄存器以存放寄存器变量的值,函数调用结束后释放寄存器。此后,在调用另外一个函数时又可以利用这些寄存器来存放该函数的寄存器变量。所以说不要用register修饰全局变量等,因为他长时间的占用寄存器不允许再被使用了。

(4)局部静态变量不能定义为寄存器变量。不能写成:register static int a, b, c,同样的道理,因为static变量函数结束不会被销毁,下面进入还会使用之前的数据,生命周期直到程序退出才结束,数据存放在静态区。

(5)由于寄存器的数量有限(不同的cpu寄存器数目不一),不能定义任意多个寄存器变量,而且某些寄存器只能接受特定类型的数据(如指针和浮点数),因此真正起作用的register修饰符的数目和类型都依赖于运行程序的机器,而任何多余的register修饰符都将被编译程序所忽略。

auto register 是用来修饰变量的,static extern 变量函数都可以