小议 static 关键字
1.静态全局变量: 只作用域本文件,其它文件extern也不行
file1.c
#include <stdio.h>
static int i = 0;
file2.c
#include <stdio.h>
extern int i;
int main(int argc, const char *argv[])
{
printf("%d/n", i);
return 0;
}
gcc *.c ->
./tmp/ccftYQ26.o: In function `main':
w2.c:(.text+0xb): undefined reference to `i'
collect2: ld returned 1 exit status
/#
2.静态局部变量
由于static定义或声明的变量存储在内存的静态区, 而不是存储在栈中, 所以出了这个作用域后
{
static int i = 1;
i++;
}
变量i不会销毁, 再次进入也不会被重新定义,而是使用原来的值,不过这个作用域是局部的.也就是在其它作用域定义个静态i , 和 第一个静态i 不是同一块内存.
这里有点要注意,再次进入这个作用域, static int i = 1; 其实只起到声明作用 .只是告诉你这里面有这个符号而已. 没有起到赋值作用.
看下面的程序:
static int j ;
void test() {
static int i = 1; //相当于声明
i++;
printf("i=%d/n", i);
}
void test2() {
j = 0; //每次进入这个作用域 都会被重新赋值下
j++;
printf("j=%d/n", j);
}
int main(int argc, const char *argv[])
{
int k = 0;
for (; k<10; k++) {
test();
test2();
}
return 0;
}
3.修饰函数, 修饰函数不同于修饰变量, 有一点相同就是, 只作用域本文件, 和存储方式无关(静态存储区). 这个作用很大, 和 C++的namespace作用相当!
4. C++ 修饰成员变量, 所有对象共享静态成员
class Test {
public:
Test(int j, int k);
void GetI() { cout<<i<<endl; }
private:
int j, k;
static int i; //静态成员,非全局的
};
int Test::i = 0;
Test::Test(int j, int k) {
this->j = j;
this->k = k;
i = j + k;
}
int main(int argc, const char *argv[])
{
Test a(1, 2);
a.GetI();
Test b(2, 3);
b.GetI();
a.GetI();
return 0;
}
5.静态成员函数
静态成员函数不能调用非静态成员, 因为它没有this ,非静态成员需要对象才能调用. 正因为没有this,所以速度上有少许的增长, 当然静态成员函数也是可以用对象来调用的.
class Test {
public:
Test(int j, int k);
static void GetI() { cout<<i<<endl; }
static void test() ;
private:
int j, k;
static int i;
};
int Test::i = 0;
Test::Test(int j, int k) {
this->j = j;
this->k = k;
i = j + k;
}
void Test::test() {
GetI();
}
int main(int argc, const char *argv[])
{
Test a(1,2);
a.test();
Test::test();
return 0;
}
6.默认初始化为0 , 由于存储在静态区包括全局变量, 会默认初始化为0
摘自 Crazybaby's blog