预处理是在编译之前的处理,而编译工作的任务之一就是语法检查,预处理不做语法检查。预处理命令以符号“#”开头。

  常用的预处理指令包括:

  • 宏定义:#define
  • 文件包含:#include
  • 条件编译:#if、#elif、#ifndef、#ifdef、#endif、#undef
  • 错误信息指令:#error
  • #line指令
  • 布局控制:#pragma

宏定义

  宏定义又称为宏代换宏替换,简称“宏”。宏替换只作替换,不做计算,不做表达式求解。宏定义分带参数的宏定义和不带参数的宏定义。在带参数的宏定义,宏名和参数的括号间不能有空格。

  宏定义不分配内存,变量定义分配内存。

  宏展开不占运行时间,只占编译时间;函数调用占运行时间(分配内存、保留现场、值传递、返回值)。

  出现在宏定义中的#运算符把跟在其后的参数转换成一个字符串,有时把这种用法的#称为字符串化运算符。例如:

#include<iostream>
using namespace std; #define STR(n)"abcd"#n int main()
{
cout<<STR()<<endl;
system("pause");
return ;
}

  输出结果为:

  ##运算符用于把参数连接到一起,预处理程序把出现在##两侧的参数合并成一个符号。例如:

#include<iostream>
using namespace std; #define STR(a,b,c) a##b##c int main()
{
cout<<STR(,,)<<endl;
system("pause");
return ;
}

  输出结果为:

文件包含

  #include<文件名>称为标准方式,到系统头文件目录查找文件,#include"文件名"则先在当前目录(用户路径)查找,而后到系统头文件目录查找。

  我们以#include<iostream.h>和#include<iostream>为例说明:iostream.h是C语言格式的头(库)文件,为旧版本的标准库,只支持窄字符集;而iostream为C++的标准头文件,支持窄字符集和宽字符集。

  被包含文件中的静态全局变量不用在包含文件中声明

条件编译

  使用条件编译可以使目标程序变小,运行时间变短。

  #undef指令,用来删除事先定义的宏定义, 其一般形式为:#undef 宏替换名

错误信息指令

  #error指令,该指令用于程序的调试,输出一个错误信息,当编译中遇到#error指令就停止编译。其一般形式为: #error 出错信息。

#ifndef __cplusplus
#error this is not a C++ complier.
#endif
#include<iostream>
using namespace std;
int main()
{
system("pause");
return ;
}

#line指令

  命令#line改变_LINE__FILE_的内容,它们是在编译程序中预先定义的标识符。

  其格式为:#line number [ filename ],这条指令可以改变当前的行号和文件名。

#include<iostream>
using namespace std; #line 100 "a.cpp" int main()
{
cout<<__LINE__<<'\t'<<__FILE__<<endl;
system("pause");
return ;
}

  运行结果:

布局控制指令

  在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。

  其格式一般为: #pragma Para,其中Para 为参数。

message 参数:在编译信息输出窗口中输出相应的信息

#pragma message("消息文本")

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

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

#pragma once

  只要在头文件的最开始加入这条指令就能够保证头文件被编译一次,但移植性差。如果写的程序要跨平台,最好使用C++中的宏定义。

#pragma hdrstop:表示预编译头文件到此为止,后面的头文件不进行预编译。

#pragma resource

#pragma resource "winform.dfm"

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

#pragma warning:输出警告信息。

我们运行一下程序:

int main()
{
float f=3.6;
int i=f;
cout<<i<<endl;
system("pause");
return ;
}

会出现如下警告信息:

>ClCompile:
>f.cpp
>c:\users\gaohongchen\desktop\\\\f.cpp(): warning C4305: “初始化”: 从“double”到“float”截断
>c:\users\gaohongchen\desktop\\\\f.cpp(): warning C4244: “初始化”: 从“float”转换到“int”,可能丢失数据

若我们在程序上方添加:

#pragma warning(disable:4305)

则编译时警告信息会变为:

>ClCompile:
>f.cpp
>c:\users\gaohongchen\desktop\\\\f.cpp(): warning C4244: “初始化”: 从“float”转换到“int”,可能丢失数据

若我们在程序上方添加:

#pragma warning(error:4244)

则警告信息会变为错误信息:

>ClCompile:
>f.cpp
>c:\users\gaohongchen\desktop\\\\f.cpp(): warning C4305: “初始化”: 从“double”到“float”截断
>c:\users\gaohongchen\desktop\\\\f.cpp(): error C4244: “初始化”: 从“float”转换到“int”,可能丢失数据

#pragma comment:该指令将一个注释记录放入一个对象文件或可执行文件中。

  常用的lib关键字,可以帮我们连入一个库文件。例如:

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

#pragma disable:在函数前声明,只对一个函数有效。该函数调用过程中将不可被中断。一般在C51中使用较多。

#pragma pack(x):改变编译器的对齐方式,编译器默认对齐为8,C++固有类型的对齐取编译器对齐方式与自身大小中较小的一个

相关链接:

  Predefined Macros:https://msdn.microsoft.com/en-us/library/b0084kay(v=vs.140).aspx

C/C++常用预处理指令的更多相关文章

  1. #pragma常用预处理指令

    #pragma pack(1):1字节对齐#pragma once:指定头文件被编译一次#pragma message("message"):编译时输出message文本#prag ...

  2. 常用C/C++预处理指令详解

    预处理是在编译之前的处理,而编译工作的任务之一就是语法检查,预处理不做语法检查.预处理命令以符号“#”开头. 常用的预处理指令包括: 宏定义:#define 文件包含:#include 条件编译:#i ...

  3. VC中预处理指令与宏定义详解

    刚接触到MFC编程的人往往会被MFC 向导生成的各种宏定义和预处理指令所吓倒,但是预处理和宏定义又是C语言的一个强大工具.使用它们可以进行简单的源代码控制,版本控制,预警或者完成一些特殊的功能. 一个 ...

  4. C#中的预处理指令

    C#中的预处理指令 作为预处理中的一对:#region name ,#endregion可能是大家使用得最多的,我也常用它来进行代码分块,在一个比较长的cs文件中,这么做确实是一件可以让你使代码更清晰 ...

  5. iOS预处理指令

    预处理过程扫描源代码,对其进行初步的转换,产生新的源代码提供给编译器.可见预处理过程先于编译器对源代码进行处理. 预处理指令是以#开头的代码行,#后是指令关键字,在关键字和#号之间允许存在任意个数的空 ...

  6. #pragma预处理指令讲解

    在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的 ...

  7. 预处理指令中#Pragma

    在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的 ...

  8. #pragma 预处理指令详解

    源地址:http://blog.csdn.net/jx_kingwei/article/details/367312 #pragma  预处理指令详解              在所有的预处理指令中, ...

  9. C++中的#pragma 预处理指令详解

    源地址:http://blog.csdn.net/roger_77/article/details/660311 在所有的预处理指令中,#pragma 指令可能是最复杂的了,它的作用是设定编译器的状态 ...

随机推荐

  1. LinQ to sql 各种数据库查询方法

    1.多条件查询: 并且 && 或者 || var list = con.car.Where(r => r.code == "c014" || r.oil == ...

  2. SSM综合练习

    CRM系统 CRM项目外观 1. 开发环境 IDE: Eclipse Neon Release (4.6.0) Jdk: 1.8 数据库: MySQL 2. 创建数据库 创建crm数据库,这里使用的是 ...

  3. Makefile编写参考

    http://www.ruanyifeng.com/blog/2015/02/make.html

  4. 面试真题--------spring源码解析AOP

    接着上一章对IOC的理解之后,再看看AOP的底层是如何工作的. 1.实现AOP的过程    首先我们要明白,Spring中实现AOP,就是生成一个代理,然后在使用的时候调用代理. 1.1 创建代理工厂 ...

  5. vim字符串替换及小技巧

    vi/vim 中可以使用 :s 命令来替换字符串.以前只会使用一种格式来全文替换,今天发现该命令有很多种写法(vi 真是强大啊,还有很多需要学习),记录几种在此,方便以后查询. :s/vivian/s ...

  6. socat流量操控

    被称为nc++,双向数据流通道工具. 假设有这样一个场景 相互通信 创建服务器端,侦听2222端口 socat - tcp4-listen:2222 查看2222端口是否打开 netstat -pan ...

  7. SSM的例子-参考

    ssm的例子:http://blog.csdn.net/double030/article/details/63683613

  8. vs中更改项目名称注意事项

    1,项目属性中的所有需要改的地方,还有程序集名称. 2,解决方案用记事本打开更改启动路径. 3,重新加载即可.

  9. 第四章 栈与队列(c2)栈应用:括号匹配

  10. JAVA 关于JNI本地库加载

    1.调用JNI的时候,通常我们使用System.loadLibrary(String libname)来load JNI library, 同样也可以使用System.load(String file ...