Linux入门DAY12
#嵌入式开发基础##Linux##C语言#前言本篇笔记梳理Linux下gcc四阶段编译流程、C预处理全套语法宏、头文件、条件编译与指针核心知识点是嵌入式Linux C开发的基础重点。预处理负责文本替换指针直接操作内存地址二者结合是函数传地址、数组操作、底层开发的核心。一、gcc编译四阶段Day12 开篇完整流程 main.c → 预处理 → 编译 → 汇编 → 链接 → a.out1. 预处理-E作用展开 # 开头代码处理头文件、宏、条件编译命令 gcc -E main.c -o main.i处理内容 #include 、 #define 、 #if/#endif 条件编译2. 编译-S作用C代码转为汇编指令命令 gcc -S main.i -o main.s3. 汇编-c作用汇编指令转为二进制目标文件命令 gcc -c main.s -o main.o4. 链接无参数作用链接系统库函数、整合目标文件生成可执行程序命令 gcc main.o -o main二、预处理命令1. 宏定义 #define1无参宏常量语法 #define 标识符 替换文本⚠ 核心注意点1. 预处理阶段纯文本替换不做运算2. 宏标识符推荐大写定义末尾不能加分号3. 表达式宏建议整体加括号避免优先级错误4. 宏vs函数宏是文本替换无调用开销代码膨胀函数运行时调用保存/恢复栈帧5. 大量使用宏会增大程序体积。2带参宏宏函数语法 #define 标识符(参数1,参数2) 实现 。规则传参只写变量名不能加数据类型。2. 头文件包含 #include1. 头文件 系统头文件编译器去 /usr/include 查找2. 头文件 自定义头文件从当前工程目录查找自定义头文件可存放内容- 嵌套包含其他头文件- 自定义数据类型struct/enum- 宏定义- 函数、全局变量声明3. 条件编译两大用途用途1防止头文件重复包含头文件保护宏#ifndef 宏名#define 宏名// 头文件全部内容#endif逻辑宏未定义则编译内部代码已定义直接跳过。用途2代码分段编译、屏蔽代码1. #if 逻辑表达式 表达式为真才编译中间代码 #if 0 可永久屏蔽代码2. #ifdef 宏名 宏已定义则编译代码1搭配 #else 实现二选一编译#ifdef PI//代码1#else//代码2#endif三、指针全套知识点1. 内存、地址、指针基础概念- 内存程序运行可访问的存储空间以字节为最小单位- 地址内存每个字节的编号- 指针 地址代表一块内存空间的编号- 指针变量专门存放地址的变量占用独立内存。2. 指针变量定义语法 基类型 * 变量名;- 基类型指针指向内存存储的数据类型- * 标识该变量是指针- 大小64位系统占8字节32位系统占4字节与指向类型无关。3. 指针初始化与野指针1. 野指针未初始化、指向已释放内存的指针直接访问会崩溃2. 规避方案- 初始化赋值 NULL 数值0直接赋值已有普通变量的地址。4. 两大核心运算符1取地址运算符 作用获取变量首字节地址规则- 只能作用于变量不能给常量、表达式取地址- 变量 拿到变量起始内存地址。2解引用运算符 *作用访问指针指向内存里的数据规则1. 仅放在指针变量左侧使用2. *指针 等价于指针指向的普通变量3. 读写字节数由指针基类型决定 int* 读写4字节。5. 指针算数运算1. 无意义运算 * / % 不能用于指针2. 指针±整数 p1 向后偏移 sizeof(基类型) 字节 p-1 向前偏移3. 指针-指针仅同类型指针可相减结果为两个地址间元素个数 (地址差 / sizeof(基类型)) 。6. 指针作为函数参数传地址核心考点1. 修改主函数变量传递变量地址函数内通过 * 修改原值2. 只读使用变量传值/传地址均可3. 多返回值传入外部变量地址函数内部写入结果。7. 指针与一维数组1. 数组名是首元素地址常量不能赋值修改2. 下标等价写法- a[0] ↔ *a- a[1] ↔ *(a1)- a[n] ↔ *(an)3. 数组做函数参数时底层会退化为对应类型指针。小结1. 预处理是编译第一阶段核心完成文本替换宏、头文件、条件编译是开发高频工具头文件保护宏是工程必备规范2. gcc四阶段编译命令需熟记可单独生成.i/.s/.o中间文件用于调试底层代码3. 指针本质是内存地址 取地址、 * 解引用是基础操作算数偏移遵循基类型字节大小4. 传地址调用是指针核心应用实现函数修改变量、多返回值、数组批量操作是测井嵌入式、Linux C课程设计的高频考点5. 数组名等价首元素指针下标与指针写法可以互相转换是遍历数组的两种实现方式。