**引言:**
**static關鍵字不僅可以修飾變量,而且可以修飾函數。了解它的用法,不僅對閱讀別人的代碼有幫助,也有助于自己寫出更加健壯的程序。**
**用法:**
**用于不同的上下文環境時,static關鍵字具有不同的意義。**
**(一)**
當它用于函數定義時,或用于代碼塊之外的變量聲明時,static關鍵字用于修改標示符的鏈接屬性,從externl改為internal。但標示符的存儲類型和作用域不受影響。這種方式聲明的函數或變量只能用于聲明它們的源文件中。
**(二)**
當它用于代碼塊內部的變量聲明時,static關鍵字用于修改變量的存儲類型,從自動變量修改為靜態變量,但變量的鏈接屬性和作用域不受影響。用這種方式聲明的變量在程序執行之前創建,并在程序的整個執行期間一直存在,而不是每次在代碼塊開始執行時創建,在代碼塊執行完畢后銷毀。
**示例解析:**
**代碼解釋一:**
**main.c源碼**
~~~
#include <stdio.h>
#include "test.h"
void main(void)
{
fun(); /*fun函數就是在test.c文件中聲明的函數*/
printf("j = %d\n", j);/*j變量也是在test.c文件中聲明的變量*/
}
~~~
test.c源碼
~~~
#include <stdio.h>
static int i = 1;/*聲明為內部變量,只能用于test.c源文件*/
int j = 2;/*可以作為外部變量使用,在main文件中用到了*/
static void fun1(void)/*聲明為內部函數,只能用在test.c源文件中*/
{
printf("i+1 = %d, j+1 = %d\n", i+1, j+1);
}
void fun(void)/*可以用在其他文件中,用在main文件中*/
{
printf("i = %d, j = %d\n", i, j);
fun1();
}
~~~
test.h源碼
~~~
extern int j;
extern void fun(void);
~~~
編譯上面的程序:gcc main.c test.c -o test生成可執行文件test
**運行可執行文件test顯示結果如下:**
~~~
i = 1, j = 2//該行是由main函數里調用的test.c文件中的fun函數生成的
i+1 = 2, j+1 = 3//該行是由test文件中fun函數調用的fun1函數生成的
j = 2//這是由main函數使用外部變量j直接生成的
~~~
**代碼解釋二:**
**test.c源碼**
~~~
#include <stdio.h>
void main(void)
{
int i = 1;
printf("i = %d\n", i);
}
~~~
teststatic.c源碼
~~~
#include <stdio.h>
void main(void)
{
static int i = 1;/*用于代碼塊內部變量的聲明*/
printf("i = %d\n", i);
}
~~~
編譯上面的兩個文件
**gcc test.c -o test**
**gcc teststatic.c -o teststatic**
**生成兩個可執行文件test和teststatic**
**使用size命令查看兩個可執行文件各個段大小:size test teststatic**
**text data bss dec ? hex filename**
**929 ?264 ? ? 8 ? 1201 4b1 test**
**929 ? 268 ? ?8 ? 1205 4b6 teststatic**
**使用static修飾的程序data段更大,因為它在程序執行之前創建,并一直存在到程序執行結束。**
**補充:**
**關于作用域存儲類型的解釋,參考:**
**[http://blog.csdn.net/to_be_it_1/article/details/24450227
](http://blog.csdn.net/to_be_it_1/article/details/24450227)**
[http://blog.csdn.net/to_be_it_1/article/details/24467879](http://blog.csdn.net/to_be_it_1/article/details/24467879)
- 前言
- (四)回調函數
- (一)while(1)死循環與for(;;)死循環的區別
- (二)static關鍵字
- (三)函數
- (四)可變參數函數
- (五)setjmp和longjmp
- (六)指針
- (七)回調函數
- (八)字符串
- (九)動態內存分配
- (十)結構體
- (十一)深入理解指針
- (十二)命令行參數
- (十三)printf、fprintf、sprintf和snprintf函數
- (十四)const關鍵字詳解
- (十五)字符串輸入函數fgets、gets和scanf
- (十六)字符串輸出函數puts、fputs和printf
- (十七)字符/字符串輸出函數fputc、fputs、putc、putchar和puts
- (十八)字符/字符串輸入函數fgetc、fgets、getc、getchar和gets
- (十九)restrict關鍵詞
- (二十)scanf函數詳解
- (二一)內聯函數
- (二二)位操作
- (二三)errno變量
- (二四)內存分配