c语言的定义与声明
声明
很多人都不太明白声明这玩意有什么用。
我定义一个变量:
1.分配了内存
2.初始化了数据
3.以后可以存取
但是声明这玩意,好像什么也没干哪!
声明(declaration )指定了一个变量的标识符,用来描述变量的类型,是类型还是对象,或者函数等。声明,用于编译器(compiler)识别变量名所引用的实体。以下这些就是声明:
extern int bar;
extern int g(int, int);
double f(int, double); // 对于函数声明,extern关键字是可以省略的。
class foo; // 类的声明,前面是不能加class的。
要理解声明,就得了解连接器(linker).我们知道c语言是分开编译。
gcc -c 1.c 2.c 3.c
c编译器会输出1.o 2.o 3.o
注意
编译器根本不知道3者之间的关系:
1.c中是否调用了2.c中定义的函数f()
2.c是否修改了3.c中定义的变量var
注意编译器压根不知道这么复杂的邻里关系,七舅姥爷的远亲表姨。
举个例子:
1.c
int main(){
f();
return 0;
}
gcc -c 1.c
报错defined refernece to f
但是你加上
extern void f();
int main(){
f();
return 0;
}
就OK了,编译就通过!
声明就是告诉编译器,我这个是使用别人的,你别报错!到时候连接器会帮我找到的。
gcc 1.c 2.c 3.c
连接器负责在其他两个模块里找f的定义
定义
定义是对声明的实现或者实例化。
连接器(linker)需要它(定义)来引用内存实体。
与上面的声明相应的定义如下:
int bar;
int g(int lhs, int rhs) {return lhs*rhs;}
double f(int i, double d) {return i+d;}
class foo {};// foo 这里已经拥有自己的内存了,对照上面两个函数,你就应该明白{}的用处了吧?
注意
定义只能使用一次!
如果你定义变量超过一次,连接器是不知道把reference和哪块内存连接,然后就会报 duplicated symbols这样的错误了(symbols是指定义后的变量名)。
总结
总之,最终原因是c采用分开编译,最终连接的方式。
所以声明就成为linker去寻找其定义的钥匙。它只是为了给编译器提供引用标识,让编译器能够知道有这个引用,能用这个引用来引用某个实体。
声明是为了让编译器正确处理对声明变量和函数的引用。
定义是一个给变量分配内存的过程,或者是说明一个函数具体干什么用。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。