C语言高频面试题——指针数组和数组指针

news2025/4/22 18:12:42

指针数组和数组指针是 C/C++ 中容易混淆的两个概念,以下是详细对比:


1. 指针数组(Array of Pointers)

  • 定义:一个数组,其元素是 指针类型
  • 语法type* arr[元素个数];
    • 例如:int* ptr_array[5]; 表示一个包含 5 个 int* 类型指针的数组。
  • 内存布局
    • 数组本身占用连续内存空间,每个元素存储的是 指针的值(即地址)。
    • 每个指针可以指向任意地址(例如不同变量、不同数组的元素)。
  • 用途
    • 存储多个指针(如字符串数组、函数指针数组)。
    • 示例:
      int a = 1, b = 2, c = 3;
      int* ptr_array[3] = {&a, &b, &c}; // 每个元素指向一个整型变量
      

2. 数组指针(Pointer to Array)

  • 定义:一个指针,指向 数组类型
  • 语法type (*ptr)[数组长度];
    • 例如:int (*arr_ptr)[10]; 表示一个指向 int[10] 类型数组的指针。
  • 内存布局
    • 指针本身只存储一个地址(指向数组的首元素)。
    • 通过该指针访问时,编译器会根据数组长度计算元素偏移。
  • 用途
    • 操作多维数组(如作为函数参数传递二维数组)。
    • 示例:
      int arr[5] = {1, 2, 3, 4, 5};
      int (*arr_ptr)[5] = &arr; // 指向整个数组
      

关键区别总结

特性指针数组数组指针
类型数组元素是 type*(指针)指向 type[长度](数组类型)
声明语法type* arr[大小];type (*ptr)[大小];
内存占用大小 × sizeof(指针)sizeof(指针)(通常 8 字节)
解引用操作arr[i] 是一个 type* 类型指针*ptr 是一个 type[大小] 类型数组
典型用途存储多个指针(如字符串数组)操作多维数组或动态数组

示例对比

  1. 指针数组

    int a = 1, b = 2, c = 3;
    int* ptr_array[3] = {&a, &b, &c};
    printf("%d", *ptr_array[0]); // 输出 1
    
  2. 数组指针

    int arr[3] = {10, 20, 30};
    int (*arr_ptr)[3] = &arr;
    printf("%d", (*arr_ptr)[1]); // 输出 20
    

常见误区

  • 语法陷阱int* ptr1[5](指针数组)和 int (*ptr2)[5](数组指针)的括号位置不同,含义完全不同。
  • 数组名 vs 指针:数组名 arr 是数组首元素的地址(类型为 int*),而 &arr 是整个数组的地址(类型为 int(*)[N])。

总结

  • 指针数组:存指针的数组,每个元素是独立指针。
  • 数组指针:指向整个数组的指针,通过它访问数组元素时需考虑数组长度。

代码

int arr[3] = {10, 20, 30};
int (*ptr)[3] = &arr; // ptr 是指向数组的指针,类型为 int(*)[3]

表达式 1:*((*ptr) + 1)

分步解析:
  1. ptr 的类型int(*)[3](指向长度为3的数组的指针)。
  2. *ptr 的类型int[3](即数组 arr 本身)。
  3. *ptr 的退化:在表达式中,数组名会退化为指向首元素的指针,因此 *ptr 退化为 int* 类型,指向 arr[0]
  4. (*ptr) + 1
    • *ptrint* 类型,指向 arr[0]
    • +1 操作会移动 1 * sizeof(int) 字节(假设 int 占4字节)。
    • 结果地址:&arr[0] + 1&arr[1]
  5. *((*ptr) + 1)
    • 解引用 &arr[1],得到 arr[1] 的值 20
内存布局图示:
arr 地址:0x1000
| 0x1000 | 0x1004 | 0x1008 |
| 10     | 20     | 30     |

ptr 地址:0x2000
| 0x2000 |
| 0x1000 | // ptr 存储的是数组 arr 的地址

(*ptr) + 1 → 0x1000 + 1 * 4 = 0x1004 → 指向 20

表达式 2:*(ptr + 1)

分步解析:
  1. ptr 的类型int(*)[3](指向长度为3的数组的指针)。
  2. ptr + 1
    • ptr 的类型是 int(*)[3],因此 +1 操作会移动 1 * sizeof(int[3]) 字节。
    • sizeof(int[3]) = 3 * 4 = 12 字节(假设 int 占4字节)。
    • 结果地址:0x1000 + 12 = 0x100C(超出原数组范围)。
  3. *(ptr + 1)
    • 解引用非法地址 0x100C,导致 未定义行为(可能读取垃圾值或程序崩溃)。
内存布局图示:
ptr + 1 → 0x1000 + 12 = 0x100C(该地址未分配给 arr)
| 0x100C | 0x1010 | 0x1014 | ...(未知内存)
| ????   | ????   | ????   |

关键区别总结

表达式类型指针运算步长访问的内存地址结果
*((*ptr) + 1)int1 * sizeof(int)&arr[1](合法地址)20
*(ptr + 1)int[3](数组)1 * sizeof(int[3])&arr + 1(非法地址)未定义行为(如崩溃)

为什么会有这样的差异?

  • ptr 的类型决定了指针运算的步长
    • ptrint(*)[3]ptr + 1 跳过整个数组(3个 int)。
    • *ptr 退化为 int*(*ptr) + 1 跳过一个 int
  • 数组指针 vs 普通指针
    • ptr 是数组指针,操作的是整个数组。
    • *ptr 是普通指针,操作的是数组的元素。

类比解释

假设有一个书架:

  • ptr:指向整个书架(书架地址)。
    • ptr + 1 → 移动到下一个书架(可能不存在)。
  • *ptr:指向书架上的第一本书(书的地址)。
    • (*ptr) + 1 → 移动到书架上的第二本书。

代码验证

#include <stdio.h>

int main() {
    int arr[3] = {10, 20, 30};
    int (*ptr)[3] = &arr;

    printf("表达式1: %d\n", *((*ptr) + 1)); // 输出 20
    printf("表达式2: %d\n", *(ptr + 1));    // 未定义行为(可能输出垃圾值或崩溃)
    return 0;
}

在这里插入图片描述


总结

  • *((*ptr) + 1):操作数组元素,合法且安全。
  • *(ptr + 1):操作数组外的内存,危险且非法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2340271.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux服务器配置Anaconda环境、Pytorch库(图文并茂的教程)

引言&#xff1a;为了方便后续新进组的 师弟/师妹 使用课题组的服务器&#xff0c;特此编文&#xff08;ps&#xff1a;我导从教至今四年&#xff0c;还未招师妹&#xff09; ✅ NLP 研 2 选手的学习笔记 笔者简介&#xff1a;Wang Linyong&#xff0c;NPU&#xff0c;2023级&a…

Android端使用无障碍服务实现远程、自动刷短视频

最近在做一个基于无障碍自动刷短视频的APP&#xff0c;需要支持用任意蓝牙遥控器远程控制&#xff0c; 把无障碍服务流程大致研究了一下&#xff0c;从下面3个部分做一下小结。 1、需要可调整自动上滑距离和速度以适配不同的屏幕和应用 智能适配99%机型&#xff0c;滑动参数可…

搭建用友U9Cloud ERP及UAP IDE环境

应用环境 Microsoft Windows 10.0.19045.5487 x64 专业工作站版 22H2Internet Information Services - 10.0.19041.4522Microsoft SQL Server 2019 - 15.0.2130.3 (X64)Microsoft SQL Server Reporing Services 2019 - 15.0.9218.715SQL Server Management Studio -18.6 laster…

多模态大语言模型arxiv论文略读(二十九)

Temporal Insight Enhancement: Mitigating Temporal Hallucination in Multimodal Large Language Models ➡️ 论文标题&#xff1a;Temporal Insight Enhancement: Mitigating Temporal Hallucination in Multimodal Large Language Models ➡️ 论文作者&#xff1a;Li Su…

卷积神经网络(CNN)详解

文章目录 引言1.卷积神经网络&#xff08;CNN&#xff09;的诞生背景2.卷积神经网络&#xff08;CNN&#xff09;介绍2.1 什么是卷积神经网络&#xff1f;2.2 卷积神经网络&#xff08;CNN&#xff09;的基本特征2.2.1 局部感知&#xff08;Local Connectivity&#xff09;2.2.…

【SF顺丰】顺丰开放平台API对接(注册、API测试篇)

1.注册开发者账号 注册地址&#xff1a;顺丰企业账户中心 2.登录开发平台 登录地址&#xff1a;顺丰开放平台 3.开发者对接 点击开发者对接 4.创建开发对接应用 开发者应用中“新建应用”创建应用&#xff0c;最多创建应用限制数量5个 注意&#xff1a;需要先复制保存生产校验…

VisualSVN过期后的解决方法

作为一款不错的源代码管理软件&#xff0c;svn还是有很多公司使用的。在vs中使用svn&#xff0c;大家一般用的都是VisualSVN插件。在30天试用期过后&#xff0c;它就不能被免费使用了。下面给大家讲如何免费延长过期时间&#xff08;自定义天数&#xff0c;可以设定一个很大的值…

DeepSeek智能时空数据分析(二):3秒对话式搞定“等时圈”绘制

序言&#xff1a;时空数据分析很有用&#xff0c;但是GIS/时空数据库技术门槛太高 时空数据分析在优化业务运营中至关重要&#xff0c;然而&#xff0c;三大挑战仍制约其发展&#xff1a;技术门槛高&#xff0c;需融合GIS理论、SQL开发与时空数据库等多领域知识&#xff1b;空…

STM32学习2

一、OLED 1.1 OLED介绍 OLED&#xff08;Organic Light Emitting Diode&#xff09;&#xff1a;有机发光二极管 OLED显示屏&#xff1a;性能优异的新型显示屏&#xff0c;具有功耗低、相应速度快、宽视角、轻薄柔韧等特点 0.96寸OLED模块&#xff1a;小巧玲珑、占用接口少…

LabVIEW液压系统远程监控与故障诊断

开发了一种基于LabVIEW的远程液压系统监控解决方案&#xff0c;通过先进的数据采集与分析技术&#xff0c;有效提升工程机械的运作效率和故障响应速度。该系统结合现场硬件设备和远程监控软件&#xff0c;实现了液压系统状态的实时检测和故障诊断&#xff0c;极大地提升了维护效…

Idea中实用设置和插件

目录 一、Idea使用插件 1.Fitten Code智能提示 2.MyBatisCodeHelperPro 3.HighlightBracketPair‌ 4.Rainbow Brackets Lite 5.GitToolBox(存在付费) 6.MavenHelperPro 7.Search In Repository 8.VisualGC(存在付费) 9.vo2dto 10.Key Promoter X 11.CodeGlance…

Java写数据结构:栈

1.概念&#xff1a; 一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 压栈&#xff1a;栈的插…

机器学习-08-推荐算法-案例

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中关联规则 参考 机器学习&#xff08;三&#xff09;&#xff1a;Apriori算法&#xff08;算法精讲&#xff09; Apriori 算法 理论 重点 MovieLens:一个常用的电影推荐系统领域的数据集 23张图&#x…

LLM中的N-Gram、TF-IDF和Word embedding

文章目录 1. N-Gram和TF-IDF&#xff1a;通俗易懂的解析1.1 N-Gram&#xff1a;让AI学会"猜词"的技术1.1.1 基本概念1.1.2 工作原理1.1.3 常见类型1.1.4 应用场景1.1.5 优缺点 1.2 TF-IDF&#xff1a;衡量词语重要性的尺子1.2.1 基本概念1.2.2 计算公式1.2.3 为什么需…

Office文件内容提取 | 获取Word文件内容 |Javascript提取PDF文字内容 |PPT文档文字内容提取

关于Office系列文件文字内容的提取 本文主要通过接口的方式获取Office文件和PDF、OFD文件的文字内容。适用于需要获取Word、OFD、PDF、PPT等文件内容的提取实现。例如在线文字统计以及论文文字内容的提取。 一、提取Word及WPS文档的文字内容。 支持以下文件格式&#xff1a; …

HXBC编译相关错误

0、Keil MDK报错:Browse information of one or more files is not available----解决方法: 1、使用cubemax生成的工程中,某些引脚自定义了的,是在main.h中,要记得移植。 注意:cubemax生成的spi.c后,在移植的时候,注意hal_driver下面要对应增加hal_stm32H7xxxspi.c …

运维概述(linux 系统)

1、运维的基本概念 2、企业的运行模式 3、计算机硬件 运维概述 运维岗位的定义 在技术人员&#xff08;写代码的&#xff09;之间&#xff0c;一致对运维有一个开玩笑的认知&#xff1a;运维就是修电脑的、装网线的、背锅的岗位。 IT运维管理是指为了保障企业IT系统及网络…

C语言 数据结构 【堆】动态模拟实现,堆排序,TOP-K问题

引言 堆的各个接口的实现&#xff08;以代码注释为主&#xff09;&#xff0c;实现堆排序&#xff0c;解决经典问题&#xff1a;TOP-K问题 一、堆的概念与结构 堆 具有以下性质 • 堆中某个结点的值总是不大于或不小于其父结点的值&#xff1b; • 堆总是一棵完全二叉树。 二…

模型加载常见问题

safetensors_rust.SafetensorError: Error while deserializing header: HeaderTooLarge 问题代码&#xff1a; model AutoModelForVision2Seq.from_pretrained( "/data-nvme/yang/Qwen2.5-VL-32B-Instruct", trust_remote_codeTrue, torch_dtypetorc…

PyTorch 深度学习实战(37):分布式训练(DP/DDP/Deepspeed)实战

在上一篇文章中&#xff0c;我们探讨了混合精度训练与梯度缩放技术。本文将深入介绍分布式训练的三种主流方法&#xff1a;Data Parallel (DP)、Distributed Data Parallel (DDP) 和 DeepSpeed&#xff0c;帮助您掌握大规模模型训练的关键技术。我们将使用PyTorch在CIFAR-10分类…