c/c++中静态局部变量以及全局变量的使用(转)
2016-03-24 16:10
357 查看
c/c++中的变量分为全局变量和静态全局变量,局部变量和静态局部变量。本文主要讲静态局部变量。
静态局部变量首先是一个局部变量,加上静态后,生存期就被延长了,不会随着函数的返回而被撤销,我们可以这样理解,静态局部变量就是程序生存期间一直有效,但只能在定义它的函数中使用的一种变量。
静态局部变量的声明比较简单,在声明局部变量的时候,加上关键字static就可以了。下面是一个用局部静态变量计算阶乘的具体例子。
实例1:
#include "stdio.h"
int fac(int n)
{
static int nRet = 1; //静态局部变量
nRet *= n;
return nRet;
}
void main()
{
for(int i=1;i<5;i++)
{
printf("%d!=%d\n",i,fac(i));
}
getchar();
}
在第一次调用函数fac的时候,函数fac中的静态局部变量nRet被初始化为1,如果没有默认指定初始化值得话,会被默认初始化为0. 主函数main中共进行了4次fac函数的调用:
第一次调用:初始化nRet为1 函数返回时:nRet=1
第二次调用时: nRet=1 函数返回时:nRet=2
第三次调用时: nRet=2 函数返回时:nRet=6
第四次调用时: nRet=6 函数返回时:nRet=24
可以看出,静态局部变量在第一次调用的时候进行初始化,每次函数调用后,静态局部变量不会像局部变量那样被立即释放,而是继续有效,在下一次函数调用的时候会继续使用上一次的值。
实例2:
#include <iostream>
using namespace std;
int add(int b,int a)
{
static int z=1;
z=b+a+z;
return z;
}
void main( )
{ int a=1,b=2,x1,x2,x3;
x1=add(a,b);//4
x2=add(add(a,b),b);//16
x3=add(a,b);//18
cout<<x1<<'\n'<<x2<<'\n'<<x3<<endl;
}
以下是对全局变量的使用(转):
例子:
头文件:state.h 源文件:state.cpp
其它源文件:t1.cpp t2.cpp t3.cpp, 这些源文件都包含头文件state.h。
需要定义一个全局变量供这些源文件中使用:方法如下
1、在 state.h声明全局变量: extern int a;
2、在state.cpp中定义该全局变量:int a = 10;
这样其它源文件就可以使用该变量啦
这里需要的是“声明”,不是“定义”!根据C++标准的规定,一个变量声明必须同时满足两个条件,否则就是定义:
(1)声明必须使用extern关键字;(2)不能给变量赋初值
extern int a; //声明
int a; //定义
int a = 0; //定义
extern int a =0; //定义
头文件中应使用extern 关键字声明全局变量(不定义),如果这个变量有多个文件用到,可以新建一个cpp,在其中定义,把这个cpp加入工程即可。头文件请不要定义任何变量,那是非常业余的行为……
一般在头文件中申明,用extern, 在cpp中定义。 如果在头文件中定义,如果这个头文件被多个cpp引用,会造成重复定义的链接错误。
头文件只能申明全局变量(extern),不可定义(不推荐使用) .cpp里,在最外层定义即可(int gi),直接引用
例子(自测)
//总结:一个cpp文件中定义的全局变量,即int count = 0;
//其它包含这个文件对应.h文件的文件要使用这个全局变量需要
//声明它,且也要在函数体中使用
如果在.cpp里使用static定义,则该变量只在当前cpp文件中有效,在别的文件中无效
在.h里使用static定义,不会进行编译(.h文件不编译),只会在其每个include的cpp文件中包含编译,相当于在.cpp里使用static 定义。
静态全局变量(static)
注意使用static修饰变量,就不能使用extern来修饰,即static和extern不可同时出现。
static修饰的全局变量的声明与定义同时进行,即当你在头文件中使用static声明了全局变量,同时它也被定义了。
static修饰的全局变量的作用域只能是本身的编译单元。在其他编译单元使用它时,只是简单的把其值复制给了其他编译单元,其他编译单元会另外开个内存保存它,在其他编译单元对它的修改并不影响本身在定义时的值。即在其他编译单元A使用它时,它所在的物理地址,和其他编译单元B使用它时,它所在的物理地址不一样,A和B对它所做的修改都不能传递给对方。
多个地方引用静态全局变量所在的头文件,不会出现重定义错误,因为在每个编译单元都对它开辟了额外的空间进行存储。
静态局部变量首先是一个局部变量,加上静态后,生存期就被延长了,不会随着函数的返回而被撤销,我们可以这样理解,静态局部变量就是程序生存期间一直有效,但只能在定义它的函数中使用的一种变量。
静态局部变量的声明比较简单,在声明局部变量的时候,加上关键字static就可以了。下面是一个用局部静态变量计算阶乘的具体例子。
实例1:
#include "stdio.h"
int fac(int n)
{
static int nRet = 1; //静态局部变量
nRet *= n;
return nRet;
}
void main()
{
for(int i=1;i<5;i++)
{
printf("%d!=%d\n",i,fac(i));
}
getchar();
}
在第一次调用函数fac的时候,函数fac中的静态局部变量nRet被初始化为1,如果没有默认指定初始化值得话,会被默认初始化为0. 主函数main中共进行了4次fac函数的调用:
第一次调用:初始化nRet为1 函数返回时:nRet=1
第二次调用时: nRet=1 函数返回时:nRet=2
第三次调用时: nRet=2 函数返回时:nRet=6
第四次调用时: nRet=6 函数返回时:nRet=24
可以看出,静态局部变量在第一次调用的时候进行初始化,每次函数调用后,静态局部变量不会像局部变量那样被立即释放,而是继续有效,在下一次函数调用的时候会继续使用上一次的值。
实例2:
#include <iostream>
using namespace std;
int add(int b,int a)
{
static int z=1;
z=b+a+z;
return z;
}
void main( )
{ int a=1,b=2,x1,x2,x3;
x1=add(a,b);//4
x2=add(add(a,b),b);//16
x3=add(a,b);//18
cout<<x1<<'\n'<<x2<<'\n'<<x3<<endl;
}
以下是对全局变量的使用(转):
例子:
头文件:state.h 源文件:state.cpp
其它源文件:t1.cpp t2.cpp t3.cpp, 这些源文件都包含头文件state.h。
需要定义一个全局变量供这些源文件中使用:方法如下
1、在 state.h声明全局变量: extern int a;
2、在state.cpp中定义该全局变量:int a = 10;
这样其它源文件就可以使用该变量啦
这里需要的是“声明”,不是“定义”!根据C++标准的规定,一个变量声明必须同时满足两个条件,否则就是定义:
(1)声明必须使用extern关键字;(2)不能给变量赋初值
extern int a; //声明
int a; //定义
int a = 0; //定义
extern int a =0; //定义
头文件中应使用extern 关键字声明全局变量(不定义),如果这个变量有多个文件用到,可以新建一个cpp,在其中定义,把这个cpp加入工程即可。头文件请不要定义任何变量,那是非常业余的行为……
一般在头文件中申明,用extern, 在cpp中定义。 如果在头文件中定义,如果这个头文件被多个cpp引用,会造成重复定义的链接错误。
头文件只能申明全局变量(extern),不可定义(不推荐使用) .cpp里,在最外层定义即可(int gi),直接引用
例子(自测)
class2.h #pragma once #include <iostream> using namespace std; class class2 { public: class2(void); ~class2(void); int increse2(); }; extern int count;若把class2.h中的声明去掉,变成了只在class2.cpp中定义全局变量(即int count = 0;),那么其它包含class2.h的文件在使用这个全局变量时,需要加上声明extern int count;且也只能在函数体中使用!
//总结:一个cpp文件中定义的全局变量,即int count = 0;
//其它包含这个文件对应.h文件的文件要使用这个全局变量需要
//声明它,且也要在函数体中使用
class2.cpp #include "StdAfx.h" #include "class2.h" class2::class2(void) { } class2::~class2(void) { } int count = 0;//全局变量,作用范围在这个源文件中 int class2::increse2() { count++; return count; }
class1.h #pragma once #include "class2.h" class class1 { public: class1(void); ~class1(void); //count++;//这样用不行 int increse3(); };
class1.cpp #include "StdAfx.h" #include "class1.h" class1::class1(void) { } class1::~class1(void) { } int class1::increse3() { count++; return count; }
// 全局变量的使用.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "class1.h" #include "class2.h" //#include <iostream> //using namespace std; //count++;//这样用也不行 //extern count++;//这样用也不行 //extern int count = 3;//这么用会重定义 //count++;//不重定义,光声明也不能这样用 //总结:一个类中声明的全局变量,其它包含这个类的文件对 //这个全局变量的使用需要在函数体中 int _tmain(int argc, _TCHAR* argv[]) { class2 A; class1 B; count++; int sum = A.increse2(); cout << sum << endl; int sum1 = B.increse3(); cout << sum1 << endl; system("pause"); return 0; }
如果在.cpp里使用static定义,则该变量只在当前cpp文件中有效,在别的文件中无效
在.h里使用static定义,不会进行编译(.h文件不编译),只会在其每个include的cpp文件中包含编译,相当于在.cpp里使用static 定义。
静态全局变量(static)
注意使用static修饰变量,就不能使用extern来修饰,即static和extern不可同时出现。
static修饰的全局变量的声明与定义同时进行,即当你在头文件中使用static声明了全局变量,同时它也被定义了。
static修饰的全局变量的作用域只能是本身的编译单元。在其他编译单元使用它时,只是简单的把其值复制给了其他编译单元,其他编译单元会另外开个内存保存它,在其他编译单元对它的修改并不影响本身在定义时的值。即在其他编译单元A使用它时,它所在的物理地址,和其他编译单元B使用它时,它所在的物理地址不一样,A和B对它所做的修改都不能传递给对方。
多个地方引用静态全局变量所在的头文件,不会出现重定义错误,因为在每个编译单元都对它开辟了额外的空间进行存储。
相关文章推荐
- C和C++中函数传参常见方式总结
- C++ malloc free与new delete
- c++第1次实验-1-求并联电阻
- C++ 重载 覆盖 隐藏
- c++第1次实验-2-求员工周工资
- C++智能指针总结
- c++第2实验-项目1-标准体重
- Windows C++ Url编码
- c++作业2
- C/C++笔试常问的坑
- C++学习记录
- 浅谈C/C++的浮点数在内存中的存储方式
- C语言 百炼成钢19
- C++ 拷贝构造函数和重载赋值函数
- 用Xcode创建C++工程测试LeetCode代码
- configure: error: You need a C++ compiler for C++ support.[系统缺少c++环境]
- C++,cout和std::cout的区别
- C++之:模板元编程(三) 默认模板参数
- 静态代码检查工具的使用(cppcheck)
- Cppcheck 1.54 C/C++静态代码分析工具