2.8包含警戒:多次声明

为什么写两次 void myFunc(); ,编译器不提示重复定义?

答:声明可以进行多次,定义只能进行一次。

声明和定义的区别

你或许对这个问题不屑一顾,但仔细想一想这样一个问题:声明和定义的区别到底在哪里?

区别一

  • 声明告诉编译器,这个变量或函数已经在程序其他地方存在了,所以我正在把这个信息告诉你,下面我要调用的时候请放行。但请不要为我分配任何内存空间,因为已经这个步骤在变量或函数定义的地方进行分配了。
  • 而定义则很清楚了,就是要求分配内存空间。很多时候,声明和定义是合而为一的。
int a;
void func() {}

这里同时声明且定义了一个变量和一个函数。

区别二

这点或许不是每个人都是很清楚的:声明可以进行多次,定义只能进行一次。

void myfunc();

void myfunc();

void myfunc() {}

可以通过编译,而

void myfunc();
void myfunc() {}
void myfunc() {}

则会报错,因为重复定义了。

声明和定义的分离

对于函数来说,我们已经很清楚如何对其进行声明和定义的分离了,这正是我们在成对的 .h/.cpp 中做的事情,这里补充一句,实际上编译器对所有函数的声明和定义都悄悄在前面补上了 extern,因为 extern 代表了声明的动作,当我们包含一个头文件的时候,告诉编译器,我接下来调用到的函数是在它处进行定义的。 那么变量的声明和定义如何分离呢?因为我们大多数时候都是既声明又定义一个变量的,如

int num;

这里虽然没有给num赋任何初值,但是在此处已经完成内存分配了。前面说过,extern关键词是用作声明的,因此我们可以这样做

extern int num;
int num = 100;

当然,没有人在现实生活中会这样做,而且这两行只能放在全局域中,但至少说明了将变量的声明与定义分离也是可以做到的 如果我们这样写

extern int num = 0;

就是同时声明与定义了,这时这里的extern则是冗余,可写可不写