• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

C++ 头文件小知识

1.头文件

1.1为什么要有头文件?

   C/C++ 编译采用分离编译模式。在一个项目中,有多个源文件存在,但是它们总会有一些相同的内容,比如用户自定义类型、全局变量、全局函数的声明等。将这些内容抽取出来放到头文件中,提供给各个源文件包含,就可以避免相同内容的重复书写,提高编程效率和代码安全性。所以,设立头文件的主要目的是:提供全局变量、全局函数的声明或公用数据类型的定义,从而实现分离编译和代码复用。

概括地说,头文件有如下三个作用:

  (1)加强类型检查,提高类型安全性。

(2)减少公用代码的重复书写,提高编程效率

    程序开发过程中,对某些数据类型或者接口进行修改是在所难免的,使用头文件,只需要修改头文件中的内 容,就可以保证修改在所有源文件中生效,从而避免了繁琐易错的重复修改。

(3)提供保密和代码重用的手段

头文件也是 C++ 代码重用机制中不可缺少的一种手段,在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制库即可。用户只需要按照头文件的接口声明来调用库函数,而不必关心接口的具体实现,编译器会从库中连接相应的实现代码。

1.2头文件中的 #ifndef 是干什么用的?

一个头文件被别的源文件重复包含是经常发生的,如何避免某个头文件被重复包含呢?利用条件编译轻松解决。在头文件的开始加入:

#ifndef HEADER_NAME
#define HEADER_NAME

在头文件的结尾加上:

#endif

HEADER_NAME 可以为任意内容,只要能够唯一标识当前头文件即可,建议使用头文件的名称。将这些条件编译预处理指令加入上面的示例程序中的两个头文件,问题即可解决。

要注意以下几点:

(1)条件编译指令#ifndef HEADER_NAME和#endif的意思是:如果条件编译标志 HEADER_NAME 没有定义的话,则编译#ifndef和#endif之间的程序段,否则就忽略它。头文件 只要被包含一次,条件编译标志宏 HEADER_NAME 就会被定义,这样就不会被再次包含。

(2)iostream 是标准库中的头文件,所以被包含时使用尖括号 <>,而用户自定义的头文件,被包含时使用双引号

1.3头文件中为啥不要用普通变量函数的定义?

尽量在头文件中制作声明,不定义变量、函数,否则容易重复定义而报错。

然后再说几个关键字:

extern:C++中extern是指全局的意思。它一般有两个方面的用途:

1、声明变量

首先说一下声明和定义的区别:

①变量的定义:用于为变量分配存储空间,还可以为变量指定初始值。在一个程序中,变量有且仅有一个定义。

②变量的声明:用于向程序表明变量的类型和名字。定义也是声明:当定义变量时我们声明了它的类型和名字。可以通过使用extern 关键字声明变量名而不定义它。例如:

extern int i; //声明一个变量i,但是并没有定义
int i; //声明并且定义了一个变量i

extern 声明不是定义,也不分配存储空间。事实上,它只是说明变量定义在程序的其他地方。程序中变量可以声明多次,但只能定义一次。

只有当声明也是定义时,声明才可以有初始化式,因为只有定义才分配存储空间。初始化式必须要有存储空间来进行初始化。如果声明有初始化式,那么它可被当作是定义,即使声明标记为 extern例如:

extern int i = 0;

虽然使用了 extern ,但是这条语句还是定义了i,分配并初始化了存储空间。只有当extern声明位于函数外部时,才可以含有初始化式。

因为已初始化的extern声明被当作是定义,所以该变量任何随后的定义都是错误的:例如:

extern int i = 0;
int i; //报错,重复的定义

同样,随后的含有初始化式的extern声明也是错误的:

extern int i = 0; // 定义
extern int i; // 只声明,正确
extern int i = 0; // 重复定义,错误

为什么会这样呢?因为 extern int a; 只是声明而不是定义,声明是不会为变量开辟内存空间的,自然无法对其进行初始化的操作。

全部回复(0)
正序查看
倒序查看
现在还没有回复呢,说说你的想法