C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用
学习说明
- 课程来源:B站视频:【颠覆传统学习法】韦东山带你用STM32玩转C语言:内存指针+嵌入式双技能速成 ;
- 学习目标:掌握C语言底层语法在STM32硬件实操中的应用;
- 适用人群:嵌入式入门、想巩固C语言底层用法的学习者;
### 文章目录
- [C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [@[toc]](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [1、零碎知识点](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [2、指针/地址(**指针就是地址**)](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [2.1 指针基础](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [2.2 使用指针访问硬件](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [3、数组](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [3.1 数组名就是有个指针](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [3.2 多维数组](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [3.3 问题:](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [4、结构体](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [4.1 结构体指针](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [4.2 结构体指针访问硬件](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5、函数](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.1 参数传递与栈](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.2 递归函数](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.2.1 递归函数_栈使用情况](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.2.2 递归的注意事项](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.3 作用域](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.3.1 全局变量](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.3.2 局部变量](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.3.3 嵌套在代码块中的局部变量](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.3.4 静态变量(static)](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.4 头文件](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.4.1 常见头文件用途](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.4.2 头文件包含](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.4.3 防止重复包含](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.4.4 如何创建自己的`include`文件?](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.5 多文件编程](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.6 函数指针](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.6.1 声明语法](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.6.2 简单示例](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.6.3 函数指针作为参数](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.6.4 函数指针数组](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [5.6.5 结构体中的函数指针](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项) - [注意事项](#文章目录 C语言基础语法+STM32实践学习笔记 | 指针/寄存器核心应用 @[toc] 1、零碎知识点 2、指针/地址(指针就是地址) 2.1 指针基础 2.2 使用指针访问硬件 3、数组 3.1 数组名就是有个指针 3.2 多维数组 3.3 问题: 4、结构体 4.1 结构体指针 4.2 结构体指针访问硬件 5、函数 5.1 参数传递与栈 5.2 递归函数 5.2.1 递归函数_栈使用情况 5.2.2 递归的注意事项 5.3 作用域 5.3.1 全局变量 5.3.2 局部变量 5.3.3 嵌套在代码块中的局部变量 5.3.4 静态变量(static) 5.4 头文件 5.4.1 常见头文件用途 5.4.2 头文件包含 5.4.3 防止重复包含 5.4.4 如何创建自己的
include文件? 5.5 多文件编程 5.6 函数指针 5.6.1 声明语法 5.6.2 简单示例 5.6.3 函数指针作为参数 5.6.4 函数指针数组 5.6.5 结构体中的函数指针 注意事项)
1、零碎知识点
-
volatile:中文意思是易变的 (面试笔试常见问题)
- volatile int a;明确的告诉编译器,你不要来优化我;
-
volatile signed char c;表示有符号位的变量。
-
大/小 字节序 (面试笔试常见问题)
0x12345678 (高位 ==> 低位)
字节序 存储方式 小字节序(Little-endian) 低位数据存在低地址,主流 CPU 的默认选择。 大字节序(Big-endian) 低位数据存在高地址。 -
网络通信:TCP/IP 协议规定使用大端序作为网络字节序,保证不同架构设备之间的数据传输一致性(嵌入式设备 <=> x86 )
-
部分嵌入式 CPU:如传统 PowerPC、SPARC,以及 ARM 架构的大端模式配置(ARM 支持双端序,可通过寄存器配置)
-
-
typedef 使用
c
typedef int TNT_TYPT; //以后TNT_TYPE,和int一样,可以定义变量;
2、指针/地址(指针就是地址)
2.1 指针基础
cpu |
指针大小 |
|---|---|
| 32位(默认) | 4字节 (4*8 = 32) |
| 64位置 | 8字节 (8*8 = 64) |
c
char c = 'A';
char* addrc = &c; //char类型的指针 可以存入char类型变量的地址;
// char类型的指针addrc <==> char类型变量c
// 如果不知道变量类型,可强制转换类型: int* c = (int*)0x20000000;
*addrc = 'B'; //往该指针 指向地址 中的数值写入'B' //使用指针访问变量c这块内存;为什么可以?因为addrc等于c的地址
//int* p //p is point to int
// 指针大小
char a = 1;
int b = 2;
char* addra = &a;
int* addrb = &b;
printf("sizeof(*addra) = %d\r\n",sizeof(*addra)); // == 1
printf("sizeof(*addrb) = %d\r\n",sizeof(*addrb)); // == 4
printf("sizeof(char*) = %d\r\n",sizeof(char*)); // == 4
printf("sizeof(int*) = %d\r\n",sizeof(int*)); // == 4
2.2 使用指针访问硬件
c
int a = 1;
int* p = &a; //int类型的指针 可以存入int类型变量的地址;
*p = 2; //使用指针访问变量c这块内存;为什么可以?因为addrc等于c的地址
c
==》
p = 其他硬件的地址;
*p = val;/* 写硬件的时候要考虑寄存器 所占位数 和 *p指针类型 所对应的位数;若寄存器有16位,但是定义的是 char* p (一个字节,8个位),则只能写该寄存器的低八位; 后续只能通过修改指针 p 的类型 或者 将p指向的地址+1;访问高 8 位*/
v = *p; //读硬件
c
// 最简单的 用C语言访问硬件的代码
// 在实际使用过程中,需要翻阅芯片手册 来获取对应寄存器的地址;写过程中用位操作,来修改对应的位;
int mymain(void)
{
//指针类型尽量匹配寄存器位数;
volatile int* p = (volatile int*)0x20000000;//0x20000000 是地址
*p = 0x12345678; //写0x20000000 地址中写入 0x12345678;
p = (volatile int *)0x40021414; /* GPIO_ODR寄存器的地址 */
*p = *p & 0xFFFFFDFF; /*灯亮 使得第9位为0*/ // *p = *p & ~(1<<9)
*p = *p | 0x00000200; /*灯灭 使得第9位为1*/
//*p = (1<<9);
return 0;
}
//课后作业:修改指针p的类型
int mymain(void)
{
/*
volatile int* p = (volatile int*)0x20000000;
*p = 0x12345678;
p = (volatile int *)0x40021414; //GPIO_ODR寄存器的地址
*p = 0; //灯亮
*p = 0x200; //灯灭
*/
volatile char* p = (volatile char*)0x20000000;
*p = 0x00;
p = (volatile char *)0x40021415; /* GPIO_ODR寄存器的地址 */
//*p = *p & 0xFD; /*灯亮*/
*p = *p | 0x02; /* 灯灭 */
return 0;
}
3、数组
c
volatile char a[] = "1234567890";//10个字符
printf("sizeof(a) = %d\r\n",sizeof(a)); //11字节,结尾有个'\0'
volatile char a[] = {'a','b','c'};// ==> 输出可能为 abc+乱码
volatile char a[] = {'a','b','c',0};// ==>abc 无乱码
3.1 数组名就是有个指针
c
int arr[] = {1, 2, 3, 4, 5};
int *p = arr; // 等价于 int *p = &arr[0];
// 以下两种表达式等价
printf("%d\n", arr[1]); // 输出 2
printf("%d\n", *(p + 1)); // 输出 2 //p[1] 等价于 *(p+1)
arr是常量指针,"arr++"是错误的
3.2 多维数组
c
int arr[2][3] = { {1, 2, 3},
{4, 5, 6} };
printf("%d\n", arr[0][1]); // 输出 2
printf("%d\n", arr[1][2]); // 输出 6
int (*p)[3] = arr; // 指向一个包含 3 个整数的数组的指针
printf("%d\n", p[0][1]); // 输出 2
- 指针数组 是有个数组,其中每个元素都是指针;
c
char *strs[] = {"Hello", "World", "C Programming"};
printf("%s\n", strs[0]); // 输出 Hello
3.3 问题:
下面语句有什么差别:
c
char str[] = "abc";
char *p = "abc";
//是否可以执行
p[1] = 'A';
- 不可以,
char *p = "abc";这是字符指针 指向字符串常量,p是指针变量(存储地址),存储在栈区;而"abc"是字符串常量,存储在只读数据区 (.rodata)。p仅保存了字符串常量"abc"的首地址,字符串本身不可修改(修改会触发段错误)。
4、结构体
- 结构体 字节对齐;目的是为了
cpu执行效率; (面试笔试常见问题)
4.1 结构体指针
c
struct Student {
char name[20];
int age;
char sex;
int score;
};
struct Student a;
struct Student* p; //指向结构体的 指针
p = &a;
//写入数据的 的区别
a.age = 18;
p->age = 24; //指针 指向
4.2 结构体指针访问硬件
c
#include <stdio.h>
#include <string.h>
//将寄存器及其偏移地址,写成结构体的形式,并且使用结构体指针来访问硬件寄存器
struct GPIORegs {
volatile unsigned int moder;
volatile unsigned int otype;
volatile unsigned int speedr;
volatile unsigned int pupdr;
volatile unsigned int idr;
volatile unsigned int odr;//控制LED亮灭
volatile unsigned int bsrr;
volatile unsigned int lckr;
volatile unsigned int afrl;
volatile unsigned int afrh;
};
int mymain(void)
{
//struct GPIORegs f; // f是内存里一块区域, f.odr不会访问到GPIOF的寄存器
//需要使用指针来实现对寄存器的访问
struct GPIORegs *p = (struct GPIORegs *)0x40021400; /* GPIOF的基地址 */
p->odr |= (3<<9); /* 熄灭LED1,LED2 */ //p->odr = p->odr | (3<<9)
p->odr &= ~(1<<9); /* 点亮LED1 */
p->odr |= (1<<9); /* 熄灭LED1 */
return 0;
}
5、函数
5.1 参数传递与栈
- 当程序运行到
mymain函数时,就会给它分配空间,sp寄存器就会往低地址移动,给mymain函数分配栈空间,mymian函数中的局部变量就存在该栈空间中;在函数1中运行到函数2时,sp寄存器会继续往低地址移动,开辟函数2的栈空间;两者不相交; - 递归就是在函数1中调用函数1,同样会开辟多个函数1的栈空间;
c
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int x = 3, y = 5;
swap(&x, &y); // x和y的值会被交换 传递的是地址
return 0;
}
- 函数间参数的传递传递的是值;
- 当传递的是地址(形参是指针)时,函数可通过该地址可以访问到该变量;
- 当传递的不是地址(形参也不是指针),这该函数无法访问到之前的变量;
- 当函数结束后,sp会返回到之前的值,将执行完毕的函数栈空间回收;
5.2 递归函数
- 少用,对栈空间消耗太大;
c
int factorial(int n) //计算 阶乘
{
if (n == 0)
{
return 1;
}
return n * factorial(n - 1);
}
5.2.1 递归函数_栈使用情况
- 不断开辟函数栈空间

5.2.2 递归的注意事项
- 必须有一个基例(停止条件),否则会导致无限递归。
- 递归可能占用更多栈空间,导致栈溢出。
5.3 作用域
在C语言中,作用域(Scope)决定了变量、函数等标识符在程序中的可见性 和生命周期。作用域分为 以下几类:
- 全局变量 :在函数外部定义的变量,作用域为整个程序。
- 局部变量 :在函数内部 或代码块内定义的变量,作用域仅限于定义它们的函数或代码块。
5.3.1 全局变量
- 全局变量可以通过外部定义( extern )在其他文件中使用。
5.3.2 局部变量
- 局部变量在函数或代码块执行时创建,函数或代码块执行完毕后销毁;
5.3.3 嵌套在代码块中的局部变量
c
for(int i=0; i<10; i++) //其中i就是代码块中的局部变量,仅在for循环中生效;
5.3.4 静态变量(static)
- 若在函数内定义:
- 静态的局部变量,其作用域仅限函数内部;
- 仅分配一次,仅初始化一次;
- 该变量的内存并不在该函数的栈里面;局部静态变量和全局变量均不放在栈里面,而是放在数据段;
- 若在函数外定义:
- 静态的全局变量,其作用域为该.c文件;
- 避免了多个文件中有相同变量名的问题;(当同一文件遇到同名变量,优先使用作用域小的变量)
5.4 头文件
- 头文件(以.h 为扩展名)用于声明函数 、定义宏 和类型等。它的主要作用是将程序的接口与实现分离,使代码模块化;
5.4.1 常见头文件用途
- 将函数的声明放在头文件中,这样多个源文件 可以共享这些函数的定义,而无需重复编写声明
5.4.2 头文件包含
c
#include <stdio.h>
#include "math.c" //当前目录下
5.4.3 防止重复包含
c
//a.h
#ifndef _A_H
#define _A_H
//头文件内容
#endif
/*
#if 0
#endif
*/
5.4.4 如何创建自己的include文件?
- 建立自己的
myinclude文件

- 添加
include path

5.5 多文件编程
-
多文件编程步骤:
- 创建.c、.h文件,比如:
person.c、person.h - 把.c文件加入工程,比如:把
person.c加入工程,person.h无需加入工程 - 在其他文件包含
person.h,调用person.c里的函数
- 创建.c、.h文件,比如:
-
优势:便于模块化大型项目开发;便于团队协作;方便复用;
5.6 函数指针
- 函数指针是存储函数内存地址 的变量,可以通过该指针间接调用函数。与数据指针不同,函数指针指向 的是可执行代码段 (函数实现的地址)。
5.6.1 声明语法
return_type (*pointer_name)(parameter_types);
c
//示例:定义函数指针
int (*pFunc)(int,int);//指向返回int,接受两个int参数的函数
c
//示例:定义函数指针类型
typedef int (*pFunc)(int, int); // pFunc是"函数指针类型"
pFunc p1, p2; // 定义了p1, p2,它们是"函数指针"变量
- typedef
c
int a; // a是变量
int *a; // a是指针变量
typedef int a; // a是"int", 是类型
typedef int* a; // a是"int *", 是类型
int add(int a, int b); // add是函数
int (*add)(int a, int b); // add是函数指针, 是一个变量
typedef int (*add)(int a, int b); // add是"函数指针类型", 是一个类型
5.6.2 简单示例
c
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int main()
{
int (*pAdd)(int, int);
pAdd = add;//指向函数的指针,pAdd等于add函数的地址;
// int (*pAdd)(int, int) = &add; // 或直接写 pAdd = add;
// 两种调用方式等价
int result2 = pAdd(3, 5);//跳到pAdd所表示的地址去执行,add的地址
int result1 = (*pAdd)(3, 5);
printf("Results: %d, %d\n", result1, result2);
return 0;
}
5.6.3 函数指针作为参数
c
#include <stdio.h>
void process(int (*operation)(int, int), int x, int y)
{
int result = operation(x, y);
printf("Result: %d\n\r", result);
}
int add(int a, int b)
{
return a+b;
}
int sub(int a, int b)
{
return a-b;
}
int main() {
process(add, 5, 3);
}
5.6.4 函数指针数组
c
#include <stdio.h>
void process(int (*operation)(int, int), int x, int y)
{
int result = operation(x, y);
printf("Result: %d\n\r", result);
}
int add(int a, int b)
{
return a+b;
}
int sub(int a, int b)
{
return a-b;
}
typedef int (*f_type)(int a, int b);
int main()
{
f_type f_arr[2] = {add, sub};
int v1 = 4, v2 = 2;
int result;
for (int i = 0; i < 2; i++)
{
result = f_arr[i](v1, v2);//用f_arr[i]的值作为地址,去执行Flash上的代码;
}
printf("f %d, result = %d\n\r", i, result);
return 0;
}
5.6.5 结构体中的函数指针
c
struct person
{
char *name;
int sex;
void (*print)(struct person *p);
};
void printName(struct person *p)
{
printf("Name: %s\n\r", p->name);
}
void printAll(struct person *p)
{
printf("Name: %s\n\r", p->name);
printf("Sex: %s\n\r", p->sex ? "Male" : "Female");
}
int main()
{
struct person per1 = {"zhangsan", 1, printName};
struct person per2 = {"lili", 0, printAll};
per1.print(&per1);
per2.print(&per2);
return 0;
}
注意事项
-
在
dubug结束后,一定要把断点去掉,再关闭debug;否者会卡死; -
"我们要引入一个新的知识点是为了解决一个新的问题 !"
欢迎大家一起交流讨论!