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

简介: 嵌入式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;
}

0a2653c851af460fa595bd959398a8f1.png


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


相关文章
|
4天前
|
Linux 开发工具 C语言
Linux 安装 gcc 编译运行 C程序
Linux 安装 gcc 编译运行 C程序
22 0
|
23天前
|
JSON 机器人 Linux
推荐一款嵌入式Linux开源框架与封装-cpp-tbox
推荐一款嵌入式Linux开源框架与封装-cpp-tbox
54 3
|
1月前
|
Linux 开发工具 git
Linux嵌入式系统中如何使用U-Boot实例
Linux嵌入式系统中如何使用U-Boot实例
26 0
|
1月前
|
Linux Android开发
嵌入式linux中Framebuffer 驱动程序框架分析
嵌入式linux中Framebuffer 驱动程序框架分析
27 0
|
3天前
|
Linux 开发工具 Android开发
Docker系列(1)安装Linux系统编译Android源码
Docker系列(1)安装Linux系统编译Android源码
6 0
|
11天前
|
Linux 编译器 测试技术
嵌入式 Linux 下的 LVGL 移植
嵌入式 Linux 下的 LVGL 移植
|
24天前
|
Linux
嵌入式Linux系统(NUC980)tf卡出错处理errors=remount-ro改为errors=continue
嵌入式Linux系统(NUC980)tf卡出错处理errors=remount-ro改为errors=continue
7 1
|
24天前
|
安全 Linux
嵌入式Linux系统关闭串口调试信息的输出
嵌入式Linux系统关闭串口调试信息的输出
17 1
|
24天前
|
Linux 编译器 网络安全
嵌入式Linux移植dropbear
嵌入式Linux移植dropbear
19 3
|
24天前
|
存储 Ubuntu Linux
制作一个嵌入式Linux的应用程序升级文件
制作一个嵌入式Linux的应用程序升级文件
12 2