news 2026/6/10 12:20: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/6/10 2:58:42

5步掌握Pytorch图像去雾:从零到精通的完整教程

5步掌握Pytorch图像去雾&#xff1a;从零到精通的完整教程 【免费下载链接】DehazeNet_Pytorch A Pytorch implementation for DehazeNet in paper DehazeNet: An End-to-End System for Single Image Haze Removal 项目地址: https://gitcode.com/gh_mirrors/de/DehazeNet_P…

作者头像 李华
网站建设 2026/6/10 10:58:03

无需深度学习背景:产品经理的MGeo体验手册

无需深度学习背景&#xff1a;产品经理的MGeo体验手册 地址解析是许多互联网产品中不可或缺的功能&#xff0c;无论是外卖配送、物流追踪还是用户注册&#xff0c;都需要准确识别地址中的省市区信息。MGeo作为达摩院与高德联合推出的地理文本处理模型&#xff0c;能够高效完成地…

作者头像 李华
网站建设 2026/6/10 10:57:39

Golang实现抖音直播数据采集:从技术原理到实践应用

Golang实现抖音直播数据采集&#xff1a;从技术原理到实践应用 【免费下载链接】douyin-live-go 抖音(web) 弹幕爬虫 golang 实现 项目地址: https://gitcode.com/gh_mirrors/do/douyin-live-go 你是否曾想过&#xff0c;那些在抖音直播间里快速滚动的弹幕、不断刷新的礼…

作者头像 李华
网站建设 2026/6/10 7:56:30

OpenModScan终极指南:完全免费的工业级Modbus调试解决方案

OpenModScan终极指南&#xff1a;完全免费的工业级Modbus调试解决方案 【免费下载链接】OpenModScan Open ModScan is a Free Modbus Master (Client) Utility 项目地址: https://gitcode.com/gh_mirrors/op/OpenModScan 在现代工业自动化和物联网项目中&#xff0c;Ope…

作者头像 李华
网站建设 2026/6/10 8:01:35

从单点防御到协同韧性:2025 金融证券安全十大事件启示录

2025年&#xff0c;全球金融证券行业遭遇了前所未有的网络安全风暴。供应链攻击持续破防、双重勒索模式愈演愈烈、内外部威胁交织共振&#xff0c;十大典型安全事件累计波及超3000万用户&#xff0c;覆盖征信巨头、加密交易所、证券交易所、跨国银行等核心金融基础设施&#xf…

作者头像 李华
网站建设 2026/6/10 8:00:51

终极mumax3使用指南:快速掌握GPU加速微磁模拟

终极mumax3使用指南&#xff1a;快速掌握GPU加速微磁模拟 【免费下载链接】3 GPU-accelerated micromagnetic simulator 项目地址: https://gitcode.com/gh_mirrors/3/3 mumax3是一款专业的GPU加速微磁模拟软件&#xff0c;专门为磁性材料研究和磁学计算设计。作为新一代…

作者头像 李华