extern关键字用来声明全局变量和函数

1 声明全局变量

全局变量的作用域十分的广,只要在一个源文件中定义后,应用中所有的所有源文件、对象以及函数都可以调用,生命周期更是贯穿整个程序。

1.1 方式一(常用)

定义全局变量的相关头文件中,使用extern声明全局变量

/* global_test.cpp 源文件定义全局变量 */
int g_num = 100;

/* global_test.h 声明该全局变量 */
extern int g_num;

/* main.cpp 文件 */
#include "global_test.h" /* g_num全局变量声明头文件 */

int32 get_g_num();

int main() {
  get_g_num();
  return 0;
}

int32 
get_g_num() {
  return g_num;
}

1.2 方式二(本质)

使用该全局变量的源文件中,不需要包含头文件也可以引用全局变量

/* global_test.cpp 源文件定义全局变量 */
int g_num = 100;


/* main.cpp 文件 */
extern int g_num;//声明全局变量 不需要包含头文件 也可以引用 使用extern关键字

int32 get_g_num();

int main() {
  get_g_num();
  return 0;
}

int32 
get_g_num() {
  return g_num;
}
以上两种方式的本质其实都一样,因为头文件会在预处理阶段展开到源文件中,其实第一种写法是为了条理清晰,第二种展示事件的本质。

2 声明函数

2.1 方式一(常用)

/* global_test.cpp 源文件定义函数 */
int 
printArr() {
  printf("printArr\n");
  return 0;
}

/* global_test.h 声明该函数 */
extern int printArr();

/* main.cpp 文件 */
#include "global_test.h" /* 导入该头文件,表示可能使用该声明函数 */

int main() {
  printArr();
  return 0;
}

2.2 方式二(本质)

/* global_test.cpp 源文件定义函数 */
int 
printArr() {
  printf("printArr\n");
  return 0;
}

/* main.cpp 文件 */
extern int printArr(); /* 声明并引用函数 */

int main() {
  printArr();
  return 0;
}

3 C语言函数声明有无extern

在C语言中,函数的声明可以带有关键字extern,也可以不带。

  1. 带有extern关键字的函数声明,这种声明通常用于告诉编译器,函数的定义在别的地方,这里只是为了方便调用
  2. 不带extern关键字的函数声明,这种声明既可以表示函数的定义在后面(一般用来表示该函数就在后面定义),也可以表示函数的定义在其他文件中。
/* fun.cpp */
#include <stdio.h>

int
funO () {
  printf("__funO__\n");
}


/* main.cpp */
#include <stdio.h>

int funC (); /* 一般表示该函数在该源文件后面定义 */
extern int funO ();  /* 表示其他源文件定义 */

int
main (int argc, char *argv[]) {

  funC();
  funO();

  return 0;
}

int
funC () {
  printf("__funC__\n");
}