当前位置: 首页 > news >正文

FreeRTOS-C语言指针笔记

文章目录

  • 一级指针
    • 指针基本概念
    • 指针使用示例
    • 代码说明
  • 二、二级指针
    • 二级指针重点解析

一级指针

C语言中的指针是一个非常重要的概念,它存储了变量的内存地址。指针的使用可以使程序更加高效,尤其在处理数组、字符串和动态内存分配时。

指针基本概念

  • 指针变量:用于存储内存地址的变量
  • 取地址符 &:获取变量的内存地址
  • 解引用符 *:访问指针所指向地址的内容

指针使用示例

下面是一些常见的指针使用示例:
可以运行

#include <stdio.h>// 1. 基本指针操作
void basicPointerExample() {int num = 10;int *p;       // 声明一个int类型的指针p = &num;     // 将num的地址赋值给指针pprintf("num的值: %d\n", num);printf("num的地址: %p\n", &num);printf("指针p存储的地址: %p\n", p);printf("指针p指向的值: %d\n", *p);*p = 20;      // 通过指针修改num的值printf("修改后num的值: %d\n", num);
}// 2. 指针作为函数参数(实现值的交换)
void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}// 3. 指针与数组
void pointerAndArray() {int arr[] = {1, 2, 3, 4, 5};int *p = arr;  // 数组名本身就是第一个元素的地址printf("\n数组元素: ");for(int i = 0; i < 5; i++) {// 以下两种方式等价printf("%d ", *(p + i));// printf("%d ", arr[i]);}printf("\n");
}// 4. 指针与字符串
void pointerAndString() {char *str = "Hello, World!";  // 字符串指针printf("\n字符串内容: ");// 使用指针遍历字符串while(*str != '\0') {printf("%c", *str);str++;  // 指针自增,指向 next 字符}printf("\n");
}// 5. 指针数组
void pointerArray() {char *names[] = {"Alice", "Bob", "Charlie", "David"};printf("\n指针数组中的字符串: ");for(int i = 0; i < 4; i++) {printf("%s ", names[i]);}printf("\n");
}int main() {basicPointerExample();int x = 100, y = 200;printf("\n交换前: x = %d, y = %d\n", x, y);swap(&x, &y);printf("交换后: x = %d, y = %d\n", x, y);pointerAndArray();pointerAndString();pointerArray();return 0;
}

代码说明

  1. 基本指针操作:展示了如何声明指针、获取变量地址、通过指针访问和修改变量值
  2. 指针作为函数参数:通过指针在函数内部修改外部变量的值,实现了两个数的交换
  3. 指针与数组:数组名本质上是指向第一个元素的指针,演示了如何通过指针访问数组元素
  4. 指针与字符串:字符串可以用指针表示,演示了如何通过指针遍历字符串
  5. 指针数组:数组中的每个元素都是指针,这里用指针数组存储多个字符串

指针的使用需要特别注意避免空指针、野指针等问题,这些可能会导致程序崩溃或不可预期的行为。正确使用指针可以使C程序更加灵活和高效。

二、二级指针

在C语言中,二级指针是指向指针的指针,它存储的是另一个指针变量的地址。二级指针在处理指针数组、动态二维数组以及需要修改指针本身的场景中非常有用。

下面在原有代码基础上添加二级指针的使用示例:

#include <stdio.h>
#include <stdlib.h> // 用于动态内存分配// 1. 基本指针操作
void basicPointerExample() {int num = 10;int *p;       // 声明一个int类型的指针p = &num;     // 将num的地址赋值给指针pprintf("num的值: %d\n", num);printf("num的地址: %p\n", &num);printf("指针p存储的地址: %p\n", p);printf("指针p指向的值: %d\n", *p);*p = 20;      // 通过指针修改num的值printf("修改后num的值: %d\n", num);
}// 2. 指针作为函数参数(实现值的交换)
void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}// 3. 指针与数组
void pointerAndArray() {int arr[] = {1, 2, 3, 4, 5};int *p = arr;  // 数组名本身就是第一个元素的地址printf("\n数组元素: ");for(int i = 0; i < 5; i++) {// 以下两种方式等价printf("%d ", *(p + i));// printf("%d ", arr[i]);}printf("\n");
}// 4. 指针与字符串
void pointerAndString() {char *str = "Hello, World!";  // 字符串指针printf("\n字符串内容: ");// 使用指针遍历字符串while(*str != '\0') {printf("%c", *str);str++;  // 指针自增,指向 next 字符}printf("\n");
}// 5. 指针数组
void pointerArray() {char *names[] = {"Alice", "Bob", "Charlie", "David"};printf("\n指针数组中的字符串: ");for(int i = 0; i < 4; i++) {printf("%s ", names[i]);}printf("\n");
}// 6. 二级指针使用示例
void doublePointerExample() {int num = 100;int *p = &num;    // 一级指针,指向numint **pp = &p;    // 二级指针,指向指针pprintf("\n=== 二级指针基本操作 ===\n");printf("num的值: %d\n", num);printf("p指向的值: %d\n", *p);printf("pp指向的指针所指向的值: %d\n", **pp);printf("num的地址: %p\n", &num);printf("p存储的地址: %p\n", p);printf("pp存储的地址: %p\n", pp);printf("p本身的地址: %p\n", &p);
}// 7. 二级指针与指针数组
void doublePointerAndPointerArray() {char *languages[] = {"C", "Python", "Java", "JavaScript"};char **pp;  // 二级指针,用于指向指针数组元素printf("\n=== 二级指针访问指针数组 ===\n");// 二级指针遍历指针数组pp = languages;  // 指向数组首元素for(int i = 0; i < 4; i++) {printf("语言: %s, 地址: %p\n", *pp, pp);pp++;  // 移动到下一个指针元素}
}// 8. 二级指针作为函数参数(修改指针本身)
void allocateMemory(int **ptr, int size) {// 为指针分配内存,需要二级指针才能修改外部指针*ptr = (int*)malloc(size * sizeof(int));if(*ptr == NULL) {printf("\n内存分配失败!\n");return;}// 初始化分配的内存for(int i = 0; i < size; i++) {*(*ptr + i) = i * 10;}
}int main() {basicPointerExample();int x = 100, y = 200;printf("\n交换前: x = %d, y = %d\n", x, y);swap(&x, &y);printf("交换后: x = %d, y = %d\n", x, y);pointerAndArray();pointerAndString();pointerArray();// 演示二级指针doublePointerExample();doublePointerAndPointerArray();// 二级指针作为函数参数示例int *arr = NULL;allocateMemory(&arr, 5);  // 传递指针的地址if(arr != NULL) {printf("\n通过二级指针分配的数组: ");for(int i = 0; i < 5; i++) {printf("%d ", arr[i]);}printf("\n");free(arr);  // 释放内存}return 0;
}

二级指针重点解析

  1. 二级指针的定义与初始化

    int num = 100;
    int *p = &num;    // 一级指针
    int **pp = &p;    // 二级指针,指向指针p
    

    这里pp就是二级指针,它存储的是一级指针p的地址。

  2. 二级指针的解引用

    • *pp:得到一级指针p的值(即num的地址)
    • **pp:通过两次解引用,得到最终变量num的值
  3. 二级指针的主要用途

    • 访问指针数组:如示例中遍历存储字符串的指针数组
    • 作为函数参数修改指针本身:当需要在函数内部为指针分配内存或修改指针指向时
    • 处理动态二维数组:二级指针常用来表示动态分配的二维数组
  4. 使用注意事项

    • 二级指针也可能出现空指针问题,使用前需检查
    • 多级指针会增加代码复杂度,应避免过度使用
    • 动态分配内存后需记得释放,防止内存泄漏

通过二级指针,我们可以更灵活地操作指针本身,这在处理复杂数据结构和动态内存分配时特别有用。

http://www.dtcms.com/a/331000.html

相关文章:

  • 【入门级-C++程序设计:13、STL 模板:栈(stack)、队 列(queue)、 链 表(list)、 向 量(vector) 等容器】
  • gitlab的ci/cd变量如何批量添加
  • 【P81 10-7】OpenCV Python【实战项目】——车辆识别、车流统计(图像/视频加载、图像运算与处理、形态学、轮廓查找、车辆统计及显示)
  • 智能清扫新纪元:有鹿机器人如何用AI点亮我们的城市角落
  • Streamlit实现Qwen对话机器人
  • CVPR 2025 | 机器人操控 | RoboGround:用“掩码”中介表示,让机器人跨场景泛化更聪明
  • GaussDB数据库架构师修炼(十六) 如何选择磁盘
  • Helm-K8s包管理(三)新建、编辑一个Chart
  • k8s+isulad 重装
  • Seata学习(三):Seata AT模式练习
  • CMake语法与Bash语法的区别
  • 解剖HashMap的put <三> JDK1.8
  • 会议系统进程池管理:初始化、通信与状态同步详解
  • 从 Notion 的水土不服到 Codes 的本土突围:研发管理工具的适性之道​
  • Apache 虚拟主机配置冲突导致 404 错误的排查总结
  • [机器学习]08-基于逻辑回归模型的鸢尾花数据集分类
  • AXI GPIO 2——ZYNQ学习笔记
  • 力扣top100(day03-02)--图论
  • Java 技术栈中间件优雅停机方案设计与实现全景图
  • 【JavaEE】多线程 -- 线程状态
  • 数据结构之顺序表相关算法题
  • 【数据分享】351个地级市农业相关数据(2013-2022)-有缺失值
  • linux中date命令
  • SAP-ABAP:SAP消息系统深度解析:架构设计与企业级应用实践
  • Wireshark中捕获的大量UDP数据
  • 23.Linux : ftp服务及配置详解
  • (论文速读)DiffusionDet - 扩散模型在目标检测中的开创性应用
  • AI搜索重构下的GEO优化服务商格局观察
  • 李沐-第六章-LeNet训练中的pycharm jupyter-notebook Animator类的显示问题
  • 轻松同步 Outlook 联系人到 Android