C语言了解声明和定义

示例

声明引入一个标识符并描述其类型,可以是类型,对象或函数。声明是编译器需要接受对该标识符的引用的内容。这些是声明:

extern int bar;
extern int g(int, int);
double f(int, double); /* extern can be omitted for function declarations */
double h1();           /* declaration without prototype */
double h2();           /* ditto                         */

定义实际上实例化/实现此标识符。这是链接器将链接引用链接到那些实体所需要的。这些是与上述声明相对应的定义:

int bar;
int g(int lhs, int rhs) {return lhs*rhs;}
double f(int i, double d) {return i+d;}
double h1(int a, int b) {return -1.5;}
double h2() {}  /* prototype is implied in definition, same as double h2(void) */

可以在定义的地方使用定义。

但是,必须定义一次。如果忘记定义已在某处声明和引用的内容,则链接器将不知道将引用链接到什么内容,并且会抱怨缺少符号。如果定义不止一次,则链接器将不知道将引用链接到哪个定义,并抱怨重复的符号。

例外:

extern int i = 0;  /* defines i */
extern int j;  /* declares j */

可以使用“强符号vs弱符号”的概念(从链接器的角度)来解释此异常。请查看此处(幻灯片22)以获取更多说明。

/* All are definitions. */
struct S { int a; int b; };             /* defines S */
struct X {                              /* defines X */
    int x;                              /* defines non-static data member x */
};
struct X anX;                                  /* defines anX */