extern与static修饰符的区别及使用场景详解:如何正确使用extern和static
extern 与 static 修饰符意义

extern
变量/函数定义位于其他文件中
变量/函数定义于本文件(公用)且可以用于其他文件
static
变量/函数对此文件来说是局部(专用)
static有两重意思。
场景一
main.c
外部声明了一个整数变量 flag ,由于只是声明,所以不能对其进行初始化操作 。
int main()
{
printf("%d", flag);
}
sub.c
int flag = 1;
如果在 main.c 中进行 extern int flag = 1 的操作,那么在编译的时候将会出现以下这些信息。
main.c 文件的第 5 行第 12 个位置有一个警告,内容是“flag”既被初始化了又被声明为“extern”。
extern int flag=1;
^~~~
`flag'被定义了多次。
/tmp/ccCtPSdg.o 的.data 部分在这个位置首次被定义。
collect2 出现错误,ld 返回了 1 个退出状态。
场景二
下面两个文件中的静态变量仅在其所属的文件内生效,故而不存在冲突。
main.c
static int flag = 4;
int main()
{
printf("%d", flag);
}
sub.c
static int flag = 6;
extern 对比 inlcude头文件
头文件
模块间共享的信息应该放在头文件中。如:
使用extern还是include头文件?
例子
希望在头文件里定义一个全局变量,接着将其包含到两个不同的 c 文件里,期望这个全局变量能够在这两个文件中被共同使用。测试代码如下:
// main.c
#include
#include "common.h"
int main()
{
printf("main.c : %d", key);
return 0;
}
// common.c
#include "common.h"
void test_f()
{
printf("common.c : %d", key);
}
// common.h
#ifndef _COMMON_H_
#define _COMMON_H_
int key = 1;
#endif
结果
编译器在编译时会提示出错,一般的提示大概是这样的:类似于“Symbol key multiply defined”。这意味着对变量“key”进行了重复定义。这是因为#include 命令会将头文件中的内容原封不动地搬到#include 的位置。所以,就相当于在 main.c 和 common.c 中都执行了一次 int key 。而 C 语言中,全局变量在项目内(或者叫工程内)是可见的。这样一来,就导致了在一个项目中出现了两个变量 key 。编译器便会认为这是重复定义。#ifndef、#define、#endif 在 common.h 中的目的是避免同一个文件中多次包含文件 common.h,而对于重复定义全局变量,它们并不能起到避免的作用。
解决办法
使用 extern 关键字来对变量进行声明,使其成为外部变量。在 main.c 文件中,通过 extern 关键字将变量 key 声明为外部变量。
在 common.c 里,因为使用了 include "common.h",所以就不需要再使用 extern 来声明变量 key 了。
总结:在整个工程里,变量 key 仅在 common.h 这一处被定义了一次。
// main.c
#include
extern int key;
extern void test_f();
int main()
{
printf("main.c : %d\n", key);
test_f();
return 0;
}
// common.c
#include "common.h"
void test_f()
{
printf("common.c : %d", key);
}
// common.h
#ifndef _COMMON_H_
#define _COMMON_H_
int key = 1;
#endif
参考文献
《实用 C 语言编程》于 2000 年 5 月由电力出版社出版。在该书的 P356 处,详细讲解了 C 语言中 extern 的用法,以及如何正确使用 extern 关键字。
generated byharoopad