一、宏定义指令
1.0前言
宏一定要大写
预处理:
预处理主要任务:1.头文件展开 2. 宏替换 3. 条件编译 gcc -E
头文件展开:#include <> VS #include “”
<>:包含系统定义的头文件(/usr/include),搜索路径:/usr/onclude 系统的头文件目录
“”:包含自定义的头文件,搜索路径:现在当前目录查找,再到系统头文件目录查找
gcc -l 指定头文件第三方
1.1 定义常量与命令
宏替换
1.宏语法:#define NAME Value
2.替换逻辑:傻瓜式替换 注意事项:使用()解决运算符优先级问题
3.作用:定义常量(杜绝幻数) 提高代码可读性
1.2 定义宏函数
普通自定义函数
开销大,:给形参分配空间
一系列操作:函数调用、函数返回、分配空间、释放空间(运行时间)
宏定义函数:频繁调用,且短小的函数,最好优化成宏函数(不安全)(do while(0)的作用)
傻瓜式替换,不占用空间,在预处理阶段编译(编译时间)
定义函数(宏函数):用编译时间换内存空间(用空间换运行时间:inline:修饰函数(不超过5行、不能要全局变量、静态变量、) 内嵌函数)
宏函数 VS 自定义函数
常用宏函数:(看课本)
1.3 内置宏定义
1.3.1 (#)
功能:是将其后面的宏参数进行字符串化操作
#include <stdio.h> #define WARN_IF(EXP) \ do \ { \ if(EXP) \ printf("%s\n",#EXP); \ }while(0) int main() { int num = 5; WARN_IF(num == 5); return 0; }
1.3.2 (##)
用于做连接
#define LINK_MULTPLE(a,b,c,d) a##_##b##_##c##_##d typedef struct _record_type LINK_MULTPLE(name,company,position,salary) typedef struct _record_type name_company_position_salary
1.3.2 内置宏
printf("%d\n",__ LINE );打印行号(调试,找错误,段错误) printf("%s:%d\n", func__,__ LINE__);加上所在函数 printf("%s",__ DATE__);显示日期 printf("%s",__ TIME__);显示时间
1.4 扩展
1.4.1 typedef与#define的区别
1.4.2 枚举与#define的区别
#undef 取消已定义的宏
二、条件编译指令
#if 如果给定条件为真,则编译下面代码 #ifdef 如果宏已经定义,则编译下面代码 #ifndef 如果宏没有定义,则编译下面代码 #elif 如果前面的#if给定条件不为真,当前条件为真,则编译下面代码,其实就是else if的简写 #else 跟else效果一样 #endif 结束一个#if……#else条件编译块 #error 停止编译并显示错误信息 #include <stdio.h> int main() { //条件编译:按照给定的条件编译代码(只影响编译不影响运行) printf("hello world\n"); printf("welcome to jsetc"); return 0; }
gcc demo7.c -DMAX_SIZE=1024 -o demo7
-D:向云文件定义一个宏 -D宏的名字
应用场景:
1.注释代码
2.debug_msg
3.防止头文件重复包含导致的重复定义的问题
#include <stdio.h> #ifndef __DEBUG__ #define debug_msg(fmt,args...) #else #define debug_msg(fmt,args...) printf(fmt,##args) #endif int main() { debug_msg("%s:%d\n",__TIME__,__LINE__); printf("hello world\n"); printf("welcome to jsetc\n"); return 0; }
gcc if#.c -D__DEBUG__ -o if# 开启调试
gcc if#.c -o if# 没有开启
//func1.h #ifndef __FUNC2_H__ #define __FUNC2_H__ int a = 5; #endif //最新 #pragma once int a = 5;
可以避免头文件重复包含导致的重复定义的问题
三、其他预处理指令
#include #define #undef 取消已定义的宏 #if 如果给定条件为真,则编译下面代码 #ifdef 如果宏已经定义,则编译下面代码 #ifndef 如果宏没有定义,则编译下面代码 #elif 如果前面的#if给定条件不为真,当前条件为真,则编译下面代码,其实就是else if的简写 #else 跟else效果一样 #endif 结束一个#if……#else条件编译块 #error 停止编译并显示错误信息
四、debug_msg的使用
#include <stdio.h> #ifndef __DEBUG__ #define debug_msg(fmt,args...) #else #define debug_msg(fmt,args...) printf(fmt,##args) #endif int main() { debug_msg("%s:%d\n",__TIME__,__LINE__); printf("hello world\n"); printf("welcome to jsetc\n"); return 0; }
gcc if#.c -D__DEBUG__ -o if# 开启调试
gcc if#.c -o if# 没有开启