C/C++预处理指令

  1. 预处理指令 Preprocessor Directives
    1. define
    2. undef
    3. ifdef ifndef if endif else and elif
    4. line
    5. error
    6. include
    7. 预定义标识符
    8. pragma

预处理指令 (Preprocessor Directives)

预处理指令是我们写在程序代码中的给预处理器(preprocessor)的命令,而不是程序本身的语句。预处理器在我们编译一个C++程序时由编译器自动执行,它负责控制对程序代码的第一次验证和消化。

所有这些指令必须写在单独的一行中,它们不需要加结尾的(;)分号。

#define

在这个教程的开头我们已经提到了一种预处理指令: #define ,可以被用来生成宏定义常量(defined constantants 或 macros),它的形式是:

#define name value

它的作用是定义一个叫做name 的宏定义,然后每当在程序中遇到这个名字的时候,它就会被value代替,例如:

#define MAX_WIDTH 100
char str1[MAX_WIDTH];
char str2[MAX_WIDTH];

它定义了两个最多可以存储100个字符的字符串。

#define 也可以被用来定义宏函数:

#define getmax(a,b) ((a)>(b)?(a):(b))
int x=5, y;
y = getmax(x,2);

这段代码执行后y 的值为5 。

#undef

#undef 完成与 #define相反的工作,它取消对传入的参数的宏定义:

#define MAX_WIDTH 100
char str1[MAX_WIDTH];
#undef MAX_WIDTH
如果在这段代码之后,使用MAX_WIDTH编译器就会报错。

#ifdef, #ifndef, #if, #endif, #else and #elif

这些指令可以使程序的一部分在某种条件下被忽略。

#ifdef 可以使一段程序只有在某个指定常量已经被定义了的情况下才被编译,无论被定义的值是什么。它的操作是:

#ifdef name
// code here
#endif

例如:

#ifdef MAX_WIDTH
char str[MAX_WIDTH];
#endif

在这个例子中,语句char str[MAX_WIDTH]; 只有在宏定义常量MAX_WIDTH 已经被定义的情况下才被编译器考虑,不管它的值是什么。如果它还没有被定义,这一行代码则不会被包括在程序中。

#ifndef 起相反的作用:在指令#ifndef 和 #endif 之间的代码只有在某个常量没有被定义的情况下才被编译,例如:

#ifndef MAX_WIDTH
#define MAX_WIDTH 100
#endif
char str[MAX_WIDTH];

这个例子中,如果当处理到这段代码的时候MAX_WIDTH 还没有被定义,则它会被定义为值100。而如果它已经被定义了,那么它会保持原值 (因为#define 语句这一行不会被执行) 。

指令#if, #else 和 #elif (elif = else if) 用来使得其后面所跟的程序部分只有在特定条件下才被编译。这些条件只能够是常量表达式,例如:

const int VALUE_JUDGE = 150;

#if VALUE_JUDGE >200
#define MAX_WIDTH 200

#elif VALUE_JUDGE <50
#define MAX_WIDTH 50

#else
#define MAX_WIDTH 100
#endif

char str[MAX_WIDTH];

注意看这一连串的指令 #if, #elif 和 #else 是怎样以 #endif 结尾的。

#line

当我们编译一段程序的时候,如果有错误发生,编译器会在错误前面显示出错文件的名称以及文件中的第几行发生的错误。

指令#line 可以使我们对这两点进行控制,也就是说当出错时显示文件中的行数以及我们希望显示的文件名。它的格式是:

#line number "filename"

这里number 是将会赋给下一行的新行数。它后面的行数从这一点逐个递增。

filename 是一个可选参数,用来替换自此行以后出错时显示的文件名,直到有另外一个#line指令替换它或直到文件的末尾。例如:

#line 1 "assigning variable"
int a?;

这段代码将会产生一个错误,显示为在文件"assigning variable", line 1 。

#error

这个指令将中断编译过程并返回一个参数中定义的出错信息,例如:

#ifndef __cplusplus
#error A C++ compiler is required
#endif

这个例子中如果 __cplusplus 没有被定义就会中断编译过程。

#include

这个指令我们已经见到很多次。当预处理器找到一个#include 指令时,它用指定文件的全部内容替换这条语句。声明包含一个文件有两种方式:

#include "file"
#include <file>

两种表达的唯一区别是编译器应该在什么路经下寻找指定的文件。第一种情况下,文件名被写在双引号中,编译器首先在包含这条指令的文件所在的目录下进行寻找,如果找不到指定文件,编译器再到被配置的默认路径下(也就是标准头文件路径下)进行寻找。

如果文件名是在尖括号 <> 中,编译器会直接到默认标准头文件路径下寻找。

预定义标识符

为了处理一些有用的信息,预处理定义了一些预处理标识符,虽然各种编译器的预处理标识符不尽相同,但是他们都会处理下面的4种:

__FILE__ 正在编译的文件的名字

__LINE__ 正在编译的文件的行号

__DATE__ 编译时刻的日期字符串,例如: "25 Dec 2000"

__TIME__ 编译时刻的时间字符串,例如: "12:30:55"

例如:cout<<"The file is :"<<__FILE__"<<"! The lines is:"<<__LINE__<<endl;

#pragma

这个指令是用来对编译器进行配置的,针对你所使用的平台和编译器而有所不同。要了解更多信息,请参考你的编译器手册。

时间: 2024-10-13 00:32:45

C/C++预处理指令的相关文章

预处理指令

1.预处理指令 即编译之前执行的指令 C中的预处理指令包括:文件包含,宏定义,条件编译 2.文件包含#include <stdio.h> <>和""的区别 #include <file_1.h> //直接在C库函数头文件所在目录下找 #include "file_1.h" //先在main.c所在目录下找,若无到环境变量path路径中找,若无,到C库函数头文件所在目录中找 #include可能会导致重复包含文件,降低编译效率 解决

OC高效率52之多用类型常量,少用#define预处理指令

// //  ViewController.m //  OC高效率52之多用类型常量,少用#define预处理指令 /**  *     1. 不要用预处理定义常量.这样定义出来的常量不含类型信息,编译器只是会在编译前据此执行查找与替换操作.即时有人重新定义了常量值,编译器也不会产生警告信息,这将导致应用程序中得常量值不一致.        2.在实现文件中使用static const 来定义"只在编译单元内可见的常量".由于此类常量不在全局符号表中,所以无需为其名称加前缀.     

4、多用类型常量,少用#define预处理指令

摒弃: #define ANIMATION_DURATION 0.3 #define ERROR_MESSAGE @"ErrorMessage" 1)没有常量的类型信息 2)假设此指令声明在某个头文件中,那么所有引入了这个头文件的代码,都可以访问和修改ANIMATION_DURATION. 推荐: 1.私有常量 .m文件 static const NSTimeInterval kAnimationDuration = 0.3; static NSString *const kError

C#预处理指令

C#常用的预处理指令有#region.#endregion:#define.#undef.#if.#elif.#else.#endif: #region.#endregion成对使用,表示一个代码块,可以在#region后面加注释说明,主要是使代码结构美观.清晰: #define.#undef.#if.#elif.#else.#endif一般也一起使用,#define.#undef需要放在文档的开头,#if.#endif必须一起使用: 还有#line.#pragram,似乎不常用.

黑马程序员-C学习笔记-编译预处理指令

------- ios培训. android培训.java培训.期待与您交流! ---------- 一.编译预处理指令 源代码 -> 编译预处理 -> 编译 -> 链接 -> 运行 编译预处理指令:在编译前进行解析处理的指令 特点:所有编译预处理指令都以#开头 所有编译预处理指令都不加分号 二.宏定义 1.不带参数的宏定义:  #define 宏名 值 (1)在预编译的时候所出现宏名标识的地方都会被替换成宏名后面的值 注意点:注释中的宏名不会被替换 在字符串中出现的宏名不会被替换

关于C++代码中的#pragma预处理指令

预处理指令是指在编译器编译代码时,提供按条件跳过源文件中的代码段(节).报告错误(错误信息以及行号)和警告条件,以及描绘源代码的不同区域的能力. 总是占用源代码中的单独一行,并且总是以 # 字符和预处理指令名称开头.# 字符的前面以及 # 字符与指令名称之间可以出现空白符. 下面是可用的预处理指令: #define 和 #undef,分别用于定义和取消定义条件编译符号. #if.#elif.#else 和 #endif,用于按条件跳过源代码中的节. #line,用于控制行号(在发布错误和警告信息

C/C++预处理指令#define,#ifdef,#ifndef,#endif…

本文主要记录了C/C++预处理指令,常见的预处理指令如下: #空指令,无任何效果 #include包含一个源代码文件 #define定义宏 #undef取消已定义的宏 #if如果给定条件为真,则编译下面代码 #ifdef如果宏已经定义,则编译下面代码 #ifndef如果宏没有定义,则编译下面代码 #elif如果前面的#if给定条件不为真,当前条件为真,则编译下面代码 #endif结束一个#if……#else条件编译块 #error停止编译并显示错误信息 本来只是想了解一下#ifdef,#ifnd

17-C语言预处理指令3-文件包含

说明:这个C语言专题,是学习iOS开发的前奏.也为了让有面向对象语言开发经验的程序员,能够快速上手C语言.如果你还没有编程经验,或者对C语言.iOS开发不感兴趣,请忽略 这讲介绍最后一个预处理指令---文件包含 一.基本概念 其实我们早就有接触文件包含这个指令了, 就是#include,它可以将一个文件的全部内容拷贝另一个文件中. 二.一般形式 1.第1种形式#include <文件名> 直接到C语言库函数头文件所在的目录中寻找文件 2.第2种形式 #include "文件名&quo

《黑马程序员》预处理指令(宏定义、条件编译、文件包含)(C语言)

宏定义的基本概念 ●  预处理指令都是以#开头 ●  预处理指令分为三种 1.宏定义 定义格式:#define  宏名   参数 2.条件编译 #if 条件语句     statement1; #elif 条件语句     statement2; #else     statement3; #endif       //条件编译结束必须加上此条语句,否则statement3以下的所有语句都将默认为不编译 3.文件包含 ●  预处理指令在代码翻译成0和1之前进行 ●  预处理指令的位置是可以写的

15-C语言预处理指令1-宏定义

预处理指令简介 1.C语言在对源程序进行编译之前,会先对一些特殊的预处理指令作解释(比如之前使用的#include文件包含指令),产生一个新的源程序(这个过程称为编译预处理),之后再进行通常的编译 2.为了区分预处理指令和一般的C语句,所有预处理指令都以符号"#"开头,并且结尾不用分号 3.预处理指令可以出现在程序的任何位置,它的作用范围是从它出现的位置到文件尾.习惯上我们尽可能将预处理指令写在源程序开头,这种情况下,它的作用范围就是整个源程序文件 4.C语言提供的预处理指令主要有:宏