您的位置:首页 > 编程语言 > C语言/C++

C/C++ static 关键字

2012-09-16 18:43 309 查看
记得曾经有同事碰到一个在这样的问题,他在头文件中定义了一个static变量,原本是在多个源码文件中共享,却发现在一个源文件中赋值了,却发现在另一个源文件中发下还是空指针。大致的代码如下:
test.h

#ifndef _TEST_H_
#define _TEST_H_
static typeName* m_Test = new TypeName();

...
#endif
test1.c

#include "test.h"

void test1()
{
m_Test->some_var = "xxxxx";
}
test2.c

#include <stdio.h>
#include "test.h"

void test2()
{
printf("%s",m_Test->some_var);
}
test.c
#include <stdio.h>

int main(int argc,char* argv[])
{
test1();
test2();
}
结果却发现并没有打印出他想要的值"xxxxx",他很不解。为了给他解释原因,在vs2010中新建一个win32 project。添加下面的这些代码:

test.h

#ifndef _TEST_H_
#define _TEST_H_

static int tt = 3;

void test1();
void test2();

#endif //_test_h_
test1.cpp

#include "stdafx.h"
#include "test.h"

void test1()
{
printf("test1 var tt address is %08x\n",&tt);
tt = 8; //修改tt变量的值,测试是否会影响test2中的变量tt
printf("test1 var tt value is %d\n",tt);
}
test2.cpp

#include "stdafx.h"
#include "test.h"

void test2()
{
printf("test2 var tt address is %08x\n",&tt);
printf("test2 var tt value is %d\n",tt);
}
test.cpp
#include "stdafx.h"
#include "test.h"
int _tmain(int argc, _TCHAR* argv[])
{
test1();
test2();
return 0;
}
测试的结果输出为

test1 var tt address is 00a2b000

test1 var tt value is 8

test1 var tt address is 00a2b004

test1 var tt value is 3

从上面的结果可以看出变量test1中的tt变量和test2中的tt变量并不是同一个,所以test1中修改了tt的值并不会影响到test2中的tt的值。具体原因就得说说C语言中static关键字声明的变量的作用域了。在C语言中,static可用来声明全局变量,也可用来声明局部变量。但是不管是全局变量还是局部变量,static声明的变量的值都存储在全局数据区,一般static变量在声明时就要初始化,若未出世程序会自动给初始值0。

static声明的全局变量的作用域是从声明处开始到文件结束。修改test1.c和test2.c文件就:

test1.cpp

#include "stdafx.h"
#include "test.h"

static int xx = 8;

void test1()
{
printf("test1 var tt address is %08x\n",&tt);
tt = 8; //修改tt变量的值,测试是否会影响test2中的变量tt
printf("test1 var tt value is %d\n",tt);
}
test2.cpp

#include "stdafx.h"
#include "test.h"

void test2()
{
printf("xx value %d",xx);//这里会提示xx变量未定义
printf("test2 var tt address is %08x\n",&tt);
printf("test2 var tt value is %d\n",tt);
}


前面提到的按个同事说犯的错误也正是因为这个原因导致的,在test.h文件中声明的变量被test1.cpp和test2.cpp文件都包含了。所有在test1.cpp和test2.cpp文件中都会有一个单独的tt变量。并不会达到共享的原因。

static声明局部变量可以先看下面一段代码:

void test()
{
static int var = 10;
printf("var is %d\n",var);
var++;
}

int main(int argc,char* argv[])
{
test();
test();
test();
}
打印的结果是:

var is 10

var is 11

var is 12

why? 静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。

C++ 中static关键字

在文件中static声明的变量和函数中声明的局部变量作用跟C语言中是一样的,多的是在类中使用static 声明的变量表示这个变量是属于类的,所有该类的对象实例共享同一个static变量。值得注意的是静态数据成员定义时要分配空间,所以不能在类声明中定义。static声明的类成员初始化格式是这样的 <数据类型><类名>::<静态数据成员名>=<值>,在初始化的时候不需要加上static关键字。访问类的static成员形式如下<类类型名>::<静态数据成员名>。

同样,可以声明static成员函数,所有类的对象实例共享同一个static成员函数。静态成员函数与静态数据成员一样,都是类的内部实现,属于类定义的一部分。普通的成员函数一般都隐含了一个this指针,this指针指向类的对象本身,因为普通成员函数总是具体的属于某个类的具体对象的。通常情况下,this是缺省的。如函数fn()实际上是this->fn()。但是与普通函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有this指针。从这个意义上讲,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。类中static的成员函数在定义的时候并不需要static关键字。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: