C/C++中static用法小结

来源:互联网 发布:中国移动网络维护 编辑:程序博客网 时间:2024/05/21 19:47

static意为静止的、不变的,如其字意,在C语言中,关键字static的出现将改变变量的存储区域和作用域。static作为关键字还广泛出现在各种编程语言中,不管是C、C++、C#、JAVA、VB,还是其他高级计算机语言如FORTRAN、ALGOL、COBOL、BASIC、LISP等语言中,都有static的身影,只是有着不同的作用。本文将对C/C++中的static关键字做比较全面的说明,作为小结。

(注:在写本篇学习笔记时,本人学习和参考了网络文章,并做了借鉴,感谢各位前辈的分享。如果本文对您有所帮助,您可以随意分享,如果发现文中有误,也请指教,谢谢。本文用到的调试工具:C-free 5.0,操作系统:Windows 7)

在C/C++中,static作为关键字的作用为:

1、修饰局部变量;

2、修饰全局变量;

3、修饰全局函数;

4、修饰成员变量或者成员函数;(C++)


1、修饰局部变量:

void fun()

{

    int i=10;

    static int j=10;

}

在修饰局部变量的时候,static改变了变量的存储区域。局部变量的定义和声明默认情况下是auto修饰的,这也是我们在C语言程序中很少看到auto的原因。

auto修饰的变量存储在栈中,属于动态存储类别,占用动态存储空间,函数调用结束后自动释放;aoto变量如果没有初始化,其值不可预知,可能是被分配的这段内存中的任何值。

而static修饰的变量分配在静态区存储区,在程序整个运行期间一直存在;static变量如果没有初始化,则默认为0。

auto和static修饰的变量作用域相同,但生存周期不同。


2、修饰全局变量:

如果有一个文件fileA.c:

int i=10;

static int j=20;

void funA()

{

    printf("i=%d\n",i);  // 打印结果为“i=10”

    printf("j=%d\n",j);  // 打印结果为“j=20”

    int i=30;

    int j=40;

    printf("i=%d\n",i);  // 打印结果为“i=30”

    printf("j=%d\n",j);  // 打印结果为“j=40”

}

另一个文件fileB.c:

void funB()

{

    printf("i=%d\n",i);  // 正确,i为普通全局变量,可被操作,打印结果为“i=10”

    printf("j=%d\n",j);  // 错误,j为静态全局变量,只能作用域fileA

}

在修饰全局变量的时候,static改变了变量的作用域。全局变量的定义和声明在默认情况下是extern修饰的,这也是我们在C语言程序中很少看到extern的原因。

如上例所示,i为一般的全局变量,可在fileB中操作,而j为静态全局变量,只能作用于fileA中,fileB中不可见。

作为全局变量,如果没有被初始化,不管是static还是extern,则其值都默认为0。

在这里,我还想说明一下fileA中出现的变量隐藏,C语言的初学者需要特别在意,全局变量的作用域比局部变量大,但是局部变量的优先级比全局变量高,如果在一个函数块中声明了一个与全局变量名相同的变量,那么全局变量将被隐藏。


3、修饰全局函数:

如果有一个文件fileA.c:

void funA1()

{

}

static void funA2()

{

}

另一个文件fileB.c:

int main()

{

    funA1();  // 正确,i为普通全局变量,可被操作,打印结果为“i=10”

    funA2();  // 错误,静态全局变量,只能作用域fileA


    return 0;

}

在修饰全局函数的时候,static改变了全局函数的作用域。

如上例所示,被关键字static修饰的函数只作用于本文件,其他文件不可被调用。


以上都是static在C语言中的用法,下面我们来看下C++对static用法的扩展。

4、修饰成员变量或者成员函数:

class EnemyTarget

{

public:

    EnemyTarget()

   {

        ++numTargets;

    }

    EnemyTarget(const EnemyTarget &)

    {

        ++numTargets;

    }

    ~EnemyTarget()

    {

        --numTargets;

    }

    static size_t numberOfTarget()

    {

        return numTargets;

    }

    bool destroy();

private:

}; 

size_t EnemyTarget::numTargets;

C++重用了这个关键字,并赋予它与前面不同的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数. 这是与普通成员函数的最大区别, 也是其应用所在, 比如在对某一个类的对象进行计数时, 计数生成多少个类的实例, 就可以用到静态数据成员. 在这里面, static既不是限定作用域的, 也不是扩展生存期的作用, 而是指示变量/函数在此类中的唯一性. 这也是”属于一个类而不是属于此类的任何特定对象的变量和函数”的含义. 因为它是对整个类来说是唯一的, 因此不可能属于某一个实例对象的。(针对静态数据成员而言, 成员函数不管是否是static, 在内存中只有一个副本, 普通成员函数调用时, 需要传入this指针, static成员函数调用时, 没有this指针。) 

在上例中,静态数据成员numTargets就是用来统计产生的对象个数的。

另外,在设计类的多线程操作时,由于POSIX库下的现场函数pthread_create()要求是全局的,普通成员函数无法直接作为线程函数,可以考虑用static成员函数做现场函数。













(注:在写本篇学习笔记时,本人学习和参考了网络文章,并做了借鉴,感谢各位前辈的分享。如果本文对您有所帮助,您可以随意分享,如果发现文中有误,也请指教,谢谢。本文用到的调试工具:C-free 5.0,操作系统:Windows 7)
0 0