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

  常用的预处理指令包括:

  • 宏定义:#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. vue.js入门操作

    1.vue框架是经典的MVVM模式, .vue文件是模板文件模板文件又分为3个部分一 <template></template>(html部分)二 <script> ...

  2. CSS----学习

    CSS---表现层,修饰和表现html文档,为了解决结构层和表现层分离的问题. 通过CSS极大的提高了工作效率,方便工作人员维护和管理CSS:层叠样式表,目前用的最广泛的css版本为css2,最新版本 ...

  3. 转载一篇必须超级好的JVM配置实战

    不管是YGC还是Full GC,GC过程中都会对导致程序运行中中断,正确的选择不同的GC策略,调整JVM.GC的参数,可以极大的减少由于GC工作,而导致的程序运行中断方面的问题,进而适当的提高Java ...

  4. appium桌面版本以及一些自动化测试方方封装

    appium_desktop 标签(空格分隔): appium_desktop 一 appium_desktop_v1.2.6 1.appium_desktop在github上最新下载地址:appiu ...

  5. js中switch/case分支的值可以是变量或表达式

    在一些高级语言如C#中,switch分支的值只能是常量,而js中可以是变量或表达式: <!DOCTYPE html> <html lang="en"> &l ...

  6. 搭建jsp渗透测试环境

    java运行环境下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html fir ...

  7. poi excel 加粗

    参考 https://blog.csdn.net/wellto/article/details/52293202 XSSFWorkbook xwb = new XSSFWorkbook(); ... ...

  8. linux下安装kafka

    安装条件: 确保zookeeper已经安装成功.zookeeper安装过程见:https://www.cnblogs.com/expiator/p/9853378.html 1.下载kafka 进入A ...

  9. 关于RAID的概述

    Raid 0:一块硬盘或者以上就可做raid0优势:数据读取写入最快,最大优势提高硬盘容量,比如3快80G的硬盘做raid0 可用总容量为240G.速度是一样.缺点:无冗余能力,一块硬盘损坏,数据全无 ...

  10. 3. Longest Substring Without Repeating Characters (ASCII码128个,建立哈西表)

    Given a string, find the length of the longest substring without repeating characters. For example, ...