函数原型中的 extern 关键字是什么意思?

14

我的数学.h

// case 1 
unsigned int add_two_numbers(unsigned char a, unsigned char b);

//case 2 
extern unsigned int add_two_numbers(unsigned char a, unsigned char b); 
什么是案例1和案例2之间的区别?我从来没有在函数原型中使用extern,但看着某个比我经验更丰富的人的代码,我发现在声明函数原型时总是使用extern。请问有人可以指出其中的区别吗?(或者将我指向一个可以找到具体信息的链接)。谷歌说这与外部链接有关。有人能否指示一个其中一个方法可行而另一个不可行的示例呢?
我正在使用嵌入式C(KEIL),如果有任何区别,请告诉我。
3个回答

17

extern是一个全局链接的链接说明符。它的对应物是static,它指定了文件级别的链接。由于在C中默认为全局链接,所以对于函数声明来说,添加extern对于函数声明没有任何影响。对于变量来说,它会防止自动内存分配,而使用它是在全局范围内仅仅声明变量的唯一方式。

如果您只是搜索关键字,您会发现许多文章,例如这篇文章: geeks for geeks


2

我曾从一名有经验的程序员那里学到关于变量的以下知识:

glo.h:
#ifndef EXTERN
#define EXTERN extern
#endif
...
EXTERN int gMyVar;
...

main.c:
#define EXTERN
#include "glo.h"

任何地方包含 "glo.h" 将只声明所有全局变量。在 main.c 中包含 "glo.h" 将为变量分配存储空间。我相信这种方法是常见的做法。


1
有趣的方法,但对我来说,直接拥有一个包含变量声明的glo.c文件似乎更为简单明了。无需预处理指令。 - jgoeders
@jgoeders,这种方法只需要声明一次符号。而你的方法需要至少声明两次,当重命名/添加/删除符号时容易出错。请注意,只有在main中需要#define;所有其他文件只需要#include "glo.h" - Paul Ogilvie
我同意,你发布的方法确实消除了一些重复,尽管.c/.h定义/声明方法只有一个定义和一个声明,而不是更多,所以我不确定你在“至少两次”方面的建议是什么。这里有很多关于这两种方法(以及其他方法)的讨论:https://dev59.com/d3M_5IYBdhLWcg3wThR3 - jgoeders
"At least twice" 意味着至少有一次 extern int myvar; 声明和恰好一次 int myvar; 定义。我的方案在您链接的问题下被逐字描述,标题为“避免代码重复”(这正是我的观点)。 - Paul Ogilvie

1
对于非内联函数而言,如果没有给出存储类别说明符(注意,这只适用于函数,对象不同),使用extern是隐含的,因此你使用哪种方式只是风格上的问题。
我见过两种方式(从不在函数中使用extern/仅在头文件中的声明中使用它),或许有些人使用extern是为了与对象标识符保持一致,或者为了更容易地搜索外部符号。
选择你喜欢的方式并保持一致,这不会有任何影响。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接