一 #指令
单纯一个#号表示空指令,没有任何作用。
二 #include指令
#include <xxx.h>
#include "xxx.h"
三 #define、#undef指令
#define 标识宏名
#undef 取消定义的宏
#define PI 3.14
#undef PI
另外还有两个特殊的运算符:
# 字符串化运算符。
## 两侧的参数合并成一个符号(注意:并非合并为字符串,除非合并对像为字符串)
#define CAT(n) "ABC"#n
#define NUM(a,b) a##b
四 #if、#elif、#else、#endif指令
这几个指令称为条件编译指令,有选择地进行编译。
#define OPTION 2
#if OPTION == 1
cout << "Option: 1" << endl;
#elif OPTION == 2
cout << "Option: 2" << endl;
#else
cout << "Option: Illegal" << endl;
#endif
五 #ifdef、#ifndef、#endif指令
检查后面指定的宏是否已经定义指令。
#ifdef 表示”如果有定义
#ifndef 表示”如果没有定义“。
#ifndef MYHEAD_H
#define MYHEAD_H
#include "myHead.h"
#endif
六 #line指令
C语言中可以使用__FILE__表示本行语句所在源文件的文件名,使用__LINE__表示本行语句在源文件中的位置信息。#line指令可以重新设定这两个变量的值,其语法格式为
#line number["filename"]
其中第二个参数文件名是可省略的,并且其指定的行号在实际的下一行语句才会发生作用。
void test4()
{
cout << "Current File: " << __FILE__ << endl; //Current File: d:\test.cpp
cout << "Current Line: " << __LINE__ << endl; //Current Line: 48
#line 1000 "wrongfile"
cout << "Current File: " << __FILE__ << endl; //Current File: d:\wrongfile
cout << "Current Line: " << __LINE__ << endl; //Current Line: 1001
}
七 #error指令
#error指令在编译时输出编译错误信息,可以方便程序员检查出现的错误。
void test5()
{
#define OPTION 3
#if OPTION == 1
cout << "Option: 1" << endl;
#elif OPTION == 2
cout << "Option: 2" << endl;
#else
#error ILLEGAL OPTION! //fatal error C1189: #error : ILLEGAL OPTION!
#endif
}
八 #pragma指令
设定编译器的状态或者是指示编译器完成一些特定的动作,它有许多不同的参数。
1. #pragma once
在头文件的最开始加入这条指令可以保证头文件只被编译一次。它可以实现上述使用#ifndef实现不重复包含头文件同样的功能,但可能会有部分编译系统不支持。
2. #pragma message
该指令能够让编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。其使用方法为:#pragma message(“消息文本”),通过这条指令我们可以方便地记录在是否在源代码中定义过某个宏,如
#define ISPC
#ifdef ISPC
#pragma message("Macro ISPC is defined") //编译输出:Macro ISPC is defined
#endif
3. #pragma warning
该指令能够控制编译器发出警告的方式,其用法举例如:#pragma warning(disable : 4507 34; once : 4385; error : 164)
这个指令有三部分组成,其中disable部分表示忽略编号为4507和34的警告信息,once部分表示编号为4385的警告信息只显示一次,error部分表示把编号为164的警告信息当做错误。
另外,其还有两个用法
#pragma warning(push [, n]):保存所有警告信息的现有的警告状态,后面n是可选的,表示把全局警告等级设为n。
#pragma warning(pop):弹出最后一个警告信息,取消在入栈和出栈之间所作的一切改动。
具体例如如下:
void test6()
{
#pragma warning(push) //保存编译器警告状态
#pragma warning(disable:4305) //取消4305的警告
bool a = 5; //无警告信息
#pragma warning(pop) //恢复之前的警告
bool b = 5; // warning C4305: 'initializing' : truncation from 'int' to 'bool'
}
4. #pragma comment
该指令将一个注释记录放入一个对象文件或可执行文件中。其使用方法为:
#pragma comment(comment-type ,["commentstring"])
comment-type :是一个预定义的标识符,指定注释的类型,应该是compiler,exestr,lib,linker之一。
#pragma comment(lib, "my.lib") // lib关键字,可以帮我们连入一个库文件
5. #pragma hdrstop
该指令表示预编译头文件到此为止,后面的头文件不进行预编译。
6. #pragma resource
该指令表示把指定文件中的资源加入工程,如
#pragma resource "*.dfm"
7. #pragma code_seg
该指令能够设置程序中函数代码存放的代码段,开发驱动程序的时候会使用到。使用方法为:
#pragma code_seg(["section-name" [,"section-class"] ])。
8. #pragma data_seg
该指令建立一个新的数据段并定义共享数据。一般用于DLL中,在DLL中定义一个共享的有名字的数据段,这个数据段中的全局变量可以被多个进程共享,否则多个进程之间无法共享DLL中的全局变量。其使用方法为:
#pragma data_seg("MyData")
int value; //共享数据
#pragma data_seg()
9. #pragma pack
该指令规定数据在内存中的对齐长度,具体可以参考这里。
#pragma pack(1)
struct S{char a; int b; };
void test7(){ cout << sizeof(S) << endl; }