You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中指向数组首元素的指针与指向数组的指针有什么区别

C语言两类指针的差异解答

你对两个指针的判断完全正确,二者本质是不同类型的指针,虽然指向的内存地址数值可能相同,但编译器对二者的处理逻辑完全不同,使用时的差异也非常明显。
首先先修正示例代码的一处常见写法问题:

int arr[5] = {1,2,3,4,5};
int *pointer = arr;
// 原代码直接赋值arr会触发类型不匹配警告,正确写法需要取整个数组的地址
int (*pointer2)[5] = &arr;

1. 类型本质区别

  • pointer 是 指向int类型的指针,存储的是数组首元素arr[0]的地址,对应你说的「指向数组首元素的指针」。
  • pointer2 是 指向包含5个int元素的数组的指针(数组指针),存储的是整个数组arr的起始地址,就是你说的「指向包含5个int元素的数组的指针」。

注:数组的起始地址和数组首元素的起始地址在内存上是同一个位置,所以直接打印两个指针的数值会完全一致,二者的差异只存在于编译期的类型处理逻辑。

2. 实际使用中的核心差异

2.1 指针运算步长不同

指针加减的步长由其指向的类型大小决定:

  • pointer + 1 的步长是 sizeof(int),32位int环境下偏移4字节,指向arr[1]的地址。
  • pointer2 + 1 的步长是 sizeof(int[5]),32位int环境下偏移20字节,直接跳过整个5元素数组,指向arr结束后的下一块内存地址。
    示例输出:
// 假设arr的起始地址为0x7ffdabcdef10
printf("%p\n", pointer);      // 输出0x7ffdabcdef10
printf("%p\n", pointer + 1);  // 输出0x7ffdabcdef14
printf("%p\n", pointer2);     // 输出0x7ffdabcdef10
printf("%p\n", pointer2 + 1); // 输出0x7ffdabcdef24(10的16进制+20=24)

2.2 解引用结果不同

  • 对pointer解引用 *pointer 得到的是int类型的数值,等于arr[0]的值1,可以直接参与数值运算。
  • 对pointer2解引用 *pointer2 得到的是int[5]数组类型,等价于数组名arr,必须再取下标才能得到单个元素的值:(*pointer2)[0] 才等于arr[0]的值1。

2.3 赋值的类型约束不同

  • int*类型的指针可以直接接收退化为指针的数组名arr,不会有编译警告。
  • 数组指针int (*)[5]只能接收&arr这种取整个数组地址的右值,直接赋值arr会触发编译器的类型不匹配警告。

3. 常见使用场景

  • int*是操作数组的最常用指针类型,一般用来遍历数组元素、读写单个元素值。
  • 数组指针int (*)[N]一般用于操作二维数组、或者作为函数参数传递固定长度的数组,可以在编译期做长度校验,避免数组越界。

内容的提问来源于stack exchange,提问作者user737163

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 06:06:04