预处理
DEMO:
开发一个 C语言程序,让它暂停 5 秒以后再输出内容 “helllo” ,并且要求跨平台,在 Windows 和 Linux 下
#include <stdio.h>
//说明:在windows 操作系统和 linux操作系统下,生成源码不一样!!!
#if _WIN32 //如果是windows平台, 就执行
#include <windows.h>
#elif __linux__ //否则判断是不是linux ,如果是linux 就引入<unistd.h>
#include <unistd.h>
#endif
int main() {
//不同的平台下调用不同的函数
#if _WIN32 //识别windows平台
Sleep(5000); //毫秒
#elif __linux__ //识别linux平台
sleep(5); //秒
#endif
puts("hello"); //输出
getchar();
return 0;
}
宏定义
#define 宏名 字符串
- 就是用 一个标识符来表示字串
- 程序中反复使用的表达式就可以宏定义,注意加括号
- 简单的替换。字符串中可以含任何字符, 它可以是常数、 表达式、if 语句、 函数等 ,预处理程序对它不作任何检查,如有错误只能在编译已被宏展开后的源程序时发现
- 宏定义不是说明或语句,在行末不必加分号,如加上则连分号也一起替换
- 宏定义必须写在函数之外,其作用域为命令起到源程序结束,如要终止其作用域可使#undef命令
- 代码中的宏名如果被引号包围 ,那么预处理程序不对其作宏代替
- 宏定义允许嵌套 ,在宏定义的字符串中可以使用已经名 ,在宏展开时由预处理程序层层替换
- 习惯宏名用大写字母表示
- 可用宏定义表示数据类型,使书写方便 #define UINT unsigned int
- typedef 是在编译阶段由器处理的 ,它并不是简单的字符串替换,而给原有数据类型起一个新的名字,作为一种新的数据类型
带参数的宏定义
#define 宏名 (形参列表) 字符串
DEMO:
#include <stdio.h>
//说明
//1. MAX 就是带参数的宏
//2. (a,b) 就是形参
//3. (a>b) ? a : b是带参数的宏对应字符串,该字符串中可以使用形参
#define MAX(a,b) (a>b) ? a : b
int main(){
int x , y, max;
printf("input two numbers: ");
scanf("%d %d", &x, &y);
//说明
//1. MAX(x, y); 调用带参数宏定义
//2. 在宏替换时(预处理,由预处理器), 会进行字符串的替换,同时会使用实参, 去替换形参
//3. 即MAX(x, y) 宏替换后 (x>y) ? x : y
max = MAX(x, y);
printf("max=%d\n", max);
getchar();
getchar();
return 0;
}
注意
- 带参宏定义中,形参之间可以出现空格 但是宏名和列表不能有空格
- 在带参宏定义中,不会为形式数分配内存,因此不必指明据类型。而在宏调用中,实参包含了具体的数据,要用它们去替换形参,因此实参必须指明数据类型
- 在宏定义中,字符串内的形参通常要用括号起来以避免出错
带参宏定义&函数
- 宏展开仅是字符串的替换,不会对表达式进行计算;宏在编译之前就被处理掉 了,它没有机会参与编译也不占用内存 。
- 函数是一段可以重复使用的代码, 会被编译给它分配内存每次调函就是执行这块内存中的代码