为什么写两次 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则是冗余,可写可不写