目录
1.宏定义
1.1数值宏定义
const 修饰的数据是有类型的,而 define 宏定义的数据没有类型。
建议以后在定义一些宏常数的时候用 const 代替,编译器会给 const 修饰的只读变量做类型校验,减少错误的可能。
const 修饰的只读变量不能用来作为定义数组的维数, 也不能放在 case 关键字后面//C语言规定数组下标必须是常量,只读变量也不可以
1.2字符串宏常量
经常使用定义路径上,注意宏定义只是简单的替换,因此路径不需要加双引号
#define ENG_PATH_4 E:\\English\\listen_to_this\\listen_to_this_3
1.3不能用define宏定义注释符号,因为注释的处理先于预处理指令,所以不能用宏定义代替//、/*、*/
1.4用 define 宏定义表达式
宏函数被调用时是以实参替代形参,而不是值传送。
举例#define SQR (x) x * x
如果x=10+1,SQR (x)被替换后变成 10+1*10+1
解决办法:#define SQR (x) ((x)*(x))//注意最外层的括号也不要省略
1.5#define SUM (x) (x)+(x)SUM后面的第一个空格会被省略,后面一个不会
1.6#undef 撤销宏定义
#define PI 3.141592654
#undef PI
{
#define X 3
#define Y X*2
#undef X
#define X 2
int z=Y;
z 的值为多少?
z=4 宏定义在使用的时候才替换
}
2.条件编译
第一种形式:如果标识符被定义过则编译程序段1,否则编译程序段2。也可以没有#else
#ifdef 标识符
程序段 1
#else
程序段 2
#endif
第二种:如果标识符没被定义过则编译程序段1,否则编译程序段2。
#ifndef 标识符
程序段 1
#else
程序段 2
#endif
第三种形式:如常量表达式的值为真(非 0),则对程序段 1 进行编译,否则对程序段 2 进行编译
#if 常量表达式
程序段 1
#else
程序段 2
#endif
#elif 命令意义与 else if 相同
3.文件包含
C语言提供#include 命令来实现文件包含的操作,它实际是宏替换的延伸,有两种格式:
格式 1:
#include <filename>:其中,filename 为要包含的文件名称,用尖括号括起来,也称为头文件,表示预处理到 系统规定的路径中去获得这个文件(即 C 编译系统所提供的并存放在指定的子目录下的头文件)。找到文件后,用文件内容替换该语句。
格式 2:
#include “filename”
其中,filename 为要包含的文件名称。双引号表示预处理应在当前目录中查找文件名为filename 的文件,若没有找到,则按系统指定的路径信息,搜索其他目录。找到文件后,用文件内容替换该语句。
4.#error 预处理指令
作用是,编译程序时,只要遇到 #error 就会生成一个编译错误提示消息,并停止编译。其语法格式为:
#error error-message
宏串 error-message 不用双引号包围。
5.#line
作用是改变行数和文件名称
#line number["filename"]
number从这一条命令的下一行开始生效
6.#pragma 预处理
设定编译器的状态或者是指示编译器完成一些特定的动作
6.1#pragma message(“消息文本”) 当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来
6.2#pragma code_seg
格式如:
#pragma code_seg( ["section-name"[,"section-class"] ] )
设置程序中函数代码存放的代码段,当我们开发驱动程序的时候就会使用到它。
6.3#pragma once
只要在头文件的最开始加入这条指令就能够保证头文件被编译一次
6.4#pragma hdrstop 表示预编译头文件到此为止,后面的头文件不进行预编译。
6.5#pragma resource "*.dfm"表示把*.dfm 文件中的资源加入工程。
6.6#pragma warning
6.7#pragma comment(...) 该指令将一个注释记录放入一个对象文件或可执行文件中
6.8#pragma pack
使用指令#pragma pack (n),编译器将按照 n 个字节对齐,n可以取1,2,4,8,16。
使用指令#pragma pack (),编译器将取消自定义字节对齐方式。
//补充的内存对齐部分可参看http://t.csdn.cn/bP4R7
为什么需要内存对齐:为了 提高程序的性能,数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为 了访问未对齐的内存,处理器需要作两次内存访问;然而,对齐的内存访问仅需要一次访问。
pragma pack(show) //显示当前内存对齐的字节数,编辑器默认8字节对齐。
内存对齐能提高性能,但有时候会占用更多空间。
7.#运算符
#define SQR(x) printf("The square of "#x" is %d.\n", ((x)*(x)));
再使用:
SQR(8);
则输出的是:
The square of 8 is 64.
8.##运算符
#define XNAME(n) x ## n
如果这样使用宏:
XNAME(8)
则会被展开成这样:
x8
##就是个粘合剂,将前后两部分粘合起来