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