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


相关文章
|
23天前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
73 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
27天前
|
Linux 编译器 C语言
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
|
9天前
|
Linux
Linux - 如何编译源码安装软件
源码编译安装通常包括三个步骤:1) `./configure` 检测平台特征和依赖项,生成 Makefile;2) `make` 编译源码,生成可执行文件;3) `make install` 将可执行文件安装到指定目录并配置环境变量。
24 0
|
1月前
|
Linux 编译器 C语言
Linux c/c++之多文档编译
这篇文章介绍了在Linux操作系统下使用gcc编译器进行C/C++多文件编译的方法和步骤。
37 0
Linux c/c++之多文档编译
|
26天前
|
Linux 开发工具
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
|
2月前
|
Linux
用clang编译Linux内核
用clang编译Linux内核
|
3月前
|
Linux C语言
深度探索Linux操作系统 —— 编译过程分析
深度探索Linux操作系统 —— 编译过程分析
27 2
|
3月前
|
NoSQL Linux C语言
嵌入式GDB调试Linux C程序或交叉编译(开发板)
【8月更文挑战第24天】本文档介绍了如何在嵌入式环境下使用GDB调试Linux C程序及进行交叉编译。调试步骤包括:编译程序时加入`-g`选项以生成调试信息;启动GDB并加载程序;设置断点;运行程序至断点;单步执行代码;查看变量值;继续执行或退出GDB。对于交叉编译,需安装对应架构的交叉编译工具链,配置编译环境,使用工具链编译程序,并将程序传输到开发板进行调试。过程中可能遇到工具链不匹配等问题,需针对性解决。
|
3月前
|
Ubuntu Linux Windows
如何在WSL中的ubuntu编译Linux内核并且安装使用ebpf?
请注意,在WSL1中可能会由于内核架构限制而无法成功进行以上过程,WSL2对于Linux内核的完整支持更为合适。此外,部分步骤可能因不同的Linux发行版或内核版本而异。
159 4
|
3月前
|
传感器 人工智能 网络协议
:嵌入式 Linux 及其用途
【8月更文挑战第24天】
164 0
下一篇
无影云桌面