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

C语言|指针的应用

个人主页-爱因斯晨

文章专栏-C语言

加油哦~各位!

在这里插入图片描述

一、指针的本质

  1. 定义:指针是一种变量,专门用于存储内存地址,其大小通常为 4 字节(32 位系统)或 8 字节(64 位系统)

  2. 核心价值

    • 直接操作内存,提升程序执行效率
    • 实现函数多值返回
    • 为动态内存分配提供支持
    • 实现数据结构(链表、树等)
  3. 声明方式数据类型 *指针变量名

    int *p;  // 声明一个指向int类型的指针p
    char *str;  // 声明一个指向char类型的指针str
    

二、指针与地址的关系

  1. 取地址运算符(&):获取变量的内存地址

    int a = 10;
    int *p = &a;  // 将变量a的地址赋值给指针p
    
  2. 解引用运算符(*):通过地址访问变量的值

    printf("%d", *p);  // 输出指针p所指向的变量值,即10
    *p = 20;  // 修改指针p所指向的变量值
    
  3. NULL 指针:不指向任何有效内存的指针

    int *p = NULL;  // 初始化空指针
    if (p == NULL) {  // 判断指针是否为空// 处理空指针情况
    }
    

三、指针与变量的结合使用

  1. 指针变量的初始化

    int a = 5;
    int *p1;       // 未初始化的指针(野指针,危险!)
    int *p2 = &a;  // 正确初始化,指向变量a
    int *p3 = NULL;  // 初始化为空指针
    
  2. 指针的运算

    • 指针 ± 整数:移动指针指向的位置
    int arr[5] = {1,2,3,4,5};
    int *p = arr;
    p++;  // 指针向后移动一个int类型的大小(通常4字节)
    
    • 指针 - 指针:计算两个指针之间的元素个数
    int len = &arr[4] - &arr[0];  // 结果为4(元素个数差)
    
  3. 多级指针:指向指针的指针

    int a = 10;
    int *p = &a;    // 一级指针
    int **pp = &p;  // 二级指针
    printf("%d", **pp);  // 输出10
    

四、指针与数组的关系

  1. 数组名的特性:数组名代表数组首元素的地址(常量指针)

    int arr[5] = {1,2,3,4,5};
    printf("%p", arr);    // 输出数组首元素地址
    printf("%p", &arr[0]);  // 与上面输出相同
    
  2. 指针访问数组元素

    // 以下两种方式等价
    arr[2] = 10;
    *(arr + 2) = 10;
    
  3. 数组指针(指向数组的指针)

    int (*p)[5];  // 指向包含5个int元素的数组的指针
    int arr[5] = {1,2,3,4,5};
    p = &arr;  // p指向整个数组
    
  4. 指针数组(元素为指针的数组)

    int *p[5];  // 包含5个int*指针的数组
    int a = 1, b = 2, c = 3;
    p[0] = &a;
    p[1] = &b;
    p[2] = &c;
    

五、指针与函数的关系

  1. 函数参数传递

    • 值传递:函数内部修改不影响外部变量
    • 指针传递:函数内部可修改外部变量
    void swap(int *x, int *y) {int temp = *x;*x = *y;*y = temp;
    }// 调用方式
    int a = 3, b = 5;
    swap(&a, &b);  // a和b的值会被交换
    
  2. 函数返回指针

    int *createArray(int size) {int *arr = malloc(size * sizeof(int));return arr;  // 返回动态分配内存的指针
    }
    
  3. 函数指针(指向函数的指针)

    int add(int a, int b) {return a + b;
    }int (*funcPtr)(int, int);  // 声明函数指针
    funcPtr = add;  // 函数指针指向add函数
    int result = funcPtr(3, 5);  // 调用函数,结果为8
    

六、指针与字符串

  1. 字符串的两种表示形式

    char str1[] = "hello";  // 字符数组
    char *str2 = "world";   // 字符串常量指针
    
  2. 指针操作字符串

    char *str = "hello";
    while (*str != '\0') {printf("%c", *str);str++;  // 移动指针访问下一个字符
    }
    
  3. 字符串处理函数与指针

    #include <string.h>char *src = "hello";
    char dest[20];
    strcpy(dest, src);  // 字符串复制
    int len = strlen(src);  // 获取字符串长度
    

七、动态内存分配与指针

  1. malloc 函数:分配指定字节数的内存

    int *p = (int*)malloc(5 * sizeof(int));  // 分配5个int的内存
    if (p == NULL) {// 内存分配失败处理
    }
    
  2. calloc 函数:分配内存并初始化为 0

    int *p = (int*)calloc(5, sizeof(int));  // 分配5个int并初始化为0
    
  3. realloc 函数:重新调整已分配内存的大小

    p = (int*)realloc(p, 10 * sizeof(int));  // 将内存调整为10个int
    
  4. free 函数:释放动态分配的内存

    free(p);  // 释放内存
    p = NULL;  // 避免野指针
    

八、指针使用的常见错误

  1. 野指针:未初始化的指针或指向已释放内存的指针

    int *p;  // 野指针,危险!
    *p = 10;  // 未定义行为
    
  2. 空指针解引用:对 NULL 指针使用解引用运算符

    int *p = NULL;
    *p = 5;  // 程序崩溃
    
  3. 内存泄漏:动态分配的内存未释放

    int *p = (int*)malloc(sizeof(int));
    // 忘记调用free(p),导致内存泄漏
    
  4. 指针越界:访问超出数组范围的内存

    int arr[5];
    int *p = arr;
    p[10] = 3;  // 越界访问,可能导致程序崩溃
    

九、指针的实际应用场景

  1. 高效处理大型数据:避免数据拷贝,直接传递地址
  2. 实现数据结构:链表、树、图等都依赖指针实现
  3. 函数回调机制:通过函数指针实现事件处理
  4. 动态数据结构:根据需要动态分配和释放内存
  5. 操作硬件设备:直接访问特定内存地址控制硬件
http://www.lryc.cn/news/599809.html

相关文章:

  • Python 之 keyboard
  • 详解软件需求中的外部接口需求
  • 网络安全入门第一课:信息收集实战手册(3)
  • 芯显15寸工控液晶屏RV150X0M-N10产品资料详情
  • 高德地图 loca 实现点线的显示和点击
  • Ping32:企业数据安全的智能护盾
  • C++中使用Essentia实现STFT/ISTFT
  • C++中new和delete的多重面孔:operator new、new operator与placement new解析
  • 机器学习-SVM支持向量机
  • Zookeeper学习专栏(十):核心流程剖析之服务启动、请求处理与选举协议
  • 【Linux】进程切换与优先级
  • Metaspace耗尽导致OOM问题
  • 【运维自动化-标准运维】各类全局变量使用说明(下)
  • 伯俊科技× OB Cloud:零售业落地AI的“三步走”渐进式发展实践
  • 企业微信H5应用OAuth2登录,企业微信授权登录
  • 国产DevOps平台Gitee:如何重塑中国企业研发效能新格局
  • 如何在 Ubuntu 24.04 或 22.04 上安装和使用 GDebi
  • Qt 反射机制与动态属性系统
  • UserWarning: Workbook contains no default style, apply openpyxl‘s default warn
  • ReAct Agent(LangGraph实现)
  • 04-netty基础-Reactor三种模型
  • 无需 Root 关闭联网验证 随意修改手机名称(适用于OPPO、一加、真我)
  • 【笔记】Handy Multi-Agent Tutorial 第四章: CAMEL框架下的RAG应用 (简介)
  • RocketMQ 5.3.0 ARM64 架构安装部署指南
  • 详解FreeRTOS开发过程(八)-- 时间标志
  • 【电赛学习笔记】MaxiCAM 项目实践——与单片机的串口通信
  • ESP32学习笔记_Components(1)——使用LED Strip组件点亮LED灯带
  • Yolov8/Yolov11实例分割训练自有数据集
  • AWS WebRTC:我们的业务模式
  • 壁纸管理 API 文档