指针运算
指针运算

指针运算

一、核心概念

指针运算是指针对内存地址进行​​算术运算​​或​​关系运算​​的操作,核心围绕地址的​​移动​​和​​比较​​。

  • ​算术运算​​:加减整数、自增/自减(++, –)、指针相减。
  • ​关系运算​​:比较指针大小(>, <, ==等)。

二、核心知识点

  1. ​算术运算步长​​:指针加减整数n时,实际移动的字节数为 n * sizeof(数据类型)。
  • int *ptr + 1 → 移动4字节(假设int为4字节)
  • char *ptr + 1 → 移动1字节
  1. ​指针相减的意义​​:得到两个指针之间的​​元素个数​​,而非字节数。

int *p1 = &arr[2], *p2 = &arr[5]; int n = p2 – p1; // n = 3(相差3个元素)

  1. ​关系运算规则​​:比较的是指针指向的地址高低,常用于数组或同一内存块。
  2. ​数组与指针的等价性​​:数组名可视为指向首元素的指针,arr[i]等价于*(arr + i)。
  3. ​void指针的限制​​:void*指针不能直接运算(因步长未知),需转换为具体类型后再操作。

三、如何简单理解?

​类比书本页码​​:

  • 指针变量 → 当前页码(如第100页)
  • 指针+1 → 翻到下一页(页数根据内容大小决定)
    • 若每页存1个数字(int):翻过4页(4字节)
    • 若每页存1个字母(char):翻过1页(1字节)

四、记忆口诀

​“类型决定步长,加减元素数量;相减得元素差,比较看地址高低。”​


五、代码示例及逐行解析

#include <stdio.h> int main() { int arr[] = {10, 20, 30, 40, 50}; // 定义一个包含5个整数的数组 int *ptr = arr; // ptr指向数组首元素(arr[0]) int sum = 0; // 初始化累加器 for (int i = 0; i < 5; i++) { sum += *ptr; // 取出ptr指向的值(如arr[0]的值10),累加到sum ptr++; // ptr移动至下一个元素(地址增加sizeof(int)=4字节) } printf(“Sum: %d\n”, sum); // 输出结果:Sum: 150 return 0; }

​逐行解释:​

  1. #include 引入标准输入输出库,使printf可用。
  2. int arr[] = {10, 20, 30, 40, 50};定义数组arr,包含5个整数,内存连续分配。
  3. int *ptr = arr;arr作为数组名,自动转换为指向首元素arr[0]的指针,赋值给ptr。
  4. int sum = 0;初始化变量sum,用于存储累加结果。
  5. for (int i = 0; i < 5; i++)循环5次,遍历数组所有元素。
  6. sum += *ptr;*ptr解引用指针,获取当前指向的元素值(如第一次循环时为10)。
  7. ptr++;指针自增,移动到下一个元素。由于ptr是int*类型,实际地址增加4字节(sizeof(int))。
  8. printf(“Sum: %d\n”, sum);输出累加结果:10 + 20 + 30 + 40 + 50 = 150。

六、常见问题

  1. ​越界访问​​:若指针移动到数组之外(如ptr++超过5次),可能导致未定义行为。
  2. ​类型匹配​​:不同指针类型(如int*和char*)运算步长不同,混用易出错。
  3. ​void指针运算​​:

void *p = arr; // p++; // 错误!void指针不能直接运算 int *q = (int*)p; q++; // 正确


​总结​​:指针运算是C语言高效操作内存的核心,理解类型决定步长、数组与指针的关系后,便能灵活应用于遍历、偏移计算等场景。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注