第3章 预处理

预处理指令
预处理名称意义
#define宏定义。
#undef撤销已定义过的宏名。
#include使编译程序将另一源文件嵌入到带有#include的源文件中。
#if、#else、#elif、#endif#if的一般含义是如果#if后面的常量表达式为true,则编译它与#endif之间的代码,否则跳过这些代码。命令#endif标识一个#if块的结束。#else命令的功能有点像C语言中的else,#else建立另一选择(在#if失败的情况下)。#elif命令意义与else if相同,它形成一个if else-if阶梯状语句,可进行多种编译选择。
#ifdef、#ifndef用#ifdef与#ifndef命令分别表示“如果有定义”及“如果无定义”,是条件编译的另一种方法。
#line改变当前行数和文件名称,它们是在编译程序中预先定义的标识符。命令的基本上形式如下:#line number[“filename”]
#error编译程序时,只要遇到#error就会生成一个编译错误提示信息,并停止编译。
#pragma为实现时定义的命令,它允许向编译程序传送各种指令例如,编译程序可能有一种选择,它支持对程序执行的跟踪。可用#pragma语句指定一个跟踪选择。
ANSI标准C还定义了如下几个宏
宏名意义
_ LINE_表示正在编译的文件的行号
_ FILE_表示正在编译的文件的名字
_ DATE_表示编译时刻的日期字符串
_ TIME_表示编译时刻的时间字符串
_ STDC_判断该文件是不是定义成标准C程序

3.1 宏定义

3.1.1 数值宏常量

#define PI 3.141592654
#define ERROR_POWEROFF -1

​ const修饰的数据是有类型的,而define宏定义的数据没有类型。

3.1.2 字符串宏常量

​ 除了定义宏常数之外,经常还用来定义字符串,尤其是路径。

3.1.3 用define宏定义注释符号?

​ 试图用宏开始或结束一段注释是不行的。

3.1.4 用define宏定义表达式

​ 注意表达式一定要加括号

3.1.5 宏定义中的空格

​ 空格仅仅在定义的时候有效,在使用这个宏函数的时候,空格会被编译器忽略掉。

3.1.6 #undef

​ #undef是用来撤销宏定义的。

3.2 条件编译

​ 条件编译的功能使得我们可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件,这对于程序的移植和调试是很有用的。

#ifdef 标识符
程序段1
#endif

​ 如果标识符已被#define命令定义过则对程序段1进行编译。

​ #ifndef 标识符:如果标识符未被define命令定义过则对程序段1进行编译。

​ #if 常量表达式:如果常量表达式的值为真,则对程序段1进行编译。

3.3 文件包含

​ 文件包含是预处理的一个重要功能,它可以用来把多个源文件连接成一个源文件进行编译,结果将生成一个目标文件。

  • 格式一
#include <filename>

​ 其中,filename也称为头文件,表示预处理到系统规定的路径中去获得这个文件。找到文件后,用文件内容替换该语句。

  • 格式二
#include "filename"

​ 双引号表示预处理应当在当前目录中查找文件名为filename的文件,若没有找到,则按系统指定的路径信息,搜索其他目录。找到文件后,用文件内容替换该语句。

​ include支持相对路径。.代表当前目录,…代表上层目录。

3.4 #error预处理

​ #error预处理指令的作用是,编译程序时,只要遇到#error就会生成一个编译错误提示信息,并停止编译。

#error error-message

​ 注意,宏串error-message不用双括号包围。遇到#error指令时,错误信息被现实,同时可能还显示编译程序作者预先定义的其他内容。

3.5 #line预处理

​ #line的作用是改变当前行数和文件名称,它们是在编译程序文件中预先定义的标识符。

#line number["filename"]

​ 其中,[]内的文件名可以省略。编译器对C源码编译过程中会产生一些中间文件,通过这条指令,可以保证文件名是固定的,不会被这些中间文件代替,有利于进行分析。

3.6 #pragma预处理

​ 作用是设定编译器的状态或者是提示编译器完成一些特定的动作。

#pragma para

3.6.1 #pragma message

​ message参数:它能够在编译信息输出窗口中输出相应的信息,这对于源代码信息的控制是非常重要的。

#pragma message("消息文本")

​ 当编译器遇到这条指令时就在编译输出窗口中将信息文本打印出来。

3.6.2 #pragma code_seg

#pragma code_seg(["section-name"[,"section-class"]])

​ 它能够设置程序中函数代码存放的代码段,当我们开发驱动程序的时候就会使用到它。

3.6.3 #pragma once

#pragma once

​ 只要在头文件的最开始加入这条指令就能保证头文件被编译一次。

3.6.4 #pragma hdrstop

​ 表示预编译头文件到此为止,后面的头文件不能进行编译。

3.6.5 #pragma resource

#pragma resource "*.dfm"

​ 表示把*.dfm文件中的资源加入工程。 *.dfm中包括窗体外观的定义。

3.6.6 #pragma warning

#pragma warning(disable:4507 34; once:4385; error:164)
等价于
#pragma warning(disable:4507 34) //不显示4507和34号警告信息
#pragma warning(once:4385) //4385号警告信息仅报告一次
#pragma warning(error:164) //把164号警告信息作为一个错误

​ 同时这个pragma warning也支持如下格式:

#pragma warning(push) //保存所有警告信息的现有的警告状态
#pragma warning(push, n) //保存所有警告信息的现有的警告状态,并且把全局警告等级设定为n
#pragma warning(pop) //向栈中弹出最后一个警告信息,在入栈和出栈之间所做的一切改动取消

3.6.7 #pragma comment

#pragma comment(...)

​ 该命令将一个注释记录放入一个对象文件或可执行文件中。常用lib关键字,可以帮我们连入一个库文件。

#pragma comment(lib,"user32.lib")

​ linker:将一个链接选项放入目标文件中,你可以使用这个指令来代替由命令行传入的或者在开发环境中设置的链接选项,你可以指定/include选项来强制包含某个对象。

#pragma comment(linker,"/include:__mySymbol")

3.6.8 #pragma pack

#pragma pack(n) //编译器将按照n个字节对齐
#pragma pack() //编译器将取消自定义字节对齐方式

​ 在#pragma pack(n)和#pragma pack()之间的代码按n个字节对齐。

3.7 #运算符

​ 希望在字符串中包含宏参数,使用#,它可以把语言符号转化为字符串。

3.8 ##运算符

​ ##可以用于宏函数的替换部分,这个运算符把两个语言符号组合成单个语言符号。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值