C++中的auto与static用法

  static被称为静态修饰符,一般用于修饰变量与函数。在讲static之前先说一下自动修饰符auto是怎么回事。

void function()
{	
	int a = 5;
	auto int b=7;
	……
}

  在以上的代码块中,变量a与变量b的性质是一模一样的,都是自动变量,auto是可以被省略的。熟悉微机原理的同学应该清楚,计算机在内存中专门划分了一个区域,叫栈(stack)。栈使用一个后进先出的数据结构,即LIFO,最后进入栈的变量首先被弹出(这里稍微注意一下是弹出不是删除)。
  在程序运行过程中,如果function()这个函数被调用的话,那么自动变量a与b的值将会被压入栈中;function()函数开始执行之后,自动变量a和b就会和压入栈中的对应的值关联起来;当function()函数结束后,栈顶指针将移动到压栈前的位置,即两个值从栈中弹出。
  可见自动变量的生命周期往往是短暂的,其生命周期是和其被包含的函数息息相关:当包含它的函数被使用,自动变量就会“活”过来,包含它的函数停止使用,自动变量就会“死掉”。而且很明显可以看出,自动变量每一次“活”过来,都会重新初始化一次,代码块中的function()每被调用一次,a与b都会重新自动初始化为5和7,这也许是自动变量名称的由来。
  自动变量在短暂的人生发现了一件事,变量越是依附于函数存在,越容易在意想不到的地方失败,除非超越自动变量。于是一些变量不做自动变量了。
  C++中静态变量有三种形式:

int globalValue=100;//静态变量,外部链接
static int fileValue=200;//静态变量,内部链接

int main()
{
	……
}

void function1()
{
	static int internalValue=300;//静态变量,无链接
	int autoValue=400;//自动变量
	……
}

  由以上的代码块可以看出,C++依靠链接性为静态变量进行分类:外部链接性(其他文件可访问)、内部链接性(只在本文件中访问)、无链接性(只能在当前函数或代码块中访问)。与自动变量相比,各种静态变量的生命周期更长,它们在整个程序的执行周期中都是存在的。此外,程序在运行过程中,静态变量的数量不会改变,代码写出来几个就一直是几个,因此也不需要栈来动态管理它们。实际上,编译器会分配固定的内存块来存储静态变量。如果没有显式地初始化静态变量,静态变量也会和动态变量一样设定为0.
  globalValue和fileValue是全局变量,区别在于:globalValue可以被该文件之外的文件调用,其它文件调用globalValue时,只需要声明如下即可:

extern int globalValue;

  fileValue就不一样了,由于该变量被static修饰,因此该静态变量是不可以被外部的文件调用的,其有效范围只在本文件中。该文件中的任何函数都可以使用fileValue和globalValue,但是另外的文件只可以使用globalValue。在全局变量的层面上,static表现为确定变量的内外部链接性。
  internalValue的生命周期是整个程序的执行周期,这点与autoValue形成了强烈对比。由于生命周期的不同,internalValue与autoValue还拥有一个较为直观的区别:每次调用function1(),autoValue都会被重新初始化为400;然而internalValue只会初始化一次,当internalValue的值变化后,再调用function1(),internalValue仍会保留改变后的值,而不是初始化为300。从局部变量的层面上,static表现为确定变量的存储持续性。

file1//:
int globalValue=100;//静态变量,外部链接
……

file2//:
static int globalValue=200;//静态变量,内部链接
void function3()
{
	cout<<	globalValue<<endl;//打印出来是200
}
……

  以上的代码块可以很明显的发现内部链接静态变量与外部链接静态变量的区别。在file2中也定义了一个globalValue,但是用static进行了修饰,即覆盖了外部链接的globalValue,因此在function3()中打印globalValue的值时打印出来的是200而不是100。
  如果非要在file2中调用file1中的globalValue呢?好在C++提供了一个办法。

file1//:
int globalValue=100;//静态变量,外部链接
……

file2//:
static int globalValue=200;//静态变量,内部链接
extern int globalValue;//声明引用了fille1中的静态变量
void function3()
{
	cout<<	globalValue<<endl;//打印出来是200
	cout<<::globalValue<<endl;//打印出来是100
}
……

  C++提供了作用域解析运算符::,该运算符用于表示该变量的全局版本,因此在 function3()中第二句打印出来的值是100。
  static还可以用来修饰函数,在默认情况下,函数的链接性是外部的。

file1//:
void function4(int a)
{
	……
}

file2//:
extern void function4(int a);
function4(9);
……

  static可以将函数的链接性设置为内部的,即外部的其他文件不可以对其调用。此外,该静态函数将覆盖外部定义,即使其他文件中定义了同名称的函数,也不影响该静态函数在该文件中的使用。如下代码所示:

file1//:
void function5(int a);
void function5(int a)
{
	cout<<a<<endl;
}

file2//:
static void function5(int a,int b);
static void function5(int a,int b)
{
	cout<<a+b<<endl;
}
int main()
{
	function5(2,3);//输出5
}

  static还可以用来类成员函数,当static修饰类成员函数时,又表现出特别的性质:
  1.不能通过对象调用静态成员函数,静态成员函数不能使用this指针。较为直观的感觉是,静态成员函数不属于具体的对象,单纯属于包含其定义的类。如果静态成员函数属于public区域,则可以使用类名和作用域解析运算符调用。比如如下所示的一个静态成员函数:

static int num(){return num_string;}

  2.静态类成员函数只能使用静态数据成员。以上函数中的num_string必须是个静态成员变量
  调用该成员函数的方式如下:

int count = String::num();
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值