C语言中声明与定义

来源:互联网 发布:淘宝网客户端登录 编辑:程序博客网 时间:2024/05/19 13:30

C语言中声明与定义

声明指定了一个变量的标识符,描述了一个变量的类型。

声明用于编译器识别变量名所引用的实体。

以下是一些声明:

extern int bar;extern int g(int,int);double f(int,double);   //对于函数声明,extern关键字可以省略class foo;                     //对于类的声明

定义是对声明的实现或者实例化。

连接器需要定义来引用内存实体。

以下是一些定义:

int bar;int g(int lhs,int rhs){    return lhs*rhs;}double f(int I,double d){    return i+d;}class foo{};

定义是只能做一次的。

声明是可以多次的。

如下多次声明完全ok:

#include <stdio.h>#include <stdlib.h>int my_add(int a, int b);int my_add(int a, int b);int my_add(int a, int b);int main(int argc, char *argv[]) {    printf("%d\n",my_add(5,6));    return 0;}int my_add(int a, int b){    return a+b;}

如果你忘了定义一些你已经声明过的变量,或者忘了定义一些你在某些地方被引用到的变量,
那么连接器linker是不知道这些引用该连接到哪块内存上的,然后就会报missing symbols 这样的错误。

如果你定义变量超过一次,连接器linker是不知道把引用和哪块内存连接,然后就会报duplicated symbols这样的错误了。
以上的symbols其实就是指定义后的变量名,也就是其标识的内存块。

例如,忘记定义已经声明过的函数:

#include <stdio.h>#include <stdlib.h>int my_add(int a,int b);int main(){    printf("%d\n",my_add(5,6));    return 0;}

在编译阶段一切ok,因为声明是给编译器看的,有声明就能过。

但实际在连接的时候,linker会去寻找这个声明的实现,也就是定义的那部分,发现没有,就报“unresolved external symbol _my_add”的错误(missing symbols)。

如果只是为了给编译器提供引用标识,让编译器能够知道有这个引用,能用这个引用来引用某个实体(但没有为实体分配具体内存块的过程)叫做声明。

如果该操作能够为引用指定一块特定的内存,使得该引用能够在link阶段唯一正确地对应一块内存,这样的操作叫“定义”。

声明是为了让编译器正确处理对声明变量和函数的引用。定义是一个给变量分配内存的过程,或者是说明一个函数具体干什么用。

声明包含定义。

比如:int a;

当声明类型是int名字是a的变量的同时我们也定义了a这个变量(在内存中的某部分)。

注意:声明包含定义,也可能不包含定义。Int a就是声明包含定义,但是诸如extern int a;则仅仅是声明,没有定义。

可以使用extern关键字声明变量名但是不定义它。

比如:extern int i; 仅仅对i进行了声明但实际上没有定义i。

比如:int i; 既进行了声明也进行了定义。

例如:

#include <stdio.h>#include <stdlib.h>int main(){    extern int i;    i = 5;    return 0;}

在连接的时候会报错。

extern int i;只是说明(声明)变量在程序其他地方定义(也就是程序的外部,一般是程序的其他文件中),
但是程序找不到i的定义(linker不知道该把i和内存中的哪一个区域关联起来,也即指针不知道该指向哪个地址),所以报错。

Extern只是声明,不是定义,不会分配内存空间。

Right code:#include <stdio.h>#include <stdlib.h>extern int i = 5;int main(){    return 0;}

Right code中定义了i,分配并且初始化了存储空间。

但是,只有当extern声明位于函数外部时,才可以含有初始化式(才能进行初始化)。

Error code:#include <stdio.h>#include <stdlib.h>int main(){    extern int i = 5;    return 0;}Error information:error C2205: 'i' : cannot initialize extern variables with block scope(块范围)
Right code:#include <stdio.h>#include <stdlib.h>int main(){    extern int i;    i = 5;    printf("%d\n",i);    return 0;}int i;
Error code(如果把main中的extern去掉的话):#include <stdio.h>#include <stdlib.h>int main(){    i = 5;    printf("%d\n",i);    return 0;}int i;Error information: error C2065: 'i' : undeclared identifier
Other Right Code:#include <stdio.h>#include <stdlib.h>int main(){    extern i;    i = 5;    printf("%d\n",i);    return 0;}int i;

对于Other Right Code的解释:声明外部变量(全局变量)时可以把变量类型去掉如:extern A;

资料来源:
1. http://jingyan.baidu.com/article/020278118e51e01bcd9ce576.html
2. http://blog.sina.com.cn/s/blog_755f0c2401012im8.html
3. http://jingyan.baidu.com/article/37bce2be3d92f11002f3a2fc.html
4. http://bbs.chinaunix.net/thread-4184481-1-1.html
5. http://www.cnblogs.com/haore147/p/3647466.html
6. http://zhidao.baidu.com/link?url=JzQE0FOvo0ngPPIfo4TmcEs6myJrif_GrQVRAMt5uwPCSiH-MsZIRwMWEe7ckymk0y4DnVLL7wX6VytmTZhVrq
7. http://zhidao.baidu.com/link?url=E1HrVjyeeoBc2ZTdbmp0lw_phwGJ6sz2PKejRkHdDms-1P7TatAUUPuYMEw-QYYLhmgO7TuI83WozASaL3X5vQN0sNQKfQ3GePkeV4PGbXC
8. http://blog.csdn.net/sjxbf/article/details/6310150
9. http://wenku.baidu.com/link?url=u5XXkZ8M8Dt0nx9XPAR-rp82PFhGDFJsHed6-mMSPN-fhr5MG_emD6WXFOcVxJiBsYEqjXTI5Y5IA6-eHInwA00QrBtD3eceH9XBrFw-pRS
10. http://www.jb51.net/article/54613.htm
11. http://zhidao.baidu.com/link?url=6tFgSgee6J90lDz5sGDDDXXFQPE3rrqoY8uCs-XEbIlBZJhCeJOKQZn0bLm762pPDV7TGbnvGosLD8P3DreqHq

0 0
原创粉丝点击