不要再混淆 C 语言变量的声明和定义

一般情况下,我们对变量的 声明(Declaration)和 定义(Definition)的理解如下:

  • 声明:用于向程序表明变量的类型和名字。在程序中,变量可以被多次声明。
  • 定义:用于为变量分配存储空间,还可以为变量指定初始值。在程序中,变量有且只有一个定义。

两者主要区别:是否在内存中分配了空间。

只要记住下面的内容即可分清定义和声明:
声明相当于 普通 的声明:它所说明的并非本身,而是描述在其他地方创建的对象。
定义相当于 特殊 的声明:它为对象分配内存。
——《Expert C Programming》

进一步解读

  • 定义也是声明,定义变量时我们声明了它的类型和名字。
    1
    int i;  // 可以叫「声明」或「定义」,但「定义」更为准确
  • 声明并不一定是定义,如 extern 声明。
    1
    extern int i;  // 只能叫「声明」
  • 带有初始化式的声明是定义。
    1
    extern int i = 5; // 只能在函数体外初始化
  • 函数的声明和定义区别比较简单,带有花括号{}的是定义,否则是声明。
    1
    2
    int foo1(int x);     // 声明
    int foo2(int x) { } // 定义

程序模块化设计

模块是一个 .h 文件和一个 .c 文件的结合,头文件 .h 中是对于该模块接口的声明。

  • 若模块提供给其它模块调用的外部函数及数据需在 .h 中文件中添加 extern 关键字声明。
  • 模块内的函数和全局变量需在 .c 文件开头添加 static 关键字,注意不是在 .h 文件。

注意:不要把变量定义放入 .h 文件,这样容易导致重复定义的错误。

在 C++ 中,有以下三个例外:

  1. 值在编译时就已知的 const 变量的定义可以放到头文件中
    1
    const int num(10);
  2. 类的定义可以放到头文件中
  3. inline 函数

这三个对象可以定义在多个源文件中,只要在每个源文件中的定义相同即可。

参考

C 语言中声明和定义详解