预处理命令
- 编译:对源程序进行词法、语法分析,生成代码,优化等
- 作用:在编译之前,对源程序中的特殊命令做一些处理,生成拓展C源程序
宏定义
不带参数的宏定义
- 一般形式:#define 标识符 字符串
- 功能:用指定标识符(宏名)代替字符串(宏体)
#define YES 1 #define NO 0 #define PI 3.1415926 #define OUT printf("Hello, World!");
- 定义位置:任意 一般在函数外面
- 作用域:从命令到文件结束
- #undef可以中止宏名作用域
#define YES 1 func1() { cout << "YES " << YES << endl; //在此处 YES 的值为1 } #undef YES // 此处YES没有定义 //func2() //{ // cout << "YES " << YES << endl; // // [Error] 'YES' was not declared in this scope //} #define YES 0 func3() { cout << "YES " << YES << endl; //此处YES值为0 }
- 宏名一般用大写字母,与变量区分
- 使用宏便于修改变量值,提高程序通用性
- 宏展开 预编译时,用宏体替换宏名–不做语法检查
- 宏定义中使用必要的括号
例 #define WIDTH 80 #define LENGTH (WIDTH+40) var = LENGTH * 2; 宏展开:var= (80+40) *2;
- 宏定义可嵌套不能递归
例 #define MAX MAX+10 //error
带参数的宏定义
- 一般形式:#define 宏名(参数表) 宏体
- 功能:进行字符串替换,并进行参数替换
- 宏展开:形参用实参换,其他字符保留
- 宏体外各形参外一般应加括号()
文件包含
- 功能:一个源文件可以将另一个源文件的内容全部包含进来
- 一般形式:#include<文件名> 或 #includ “文件名”
- 处理过程:预编译时,用被包含的文件的内容取代该预处理命令,再将“包含后的文件”作为一个源文件单位进行编译,得到目标文件.obj
- 被包含的文件内容可以是源文件也可以是头文件
- 文件包含可以嵌套
条件编译
- 功能:当文件中的部分内容在满足一定条件才能编译
- 几种形式:
- 标识符已被#define命令定义过,则编译程序段1,反之编译程序段2
#ifdef 标识符 程序段1 #else 程序段2 #endif
- 标识符未被#define命令定义过,则编译程序段1,反之编译程序段2
#ifndef 标识符 程序段1 #else 程序段2 #endif
- 表达式为真,则编译程序段1,否则编译程序段2
#if 表达式 程序段1 #else 程序段2 #endif
- 标识符已被#define命令定义过,则编译程序段1,反之编译程序段2
结构体与共用体
- 结构体类型定义
注意结构体类型定义仅描述结构体组成,不分配内存空间struct [结构体名] // 结构体名可以缺省,即可以定义无名结构体 { 类型标识符 成员名1; 类型标识符 成员名2; ... ... ... ... }; // 分号';'不能省略
- 定义结构体变量的3种方法
- 先声明结构体类型,再定义结构体变量
struct [结构体名] { 类型标识符 成员名; 类型标识符 成员名; ... ... ... ... }; struct 结构体名 变量名表列;
- 声明结构体类型的同时定义结构体变量
struct [结构体名] { 类型标识符 成员名; 类型标识符 成员名; ... ... ... ... }变量名表列;
- 直接定义结构体类型变量
struct { 类型标识符 成员名; 类型标识符 成员名; ... ... ... ... }变量名表列;
- 注意
1.结构体类型与结构体变量概念不同
2.结构体变量中的成员可单独使用,方法如普通变量
3.结构体可以嵌套
4.结构体成员名与程序中变量名可以相同,二者不代表同一个对象 - 结构体变量的引用
1.结构体变量不能整体引用,只能引用变量成员:结构体变量名.成员名
2.结构体成员本身又是一个结构体类型,则需要找到最低一级的成员
3.结构体变量的成员与普通变量用法相同