1、LINE 表示正在编译的文件的行号,
2、FILE 表示正在编译的文件的名字,
3、DATE 表示编译时刻的日期字符串,
4、TIME 表示编译时刻的时间字符串,
5、STDC 判断该文件是不是定义成标准C程序。
1、数值宏常量
#define PI 3.141592654
#define ERROR_POWEROFF -1
2、字符串宏常量
#define ENG_PATH_1 E:\English\listen_to_this\listen_to_this_3
3、用define 宏定义注释符号“ ? ”
#define BSC //
#define BMC /*
#define EMC */
(D) BSC my single-line comment
(E) BMC my multi-line comment EMC
(D) 和 (E) 都是错误的 ,原因:注释先于预处理指令被处理,当这两行被展开成“ // … ” 或 “/ * … * /” 时,注释已经处理完毕,此时再出现“ // … ” 或 “/ * … * /”自然错误。因此,试图用宏开始或结束一段注释是不行的。
4、用define 宏定义表达式
(1)使用宏定义表达式时,不要吝啬括号。
(2)宏函数被调用时,是以实参代换形参,而不是 “ 值传送 ”
5、宏定义中的空格
#define SUM (x) (x) + (x)
定义了一个宏:SUM 其代表的是(x) (x) + (x)
空格仅在定义的时候有效,在使用这个宏函数的时候 ,空格会被编译器忽略。
6、#undef
(1)作用:用来撤销宏定义
(2)宏的生命周期从#define开始到 #undef 结束
1、条件编译的功能:使得我们可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。
2、条件编译的三种形式:
① #ifdef 标识符
程序段1
#else
程序段2
#endif
② #ifndef 标识符
程序段1
#else
程序段2
#endif
③ #if 常量表达式
程序段1
#else
程序段2
#endif
1、文件包含是预处理的一个重要功能,它将多个源文件链接成一个源文件进行编译,结果生成一个目标文件。
2.文件包含的两种形式:
格式一:
#include
亦称头文件
表示预处理要到系统规定的路径中去获得这个文件(即C编译系统提供的
并存放在指定子目录下的头文件),找到文件后,用文件内容替换该语句。
格式二:
#include "filename"
表示预处理应在当前目录中查找文件名为filename的文件;若没有找到,
则按系统指定的路径信息搜素其他目录。找到文件后,用文件内容替换该语句
注意:#include 是将已存在文件的内容,嵌入到当前的文件中。
#include 支持相对路径,. 代表当前目录 , ..代表上层目录
1、作用:编译程序时,只要遇到 #error 就会生成一个编译错误提示错误,并停止编译。
#error error_message
1、作用:改变当前行数和文件名称,它们是在编译程序中预先定义的标识符。
#line number[ "filename" ] [ ]内的文件名可省略
eg:#line 30 a.h 改变当前的行号为30,文件名为 a.h
2、我们知道编译器对C源码编译的过程中会产生一些中间文件,通过这条指令,可以保证文件名是固定的,不会被这些中间文件代替,有利于分析。
1、作用:设定编译器的状态或者是指示编译器完成一些特定的动作。
2、格式:
#pragma para
para 为参数
3、#pragma message
#pragma message("消息文本") 当编译器遇到这条指令,就会在
编译 窗口中将消息文本打印出来
#ifdef_X86
#pragma message("_X86 macro activated!")
#endif
检查自己是否定义了 _X86 这个宏,如果定义了,编译窗口就会输出
_X86 macro activated!
4、#pragma code_seg
#pragma code_seg(["section - name"[, "section - class"]])
他能够设置程序中函数代码存放的代码段,当我们开发程序驱动时就会使用到他。
5、#pragma once
只要在头文件的最开始加入这条指令 就能够保证头文件被编译一次。
6、#pragma hdrstop
表示 预编译头文件到此为止,后面的头文件不进行预编译。
可以用 #pragma startup指定编译优先级,如果使用了 #pragma package(smart_init) ,BCB 就会根据优先级的大小先后编译。
7、#pragma resource
#pragma resource " *.dfm " 表示把 *.dfm 文件中的资源加入工程。
*.dfm 中包括窗体外观的定义
8、#pragma warning
#pragma warning(disable: 4507 34; once: 4385; error: 164)
含义:不显示 4507 和34 号警告信息
4385号警告信息仅报告一次
把164号警告信息作为一个错误
9、#pragma comment
#pragma comment( ... )
该指令将一个注释记录放入一个对象文件或可执行文件中
10、#pragma pack
(1) 内存对齐
struct TestStruct1
{
char c1;
short s;
char c2;
int i;
};
sizeof(TestStruct1) = 12
(2)如何避免内存对齐的影响
struct TestStruct2
{
char c1;
char c2;
short s;
int i;
};
sizeof(TestStruct2) = 8
#pragma pack(n) //编译器将按照n字节对齐
#pragma pack() //编译器将取消自定义字节对齐方式
(3)对齐的规则:每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是n字节)中较小的一个对齐,即min(n, sizeof(item)),并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节。
注意:
①:每个成员分别按照自己的方式对齐,并能最小化长度
②:复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在
成员是复杂类型时,可以最小化长度
③:对齐后的长度必须是成员中最大的对齐参数的整数倍。这样在处理数组时
可以保证每一项都边界对齐。
char a[3] 对齐方式:按1字节对齐
1、字符串中包含宏参数,可以使用“#”,可以把语言符号转化为字符串。
#define SQR(x) printf("The square of " #x " is %d. \n", ((x) * (x)));
SQR(8)
输出:The square of 8 is 64.
1、也可以用于宏函数的替换部分,这个运算符把两个语言符号组合成单个语言符号
#define XNAME(n) x ## n
XNAME(8)
被展开为:x8
“ ## ” 就是个粘合剂,将前后两部分粘合起来。