在源文件(.c)和头文件(.h)中声明和定义的区别——C语言

最近在看多文件编程的时候遇到的一个问题,本来以为理解了声明和定义的区别(然而并没有····),也算是重新认识了一次声明和定义,下面上代码

声明和定义:有分配空间的叫定义,没分配空间的叫声明

定义:表示创建变量或分配存储单元

声明:说明变量的性质,但并不分配存储单元

情形一:在源文件(.c)中(函数内)

int a;//定义
extern int a;//声明

第一个int a是定义,分配了存储空间(其实包括了声明和定义两个步骤,可以叫"定义性声明"),第二个 extern int a是声明(也叫"引用性声明"),没有分配存储空间

关于extern的使用,感兴趣的读者可以看一下另一片随笔:extern的使用详解(多文件编程)——C语言

声明可以多次,定义只能有一次

意思是在源文件(.c)中可以多次声明同一个变量,例如在源文件(.c)和头文件(.h)中声明和定义的区别——C语言在编译阶段是不会报错的在源文件(.c)和头文件(.h)中声明和定义的区别——C语言

情形二:在源文件(.c)中(函数外)

在源文件(.c)和头文件(.h)中声明和定义的区别——C语言

编译结果:

在源文件(.c)和头文件(.h)中声明和定义的区别——C语言

这里的int a;放在函数外,没有出现重定义的错误,并不意味着int a就不是定义了,int a仍然是定义,编译阶段没有报错了原因在于全局变量没有赋初值,没赋初值的全局变量,那么在目标文件中是不会为

这个全局变量分配空间的,它被放在BSS段(如果是赋初值的全局变量,那么放在data段),BSS段在目标文件中是没有的(这个就是编译阶段不会报错的原因),意味着没赋初值的全局变量不占磁盘空间,

当程序加载运行时,就会为bss段中的数据分配内存进行初始化了(起到了节省磁盘空间的作用),上面说了BSS段的数据不占磁盘空间,那么它的大小和符号存在哪呢? bss段占据的大小存放在ELF文件格式

中的段表(Section Table)中,段表存放了各个段的各种信息,比如段的名字、段的类型、段在elf文件中的偏移、段的大小等信息

(感谢园友:SD8086 指出随笔中的错误)

(对内存映像感兴趣的读者可以看下这两篇文章:bss段不占据磁盘空间的理解大内高手—全局内存

情形三:在头文件(.h)中

在头文件中的声明和定义和在源文件中函数外的声明和定义相同,下面为测试结果

在源文件(.c)和头文件(.h)中声明和定义的区别——C语言在源文件(.c)和头文件(.h)中声明和定义的区别——C语言在源文件(.c)和头文件(.h)中声明和定义的区别——C语言

修改头文件后

在源文件(.c)和头文件(.h)中声明和定义的区别——C语言在源文件(.c)和头文件(.h)中声明和定义的区别——C语言在源文件(.c)和头文件(.h)中声明和定义的区别——C语言

从上面可以看出int a在头文件中仍然是定义,只不过和全局变量定义相同,只要没有赋初值,编译阶段就不会报错

上一篇:Keras之inception_v3使用


下一篇:C++ 变量的声明与定义的区别