嵌入式Linux C(十)——编译预处理

一、宏定义指令

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# 没有开启

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周末不下雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值