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

指针类型:解引用与运算的关键

        指针变量的大小与类型无关,在同一平台下所有指针变量的大小通常相同(例如在32位系统中为4字节,64位系统中为8字节)。那么为什么还需要各种各样的指针类型呢?实际上,指针类型具有重要的特殊意义,主要体现在以下几个方面:

目录

一、指针的解引用

代码1:

代码2:

调试观察可以发现:

结论:

二、指针的算术运算

三、void* 指针

示例1:类型不兼容警告

示例2:void 的使用*

VS编译代码的结果:

*void 的主要用途**:

四、指针运算

1、指针 ± 整数

1、指针运算原理

2、整型指针(int*)示例

3、字符指针(char*)示例

4、核心规律

5、记忆技巧

2、指针 - 指针

3、指针的关系运算


一、指针的解引用

对比下面两段代码,观察调试时内存的变化:

代码1:

#include <stdio.h>
int main()
{int n = 0x11223344;int *pi = &n; *pi = 0; return 0;
}

代码2:

#include <stdio.h>
int main()
{int n = 0x11223344;char *pc = (char *)&n;*pc = 0;return 0;
}

调试观察可以发现:

  • 代码1会将n的4个字节全部改为0

  • 代码2仅将n的第一个字节改为0

结论

指针的类型决定了指针解引用时能操作的内存大小(权限)。例如:

  • char* 指针解引用只能访问1个字节

  • int* 指针解引用能访问4个字节(在32位系统中)


二、指针的算术运算

观察以下代码中指针加减整数时的地址变化:

#include <stdio.h>
int main()
{int n = 10;char *pc = (char*)&n;int *pi = &n;printf("%p\n", &n);printf("%p\n", pc);printf("%p\n", pc+1);printf("%p\n", pi);printf("%p\n", pi+1);return 0;
}

代码运行的结果如下:

运行结果分析:

  • char* 类型指针+1跳过1个字节

  • int* 类型指针+1跳过4个字节(假设int为4字节)

结论指针的类型决定了指针加减整数时的步进大小。指针+1实际上是跳过1个指向类型的元素大小。


三、void* 指针

    void* 是一种特殊的指针类型,称为"无类型指针"或"泛型指针",可以接收任意类型的地址。但有其局限性:

  1. 优点可以接收任何类型指针的赋值而无需强制类型转换

  2. 限制

    • 不能直接进行指针算术运算(加减整数)

    • 不能直接解引用

示例1:类型不兼容警告

#include <stdio.h>
int main()
{int a = 10;int* pa = &a;char* pc = &a;  // 编译器警告:类型不兼容return 0;
}

        在上面的代码中,我们将一个int类型变量的地址赋给了char*指针变量。由于类型不兼容,编译器会发出警告(如下图所示)。而使用void*作为中间类型可以避免这个问题。

示例2:void 的使用*

#include <stdio.h>
int main()
{int a = 10;void* pa = &a;  // 正确void* pc = &a;  // 正确// *pa = 10;    // 错误:void* 不能直接解引用// *pc = 0;     // 错误:void* 不能直接解引用return 0;
}

VS编译代码的结果:

*void 的主要用途**:

  • 常用于函数参数,实现泛型编程

  • 用于处理未知类型的数据

  • 在内存操作函数(如memcpy、memset)中使用


四、指针运算

指针支持三种基本运算:没有指针加指针,因为这个操作没有意义,跟日期加日期一个性质!!!

1、指针 ± 整数

利用数组在内存中的连续存储特性,通过指针算术运算遍历数组:

#include <stdio.h>
int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};int *p = &arr[0];int sz = sizeof(arr)/sizeof(arr[0]);for(int i=0; i<sz; i++){printf("%d ", *(p+i)); // p+i 是指针+整数运算}return 0;
}

以下是关于指针运算核心知识点的整理:

1、指针运算原理

  • 加减整数n时,地址偏移量取决于数据类型大小
  • 计算公式:新地址 = 原地址 ± (n × sizeof(数据类型))

2、整型指针(int*)示例

  • 声明:int* pa
  • pa + 1:地址增加4字节(32/64位系统)
  • pa + n:地址增加(4 × n)字节
  • 典型步长:4字节

3、字符指针(char*)示例

  • 声明:char* pc
  • pc + 1:地址增加1字节
  • pc + n:地址增加n字节
  • 固定步长:1字节

4、核心规律

  • 运算步长由指针声明类型决定
  • 相同偏移量在不同类型指针中产生不同地址变化
  • 通用公式:地址偏移量 = n × sizeof(基类型)

5、记忆技巧

  • 本质是地址的移动操作
  • sizeof(类型)决定指针的单步步长
  • 该特性确保数组元素的正确遍历

2、指针 - 指针

计算两个指针之间的距离(元素个数),常用于字符串长度计算等场景:

#include <stdio.h>
int my_strlen(const char* s)
{const char* p = s;while (*p != '\0')p++;return p - s; // 指针相减得到字符个数
}int main()
{printf("%d\n", my_strlen("abc")); // 输出3return 0;
}

注意指针相减要求两个指针指向同一内存区域(如同一个数组)。

3、指针的关系运算

比较指针的大小(内存地址高低),常用于数组遍历:

#include <stdio.h>
int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};int *p = &arr[0];int sz = sizeof(arr)/sizeof(arr[0]);while(p < arr + sz) // 指针比较{printf("%d ", *p);p++;}return 0;
}

注意指针关系运算也要求指针指向同一内存区域才有意义。

http://www.lryc.cn/news/621824.html

相关文章:

  • 电子电气架构 --- 探索软件定义汽车(SDV)的技术革新
  • 基于多模型的零售销售预测实战指南
  • Java 大视界 -- 基于 Java 的大数据可视化在城市交通拥堵治理与出行效率提升中的应用(398)
  • 【java】对word文件设置只读权限
  • 英文PDF翻译成中文怎么做?试试PDF翻译工具
  • Canal 技术解析与实践指南
  • ffmpeg 安装、配置与使用完全指南
  • 【python实用小脚本-187】Python一键批量改PDF文字:拖进来秒出新文件——再也不用Acrobat来回导
  • fastdds.ignore_local_endpoints 属性
  • PDF Replacer:高效便捷的PDF文档内容替换专家
  • 基于 Spring AI + Ollama + MCP Client 打造纯本地化大模型应用
  • JavaScript(JS)DOM(四)
  • 大模型微调分布式训练-大模型压缩训练(知识蒸馏)-大模型推理部署(分布式推理与量化部署)-大模型评估测试(OpenCompass)
  • MuMu模拟器Pro Mac 安卓手机平板模拟器(Mac中文)
  • 代码随想录Day51:图论(岛屿数量 深搜广搜、岛屿的最大面积)
  • 解决量化模型中的 NaN 问题:为何非量化层应选用 FP32?(41)
  • 波浪模型SWAN学习(1)——模型编译与波浪折射模拟(Test of the refraction formulation)
  • Docker安装——配置国内docker镜像源
  • flutter 跨平台编码库 protobuf 工具使用
  • RAGFlow入门
  • Trae2.0:AI 编程新时代的引领者
  • 反射和类加载机制
  • 智能算法突破动态挑战,效率革命重塑计算未来!
  • (自用)console.log怎么上色
  • 使用转换函数重载布尔值类
  • 读《精益数据分析》:黏性(Stickiness)—— 验证解决方案是否留住用户
  • 自适应UI设计解读 | Fathom 企业人工智能平台
  • 5G工业一体机汽车零部件工厂的无纸化管理
  • HarmonyOS 实战:用 @Observed + @ObjectLink 玩转多组件实时数据更新
  • Go从入门到精通系列学习路线规划