定义和声明的区别、extern和static的区别以及头文件的使用

1.定义和声明的区别

定义:创建一个对象,为这个对象分配一块内存,并给它取上一个名字,这个名字就是就是我们经常所说的变量名或函数名,需要建立存储空间的。定义只能出现一次,出现多次会报错(重复定义)。

声明:告诉编译器,这个名字已经匹配到一块内存上,下面的代码用到变量或者函数是在别的地方定义的,不需要建立存储空间的。声明可以出现多次。
 

      声明的作用只有一个:可以在定义前使用。如果函数A定义在调用它的函数B前,则函数A就不需要再声明。通常我们定义变量的时候喜欢放在文件的开头,这也是变量一般不需要声明的原因。如果我们把变量的定义放在文件的末尾,就会出现编译错误(未定义),只需在文件包含的头文件中声明一下这个变量就可以了。变量的声明前必须加extern,且不能赋初值。例如:extern int a; 

变量的定义和声明:

     在定义变量的时候,这个extern居然可以被省略(定义时,默认均省略)。而在声明变量的时候,这个extern必须添加在变量前,所以有时会让你搞不清楚到底是声明还是定义。或者说,变量前有extern不一定就是声明,而变量前无extern就只能是定义。

变量的定义
int a;          //前无extern(extern被默认省略),只能是定义
int a=0;        //前无extern(extern被默认省略),且需要建立储存空间用来存放0,所以是定义
extern int a=0; //前虽然有extern,但需要建立储存空间用来存放0,所以是定义
变量的声明
extern int a;   //前有extern,是声明
 

函数的定义和声明:

      函数的定义和声明则要简单的多,这是因为函数的声明和定义在格式上就不同,函数的定义需要有函数体,声明不需要有,且函数的声明必须有封号结尾。这就不需要加关键字extern来进行区分(函数定义、声明时关键字extern也被默认省略)。这就不难理解,为什么变量的声明为啥需要前加extern,而函数声明不需要。

      int fun(); 和 extern int fun(); 都是声明(定义要有实现体),用extern int  fun()只是更明确指明是声明而已。

       这里可能会有人问:extern不是用来声明变量使能够被其他文件使用吗?这里需要明白的是文件可以使用在非本文件中定义的全局变量,并不是因为声明变量时前加了extern的缘故,而是文件包含了带有变量声明的头文件或者文件中直接带有变量的声明。这里extern仅仅是用来说明是声明变量的,而不是定义变量。

既然说到了extern,就顺便说一下static,static在C语言中主要有两个作用:

1)在函数体内,定义变量为静态局部变量,静态局部变量和普通局部变量的区别:static局部变量只被初始化一次,下一次的运算依据上一次的结果值。

2)在文件内,但在函数体外,限制变量或函数的作用域。static类型的变量或函数,只能被文件自己使用,不可以被外文件外的使用。这一作用和extern恰巧相反,这也是为什么extern和static不能同时使用的原因。

2.头文件

      头文件指的就是#include包含的文件,通常我们习惯定义为XX.h的格式,用来存放函数及变量的声明。在预编译时头文件告诉编译器哪些函数以及变量已经定义了,是可以使用的。头文件是存放变量及其函数声明的,其实变量和函数的声明,存放在C文件中也是可行的,存放在头文件中是为了管理方便,并可以被多个C文件包含。当多个C文件需要用到同一个变量或者函数时,不需要多次声明,只需包含一下含有该变量和函数的声明的头文件就可以。

注意:头文件中不能包含任何定义。例如:

/*xx头文件*/
#ifndef _XX.H
#define _XX.H
 int A;

#endif

      这里的int A是个全局变量的定义,如果这个头文件被多次引用的话,你的A会被重复定义,显然语法上错了。只不过有了这个#ifndef的条件编译,所以能保证你的头文件只被引用一次,不过也许还是不会出岔子,但若多个c文件包含这个头文件时还是会出错的,因为宏名有效范围仅限于本c源文件,所以在这多个c文件编译时是不会出错的,但在链接时就会报错,说你多处定义了同一个变量。

本博客整理自网络,仅供学习参考,如有侵权,联系删除。邮箱:[email protected]

猜你喜欢

转载自blog.csdn.net/leho666/article/details/80540108