0%

预处理和条件编译

#ifndef

防止头文件重复包含和编译

假如有一个C源文件(如S.cpp),它包含两个头文件(如H1.h和H2.h),而头文件H2.h又包含了H1.h,则最终的效果是该源文件包含了两次H1.h。如果你在头文件里定义了结构体或者类类型,编译时将会报重复定义的错误。

加上条件编译”#ifndef”则问题可解决。在H1.h中加上条件编译,如下:

1
2
3
4
5
6
7
#ifndef _H1_H
#define _H1_H
#include<iostream>

...

#endif

当第一次包含H1.h时,由于没有定义 _H1_H,条件为真,这样就会执行#ifndef _H1_H和#endif之间的代码;当第二次包含H1.h时,前面已经定义了_H1_H,条件为假,#ifndef _H1_H和#endif之间的代码也就不会再次被包含,这样就避免了重定义。最好把头文件内容都放在其中,不管你的头文件会不会被多个文件引用。

ifndef等之后的标识可自由命名,但每个头文件的标识都应该是唯一的。标识的命名规则一般是头文件名全大写,前面加下划线,并把文件名中的”.”也变成下划线。

便于程序的调试和移植

  • 当标识没有被#define定义过,则编译代码块1,否则编译块2。
1
2
3
4
5
6
7
8
9
#ifndef ...

...//1

#else

...//2

#endif
  • 当if后表达式值为真时,编译代码块1,否则编译代码块2。
1
2
3
4
5
6
7
8
#if ...

...//1
#else

...//2

#endif
  • #else不是强制的;当#else后需要嵌套#if时,可以使用#elif,它相当于#else#if。

#pragma once

一个更方便的选择

它指定该文件在编译源代码文件时仅编译一次

1
2
3
4
使用#progma once
#pragma once

...//H.h

等价于

1
2
3
4
5
6
#ifndef _H_H_ 
#define _H_H_

...

#endif // H.h