当前位置: 首页 > 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.dtcms.com/a/297519.html

相关文章:

  • 算法:最长递增子序列解法记录
  • 【RDMA】Adapters PRM Mellanox Adapters Programmer’s Reference mellanox网卡编程手册0.52
  • C 语言输入输出 (I/O)
  • 数据结构学习之堆
  • 【C语言进阶】一篇文章教会你文件的读写
  • 基于GeoTools和SpringBoot的省域驾车最快路线生成实践
  • 金仓数据库:融合与智能驱动下的革新与未来
  • SpringBoot实战指南:从快速入门到生产级部署(2025最新版)
  • 通用CI/CD软件平台TeamCity v2025.3全新发布——主要界面交互体验升级
  • SqlRest让SQL秒变Http API,还支持20+数据库(含国产数据库)
  • S7-1500 与 ET200MP 的组态控制通信(Configuration Control)功能实现详解(下)
  • STM32基础知识学习笔记:ICODE、DCODE、DMA等常见名词的解释
  • c语言-数据结构-沿顺相同树解决对称二叉树问题的两种思路
  • Canal 1.1.7的安装
  • 京东获得JD商品详情 API 返回值说明||京东API接入文档
  • 二开----02
  • (2023AAAI)T2I-Adapter:学习挖掘文本到图像扩散模型的更可控能力
  • linux系统底层逻辑 开机顺序 ubuntu22.04系统
  • ubuntu中有不同版本的pcl时的使用策略
  • Redis替代方案:腾讯云TDSQL-C内存优化实战,TPS秒上涨
  • [特殊字符] VLA 如何“绕过”手眼标定?—— 当机器人学会了“看一眼就动手”
  • 技术笔记 | RK3588 X11 桌面 GPU 性能实测
  • LIMA:大语言模型对齐的“少即是多”革命——原理、实验与范式重构
  • webRTC合并本地源码修改和官方更新
  • Python之--集合
  • 小米8(dipper)刷入kernelSU内核root定制rom系统教程以及安装LSPosed模块
  • 深度学习篇---数据预处理
  • Nginx 安全加固:如何阻止 IP 直接访问,只允许域名访问
  • 【数学建模|Matlab】数学建模「常用作图」示例
  • 中国移动融合企业网关H10G-13-中星微ZX296716处理器-破解教程