news 2026/4/24 14:43:33

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/4/24 14:44:10

mytv-android:从零开始打造专属电视直播空间

mytv-android&#xff1a;从零开始打造专属电视直播空间 【免费下载链接】mytv-android 使用Android原生开发的电视直播软件&#xff08;source backup&#xff09; 项目地址: https://gitcode.com/gh_mirrors/myt/mytv-android 还在为找不到好用的电视直播软件而烦恼吗…

作者头像 李华
网站建设 2026/4/23 10:28:48

【新】基于SSM的在线购物网站【源码+文档+调试】

&#x1f495;&#x1f495;发布人&#xff1a; 星河码客 &#x1f495;&#x1f495;个人简介&#xff1a;混迹java圈十余年&#xff0c;精通Java、小程序、数据库等。 &#x1f495;&#x1f495;各类成品Java毕设 。javaweb&#xff0c;ssm&#xff0c;springboot等项目&…

作者头像 李华
网站建设 2026/4/17 0:34:03

【新】基于SSM的游戏购买下载平台【源码+文档+调试】

&#x1f495;&#x1f495;发布人&#xff1a; 星河码客 &#x1f495;&#x1f495;个人简介&#xff1a;混迹java圈十余年&#xff0c;精通Java、小程序、数据库等。 &#x1f495;&#x1f495;各类成品Java毕设 。javaweb&#xff0c;ssm&#xff0c;springboot等项目&…

作者头像 李华
网站建设 2026/4/23 12:48:41

革命性智能防休眠工具:彻底解决电脑自动锁屏的终极方案

革命性智能防休眠工具&#xff1a;彻底解决电脑自动锁屏的终极方案 【免费下载链接】mousejiggler Mouse Jiggler is a very simple piece of software whose sole function is to "fake" mouse input to Windows, and jiggle the mouse pointer back and forth. 项…

作者头像 李华
网站建设 2026/4/23 9:59:39

得意黑 Smiley Sans:重新定义中文黑体设计美学

得意黑 Smiley Sans&#xff1a;重新定义中文黑体设计美学 【免费下载链接】smiley-sans 得意黑 Smiley Sans&#xff1a;一款在人文观感和几何特征中寻找平衡的中文黑体 项目地址: https://gitcode.com/gh_mirrors/smi/smiley-sans 在数字设计领域&#xff0c;字体选择…

作者头像 李华
网站建设 2026/4/20 19:32:03

Windows系统下AI图像增强工具Upscayl启动故障全面解决指南

Windows系统下AI图像增强工具Upscayl启动故障全面解决指南 【免费下载链接】upscayl &#x1f199; Upscayl - Free and Open Source AI Image Upscaler for Linux, MacOS and Windows built with Linux-First philosophy. 项目地址: https://gitcode.com/GitHub_Trending/up…

作者头像 李华