news 2026/2/10 1:03:20

42.指针和数组

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
42.指针和数组

一、指针和数组名可互换的场景(核心:数组名被隐式转换为指针)

绝大多数表达式场景中,数组名会被编译器隐式转换为指向数组第一个元素的指针(这个转换也叫“数组退化为指针”),此时二者的用法完全等价。

1. 访问数组元素([]下标访问)

数组名用下标访问,本质是*(数组名 + 偏移量);指针也支持同样的语法,二者完全互换。

#include <stdio.h> int main() { int arr[5] = {1,2,3,4,5}; int *p = arr; // 数组名arr隐式转为指向arr[0]的指针 // 以下4种写法完全等价,输出均为3 printf("%d\n", arr[2]); // 数组名+下标 printf("%d\n", *(arr+2)); // 数组名转指针+指针运算 printf("%d\n", p[2]); // 指针+下标 printf("%d\n", *(p+2)); // 指针+指针运算 return 0; }
2. 函数参数传递

当数组作为函数参数时,编译器会自动将其转换为指向第一个元素的指针(即使写int arr[],实际也是int *arr),此时形参的指针和实参的数组名完全互换。

// 形参写int arr[] 或 int *arr 效果完全一样 void print_arr(int arr[], int len) { for(int i=0; i<len; i++) { printf("%d ", *(arr+i)); // 等价于arr[i] } } int main() { int arr[5] = {1,2,3,4,5}; int *p = arr; print_arr(arr, 5); // 传数组名 print_arr(p, 5); // 传指针,效果完全相同 return 0; }
3. 取地址后访问(&

数组名取地址(&arr)是指向整个数组的指针,指针取地址(&p)是指向指针变量的指针,但如果仅用于访问元素,仍可互换(需注意类型匹配)。

int arr[5] = {1,2,3,4,5}; int *p = arr; // 访问arr[1],以下写法等价 printf("%d\n", (*&arr)[1]); // &arr是数组指针,解引用后回到数组名 printf("%d\n", (*&p)[1]); // &p是指针的指针,解引用后回到指针p

二、指针和数组名不可互换的场景(核心:数组名是“常量”,指针是“变量”)

数组名的本质是数组首元素地址的常量(不能被修改),而指针是存放地址的变量(可自由修改),这一本质区别导致以下场景绝对不能混用。

1. 试图修改数组名(赋值操作)

数组名是常量,不能被赋值;指针是变量,可随意赋值指向不同地址。

int arr[5] = {1,2,3,4,5}; int *p = arr; p++; // 合法:指针变量可以自增,指向arr[1] // arr++; // 非法!编译报错:数组名是常量,不能修改(lvalue required) p = &arr[2]; // 合法:指针指向arr[2] // arr = &arr[2]; // 非法!数组名不能被赋值
2. 使用sizeof运算符

sizeof(数组名)计算的是整个数组的字节大小sizeof(指针)计算的是指针变量本身的字节大小(与平台有关,32位系统4字节,64位8字节),二者结果完全不同。

int arr[5] = {1,2,3,4,5}; int *p = arr; // 关键区别! printf("%zu\n", sizeof(arr)); // 输出20(5个int,每个4字节:5*4=20) printf("%zu\n", sizeof(p)); // 输出8(64位系统)或4(32位系统) // 即使指针指向整个数组,结果仍不同 int (*arr_ptr)[5] = &arr; // 指向整个数组的指针 printf("%zu\n", sizeof(arr_ptr)); // 还是8/4,不是20
3. 取地址运算的类型和偏移

&arr是指向整个数组的指针(类型为int (*)[5]),&p是指向指针变量的指针(类型为int **),二者的偏移规则完全不同,混用会导致地址错误。

int arr[5] = {1,2,3,4,5}; int *p = arr; // &arr是数组指针(int (*)[5]),+1偏移整个数组的大小(20字节) printf("%p\n", &arr); // 假设输出0x7ffeefbff560 printf("%p\n", &arr + 1); // 输出0x7ffeefbff574(0x560 + 20 = 0x574) // &p是指针的指针(int **),+1偏移指针变量的大小(8字节) printf("%p\n", &p); // 假设输出0x7ffeefbff558 printf("%p\n", &p + 1); // 输出0x7ffeefbff560(0x558 + 8 = 0x560) // 若强行混用,会访问错误地址 int (*ap)[5] = &p; // 类型不匹配,编译警告,运行时访问错误
4. 字符串常量与字符数组(特殊场景)

字符数组名是可修改的(数组元素可改),而指向字符串常量的指针是只读的,混用会导致运行时错误。

// 字符数组:内存在栈上,可修改 char str_arr[] = "hello"; str_arr[0] = 'H'; // 合法,输出Hello // 字符串指针:指向只读数据区(.rodata),不可修改 char *str_ptr = "hello"; // str_ptr[0] = 'H'; // 非法!编译可能通过,但运行时崩溃(段错误)

三、底层原理总结

特性

数组名

指针

本质

数组首元素地址的常量

存放地址的变量

是否可修改

不可(如++、赋值)

可(如++、指向新地址)

sizeof运算

整个数组的字节大小

指针变量本身的字节大小

取地址(&)类型

指向整个数组的指针

指向指针变量的指针

总结

  1. 可互换场景:仅当数组名被隐式转换为指针时(如下标访问、函数参数传递),指针和数组名的用法完全等价;
  2. 不可互换场景:涉及修改操作(如++、赋值)、sizeof运算、取地址后的偏移、字符串常量修改时,二者本质不同,绝对不能混用;
  3. 核心记忆点:数组名是“常量指针”(地址不可改),指针是“变量指针”(地址可改),这是二者所有区别的根源。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/8 10:17:09

如何快速掌握GPU加速微磁模拟:从入门到精通

如何快速掌握GPU加速微磁模拟&#xff1a;从入门到精通 【免费下载链接】3 GPU-accelerated micromagnetic simulator 项目地址: https://gitcode.com/gh_mirrors/3/3 mumax作为一款革命性的GPU加速微磁模拟器&#xff0c;彻底改变了传统磁性材料研究的计算方式。通过充…

作者头像 李华
网站建设 2026/2/8 23:01:03

AB下载管理器完整使用指南:告别杂乱下载的终极解决方案

AB下载管理器完整使用指南&#xff1a;告别杂乱下载的终极解决方案 【免费下载链接】ab-download-manager A Download Manager that speeds up your downloads 项目地址: https://gitcode.com/GitHub_Trending/ab/ab-download-manager 你是否曾经为了寻找下载的文件而翻…

作者头像 李华
网站建设 2026/2/6 17:47:17

终极指南:5分钟快速上手MeteoInfo气象GIS与科学计算平台

终极指南&#xff1a;5分钟快速上手MeteoInfo气象GIS与科学计算平台 【免费下载链接】MeteoInfo MeteoInfo: GIS, scientific computation and visualization environment. 项目地址: https://gitcode.com/gh_mirrors/me/MeteoInfo MeteoInfo是一款专为气象领域设计的开…

作者头像 李华
网站建设 2026/2/8 2:19:49

OpenModScan:完全免费的Modbus调试工具终极指南

OpenModScan&#xff1a;完全免费的Modbus调试工具终极指南 【免费下载链接】OpenModScan Open ModScan is a Free Modbus Master (Client) Utility 项目地址: https://gitcode.com/gh_mirrors/op/OpenModScan 还在为工业自动化项目中复杂的Modbus通讯调试而烦恼吗&…

作者头像 李华
网站建设 2026/2/9 9:09:56

孤能子视角:“教育“动力学分析

EIS视角下的“教育”动力学分析第一阶段&#xff1a;启动——元三力逼问&#xff0c;定位张力1. 存续驱动 教育系统的存续驱动&#xff1a;教育作为文明系统维持自身模式存续的核心机制。它既是个体为获取生存能力&#xff08;知识、技能、社会化&#xff09;的内在驱动&#x…

作者头像 李华
网站建设 2026/2/5 4:39:27

ChanlunX缠论分析工具:从理论到实战的完整指南

ChanlunX缠论分析工具&#xff1a;从理论到实战的完整指南 【免费下载链接】ChanlunX 缠中说禅炒股缠论可视化插件 项目地址: https://gitcode.com/gh_mirrors/ch/ChanlunX 缠论作为中国原创的技术分析理论&#xff0c;在股票投资领域具有重要地位。ChanlunX缠论可视化插…

作者头像 李华