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

指针数组与数组指针的区别

#include <stdio.h>int main()
{// 1. 指针数组 (Array of Pointers)// 指针数组是一个数组,其元素都是指针。int a = 100, b = 200, c = 300, d = 400;int *arr_of_ptrs[4] = {&a, &b, &c, &d};printf("------------指针数组示例:------------\n");for (int i = 0; i < 4; i++){printf("arr_of_ptrs[%d] = %p, *arr_of_ptrs[%d] = %d\n",i, (void *)arr_of_ptrs[i], i, *arr_of_ptrs[i]);}// 2. 数组指针 (Pointer to Array)// 数组指针是一个指针,它指向整个数组。int arr[4] = {10, 20, 30, 40};// 声明一个数组指针:指向包含4个整数的数组int (*arr_ptr)[4] = &arr;printf("\n------------数组指针示例:------------\n");printf("arr_ptr地址: %p\n", (void *)arr_ptr);printf("arr地址: %p\n", (void *)arr);// 通过数组指针访问数组元素printf("第一个元素: %d\n", (*arr_ptr)[0]);printf("第二个元素: %d\n", (*arr_ptr)[1]);// 指针算术:移动整个数组的大小printf("arr_ptr + 1地址: %p (前进%d字节)\n",(void *)(arr_ptr + 1),(int)((char *)(arr_ptr + 1) - (char *)arr_ptr));return 0;
}

int (*p_array)[4] = &arr;int *p = arr; 的区别

这两种指针声明方式在C语言中有本质的区别,主要体现在指针类型、语义和指针算术运算上。

代码示例

#include <stdio.h>int main() {int arr[4] = {10, 20, 30, 40};// 方式1: 指向数组第一个元素的指针int *p = arr;// 方式2: 指向整个数组的指针int (*p_array)[4] = &arr;printf("数组地址: %p\n", (void *)arr);printf("&arr地址: %p\n", (void *)&arr);printf("\nint *p = arr:\n");printf("p地址: %p, 值: %d\n", (void *)p, *p);printf("p+1地址: %p, 值: %d\n", (void *)(p+1), *(p+1));printf("\nint (*p_array)[4] = &arr:\n");printf("p_array地址: %p\n", (void *)p_array);printf("(*p_array)[0] = %d\n", (*p_array)[0]);printf("p_array+1地址: %p\n", (void *)(p_array+1));return 0;
}

主要区别

1. 指针类型不同

  • int *p = arr;:

    • p 是指向整型的指针(int*
    • 指向数组的第一个元素
  • int (*p_array)[4] = &arr;:

    • p_array 是指向包含4个整数的数组的指针(int(*)[4]
    • 指向整个数组

2. 指针算术运算不同

  • int *p = arr;:

    • p + 1 前进一个 int 的大小(通常4字节)
    • 指向数组的下一个元素
  • int (*p_array)[4] = &arr;:

    • p_array + 1 前进整个数组的大小(4 × sizeof(int) = 16字节)
    • 指向下一个相同大小的数组

3. 解引用方式不同

  • int *p = arr;:

    • *p 直接得到数组的第一个元素的值
    • p[i]*(p+i) 访问数组的第i个元素
  • int (*p_array)[4] = &arr;:

    • *p_array 得到整个数组(类型为 int[4]
    • (*p_array)[i] 访问数组的第i个元素

内存布局示意图

内存地址: 0x1000 0x1004 0x1008 0x100C
值:       10     20     30     40↑      ↑p      p+1↑p_array (指向整个数组)↑p_array+1 (指向下一个数组,地址0x1010)

实际应用场景

使用 int *p = arr;(常见用法)

// 遍历数组元素
int arr[4] = {10, 20, 30, 40};
int *p = arr;for (int i = 0; i < 4; i++) {printf("%d ", *(p + i));// 或 printf("%d ", p[i]);
}

使用 int (*p_array)[4] = &arr;(特殊用法)

// 处理二维数组
int matrix[3][4] = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}
};// 指向二维数组的指针
int (*p_matrix)[4] = matrix;for (int i = 0; i < 3; i++) {for (int j = 0; j < 4; j++) {printf("%d ", p_matrix[i][j]);// 或 printf("%d ", (*(p_matrix + i))[j]);}printf("\n");
}

类型兼容性

需要注意的是,虽然 arr&arr 的值相同(都指向数组的起始地址),但它们的类型不同:

  • arr 的类型是 int[4],在大多数表达式中退化为 int*
  • &arr 的类型是 int(*)[4]

因此,以下赋值需要类型转换:

int arr[4] = {10, 20, 30, 40};
int *p1 = arr; // 正确,类型兼容
int *p2 = (int *)&arr; // 需要显式类型转换

总结

  • int *p = arr; 创建了一个指向数组第一个元素的指针,适用于大多数数组操作
  • int (*p_array)[4] = &arr; 创建了一个指向整个数组的指针,主要用于处理多维数组
  • 两种指针的值相同(指向同一地址),但类型不同,导致指针算术运算的行为不同
  • 理解这一区别有助于编写更准确和高效的C代码,特别是在处理多维数组时
http://www.dtcms.com/a/361180.html

相关文章:

  • 【第十一章】Python 队列全方位解析:从基础到实战
  • 鸿蒙NEXT表单选择组件详解:Radio与Checkbox的使用指南
  • 绝了!极空间搭配视频智语,生产力拉满,多平台视频摘要一键搞定
  • browsermobproxy + selenium 获取接口json
  • PLC操作
  • AI + 机器人:当大语言模型赋予机械 “思考能力”,未来工厂将迎来怎样变革?
  • 森赛睿视觉AI:大模型加持,分类更智能
  • 宋红康 JVM 笔记 Day09|方法区
  • 虚拟化技术是什么?电脑Bios中的虚拟化技术怎么开启
  • 【2025ICCV】Vision Transformers 最新研究成果
  • NetCoreKevin-DDD-微服务-WebApi-AI智能体、AISK集成、MCP协议服务、SignalR、Quartz 框架-14-数据模型与持久化
  • YOLO 目标检测:YOLOv4数据增强、CIoU Loss、网络结构、CSP、SPPNet、FPN和PAN
  • 架构选型:为何用对象存储替代HDFS构建现代数据湖
  • Linux之Shell编程(四)函数、数组、正则
  • 小土堆目标检测笔记
  • 【开题答辩全过程】以 基于Spring Boot的房屋租赁系统的设计与实现为例,包含答辩的问题和答案
  • go语言面试之Goroutine 数量控制, GC回收 和任务调度
  • 【Qwen】Qwen3-30B-A3B 模型性能评估指南 + API KEY介绍
  • DAY02:【DL 第一弹】pytorch
  • JS闭包讲解
  • 在 Halo 中导入 Markdown 和 Word 文档
  • openEuler2403编译安装Nginx
  • 【C++】 Vector容器操作全解析
  • springboot:数据校验
  • 人工智能之数学基础:常用的连续型随机变量的分布
  • Web知识的总结
  • 直播预告 | Excelize 跨语言实战
  • 搭载AX650N高能效比智能视觉芯片——AX2050系列边缘计算盒,可应用在智慧安防交通仓储教育,人脸识别,明厨亮灶,安全生产,智能机器人等
  • Linux ARP老化机制/探测机制/ip neigh使用
  • 前端性能优化实战:如何高效管理和加载图片、字体、脚本资源