变量作用域
1. C++变量根据定义位置的不同,具有不同的作用域,
作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名作用域和文件作用域。
2.从作用域看:
全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包括全局变量定义的源文件需要用extern关键字再次声明这个全局变量。
静态局部变量具有局部作用域。它只被初始化一次,从第一次初始化直到程序运行结束都一直存在,他和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。
局部变量也只有局部作用域,他是自动对象,他在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用结束后,变量就被撤销,其所占用的内存也被收回。
静态全局变量也具有全局作用域,他与全局变量的区别在于如果程序包含多个文件的话,他作用于定义它的文件里,不能作用到其他文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同的静态全局变量,他们也是不同的变量。
3.从分配内存空间看:
全局变量、静态局部变量、静态全局变量都在静态存储区分配空间,而局部变量在栈分配空间。
全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上没有什么不同。区别在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其他源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其他源文件中引起错误。
1、静态变量会被放在程序的静态数据存储区里,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是他与堆栈变量和堆变量的区别
2、变量用static告知编译器,自己仅仅在变量的作用域范围内可见。这一点是他与全局变量的区别。
从以上分析可以看出,把局部变量改变为静态变量后是改变了他的存储方式,即改变了他的生存期。把全局变量改变为静态变量后是改变了他的作用域,限制了他的使用范围,因此static这个说明符在不同的地方起的作用是不同的。
TIPS:
1、若全局变量仅在单个文件中访问,则可以讲这个变量修改为静态全局变量。
2、若全局变量仅在单个函数中使用,则可以将这个变量修改为该函数的静态局部变量。
3、全局变量、静态局部变量、静态全局变量都存放在静态数据存储区。
4、函数中必须要使用static变量的情况:当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。
方法作用域
局部变量
范围:在一个函数内部定义的变量,作用范围只限于本函数体内。
生存期:程序执行到本函数才会给局部变量分配内存单元,函数执行完毕局部变量所占的存储单元就被释放
静态局部变量
范围:函数体内,离开函数体就不起作用,但是值仍然被保留,下次被调用的时候使用的是上次的值
生存期:在编译阶段赋值,从程序运行开始就被分配固定的存储单元(静态存储区),整个程序运行期间不再重新分配,生存周期是整个程序运行期间
#include<iostream>
using namespace std;
int calltimes(){
static int i=0;
i++;
cout<<"The function has been called "<< i <<" times!" <<endl;
}
int main(){
calltimes();
calltimes();
calltimes();
calltimes();
system("pause");
return 0;
}
输出
The function has been called 1 times!
The function has been called 2 times!
The function has been called 3 times!
The function has been called 4 times!
全局变量
在函数体外部定义的变量是全局变量,可以被本文件所有其他函数访问使用。
作用域:所有文件。在一个cpp定义的全局变量在另一个cpp中使用,应该在使用它的函数体内部或外部进行extern说明
生存期:全局变量在程序的全部执行过程中占用固定的内存单元,生存周期是整个程序运行期间。
静态全局变量
作用域:定义它的cpp文件,而不是程序中的所有cpp文件
生存期:整个程序运行期间
不同cpp文件可以使用相同名称的静态全局变量名互不干扰
variable.cpp
static int i=10;
int j=100;
main.cpp
#include <cstdlib>
#include <iostream>
#include "test.h"
using namespace std;
//extern int i; //由于在variable.cpp中i是静态成员,所以即使加了extern声明也不能访问到,编译不成功
extern int j;//只有加extern声明才能访问到variable.cpp中的全局变量j
int main(int argc, char *argv[])
{
// cout<<i<<endl;
cout<<j<<endl;
system("PAUSE");
return EXIT_SUCCESS;
}
输出:
100
static函数
静态函数只能被所在的cpp文件调用,不同cpp文件可以有相同的静态函数名字。
可被其他文件调用的函数
调用方式有两种
第一引入函数所在头文件,第二在调用函数前进行extern声明
test.h
#include<iostream>
using namespace std;
int sum1(int,int);
static int sum2(int, int);
int sum3(int,int);
test.cpp
#include "test.h"
int sum1(int x, int y){
cout<<"sum 1 calculating ...."<<endl;
return x+y;
}
static int sum2(int x, int y){
cout<<"static sum 2 calculating ...."<<endl;
return x+y;
}
int sum3(int x, int y){
cout<<"sum 3 calculating ...."<<endl;
return sum2(x,y);
}
main.cpp
#include <cstdlib>
#include <iostream>
#include "test.h"
using namespace std;
int main(int argc, char *argv[])
{
//extern int sum1(int,int);//如果不加test.h头文件引用,进行extern声明同样可以调用sum1
cout<<sum1(1,2)<<endl;
//cout<<sum2(1,2)<<endl; //sum2是静态函数,不能调用
cout<<sum3(1,2)<<endl; // sum3与sum2在同一个cpp文件中,sum3可以调用sum2
system("PAUSE");
return EXIT_SUCCESS;
}
转自:c++变量与函数的作用域与生存期 - memristor的个人空间 - OSCHINA - 中文开源技术交流社区