**引言:**
**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变量
- (二四)内存分配