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

C指针---指针数组与数组指针

目录

1.什么是指针数组

1.1 应用场景

1.1.1用指针数组处理多个字符串

1.1.2. 使用指针数组处理多维数组

2.什么是数组指针

2.1数组指针与普通指针的区别

2.2 应用场景

2.1.1. 处理多维数组

2.2.2. 传递固定大小的数组(三维数组:块,行,列)

2.3.3 数组指针作为函数返回值

2.3.4. 与动态内存分配结合使用

3.解引用


1.什么是指针数组

在C语言中,指针数组是一个数组,其中的每个元素都是指针类型。指针数组的声明形式为:

int *arr[3]; // arr是一个包含3个元素的指针数组,每个元素都是int类型的指针

在这个例子中,arr是一个包含 3 个元素的数组,每个元素都是指向int类型的指针。可以通过赋值给每个元素来初始化这些指针

下面是关于如何简单使用指针数组的示例:

#include <stdio.h> int main() { int a = 10, b = 20, c = 30; int *arr[3]; // 定义一个指针数组,包含3个元素 arr[0] = &a; // arr[0]指向a arr[1] = &b; // arr[1]指向b arr[2] = &c; // arr[2]指向c // 打印数组中的指针指向的值 printf("arr[0] points to value: %d\n", *arr[0]); printf("arr[1] points to value: %d\n", *arr[1]); printf("arr[2] points to value: %d\n", *arr[2]); return 0; }

解释:

arr[0] = &a;a的地址赋值给arr[0],即arr[0]指向a

*arr[0]解引用指针,访问arr[0]所指向的值,即a的值。

1.1 应用场景

指针数组常用于处理多个指针的集合,例如在处理多个字符串或多维数组

1.1.1用指针数组处理多个字符串

在C语言中,字符串是以字符数组的形式存储的,而指针数组可以用来存储多个字符串字符数组的指针)。

#include <stdio.h> int main() { // 定义一个指针数组,数组中的每个元素是指向字符串的指针 char *arr[] = {"Hello", "World", "C", "Programming"}; // 使用指针数组访问每个字符串 for (int i = 0; i < 4; i++) { printf("String %d: %s\n", i + 1, arr[i]); } return 0; }

解释:

char *arr[]是一个指针数组,每个元素都是一个char*类型的指针,指向一个字符串(即字符数组)。

arr[i]可以访问数组中的每个字符串。

1.1.2. 使用指针数组处理多维数组

指针数组还可以用于处理多维数组,尤其是二维数组的情况。

#include <stdio.h> int main() { // 定义一个二维数组 int arr[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; // 定义一个指向二维数组的指针数组 int *ptrArr[3]; // 将每行的首地址赋给指针数组 for (int i = 0; i < 3; i++) { ptrArr[i] = arr[i]; // 每个指针指向二维数组的一行 } // 使用指针数组访问二维数组元素 for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { printf("arr[%d][%d] = %d\n", i, j, ptrArr[i][j]); } } return 0; }

解释:

ptrArr[i] = arr[i]:这里将arr中每一行的首地址赋给指针数组ptrArr。每个ptrArr[i]就是指向arr[i]的指针。

通过指针数组ptrArr[i][j]访问二维数组中的元素

2.什么是数组指针

数组指针是指向数组的指针(本质上是一个指针)与指针数组不同,数组指针指向的是一个整个数组,而不是数组的单个元素。

用例:声明一个指向包含 5 个int元素的数组的指针

int (*ptr)[5];

代码示例:

#include <stdio.h> int main() { int arr[3] = {10, 20, 30}; int (*ptr)[3] = &arr; // ptr 是一个指向数组的指针 // 通过数组指针访问数组元素 printf("arr[0] = %d\n", (*ptr)[0]); printf("arr[1] = %d\n", (*ptr)[1]); printf("arr[2] = %d\n", (*ptr)[2]); // 也可以直接通过数组指针遍历数组 for (int i = 0; i < 3; i++) { printf("arr[%d] = %d\n", i, (*ptr)[i]); } return 0; }

解释:

int (*ptr)[3] = &arr;:声明了一个数组指针ptr,它指向一个包含 3 个int元素的数组。

(*ptr)[i]:通过解引用数组指针ptr来访问数组元素。

数组指针与指针数组的比较:

数组指针:指向整个数组。例如,int (*ptr)[5];是一个指向包含 5 个int元素数组的指针。

指针数组:是一个数组,数组中的每个元素都是一个指针。例如,int *arr[5];是一个包含 5 个int类型指针的数组。

2.1数组指针与普通指针的区别

数组指针是指向整个数组的指针,它可以用来操作整个数组。

普通指针是指向数组中单个元素的指针。

2.2 应用场景

数组指针在C语言中也有一些特定的应用场景,尤其是在处理多维数组或者在函数传递数组时,数组指针显得非常有用。

2.1.1. 处理多维数组

数组指针在处理多维数组时非常有用,特别是想要传递一个二维数组给函数时,数组指针可以提供一种方便且简洁的方式。

#include <stdio.h> void print2DArray(int (*arr)[3], int rows) { for (int i = 0; i < rows; i++) { for (int j = 0; j < 3; j++) { printf("%d ", arr[i][j]); } printf("\n"); } } int main() { int arr[2][3] = { {1, 2, 3}, {4, 5, 6} }; // 使用数组指针传递二维数组 print2DArray(arr, 2); return 0; }

参数解释

int (*arr)[3]:表示arr是一个指向大小为 3 的数组的指针。

int rows:表示二维数组的行数。

当调用print2DArray(array, 2)时:array实际上是&array[0],它是一个int (*)[3]类型的指针,指向二维数组的第一行。

函数内部arr[i]表示第i行数组,arr[i][j]表示第i行第j列的具体元素。

为什么使用数组指针?

使用数组指针的好处是,它简化了多维数组的传递和访问,同时保留了数组的结构信息。例如:

  • 如果我用数组指针,而是直接传递一个普通的指针int *,则需要额外传递列数信息来计算索引,访问数组变得复杂。
  • 使用数组指针时,编译器知道每一行的元素数量(3 个int),可以正确计算内存偏移量。

2.2.2. 传递固定大小的数组(三维数组:块,行,列)

当你需要传递固定大小的数组(如 2D 数组)给函数时,数组指针是一个非常有效的工具。

#include <stdio.h> void print3DArray(int(*arr)[3][1]) { for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { printf("%d ", arr[i][j][0]); } printf("\n"); } } int main() { int arr[2][3][1] = { {{1}, {2}, {3}}, {{4}, {5}, {6}} }; // 传递数组指针到函数 print3DArray(arr); return 0; }

int (*arr)[2][3]表示指向 2x3 的三维数组的指针。

arr的本质

在 C 中,数组名在大多数上下文中会退化为指向数组首元素的指针。对于一个三维数组:

  • arr是指向第一个二维数组(arr[0])的指针。
  • 类型为int (*)[3][1],即“指向包含 3 行,每行 1 列的二维数组的指针”。

2.3.3 数组指针作为函数返回值

在某些情况下,希望一个函数返回一个指向数组的指针。数组指针可以帮助我们以更简洁的方式处理这类需求。

#include <stdio.h> int (*getArray())[3] { static int arr[3] = {10, 20, 30}; return &arr; // 返回指向数组的指针 // 返回数组的地址 } int main() { int (*arrPtr)[3] = getArray(); // 获取指向数组的指针 // 使用返回的指针访问数组元素 printf("arr[0] = %d\n", (*arrPtr)[0]); printf("arr[1] = %d\n", (*arrPtr)[1]); printf("arr[2] = %d\n", (*arrPtr)[2]); return 0; }

换句话说:getArray是一个返回指向包含 3 个整数的数组的指针的函数

  • getArray()是一个函数,说明它可以被调用。

  • (*getArray())表明这个函数返回一个指针。(指针函数)
  • (*getArray())[3]表示这个指针指向一个包含 3 个整数的数组。

函数getArray()的返回值是int (*)[3]

  • int (*)[3]是一种指针类型,它指向一个包含 3 个整数的数组。

注意:易混淆说明:直接返回arr

如果函数这样写:那么返回的类型是指向数组首元素的指针,即int*,而不是int (*)[3]

  • arr的类型是int*,指向arr[0]
  • &arr是数组的地址,表示整个数组在内存中的位置。

2.3.4. 与动态内存分配结合使用

在动态内存分配时,如果需要分配多维数组并通过指针传递给函数,数组指针是一个很好的选择。

#include <stdio.h> #include <stdlib.h> void printDynamicArray(int (*arr)[3], int rows) { for (int i = 0; i < rows; i++) { for (int j = 0; j < 3; j++) { printf("%d ", arr[i][j]); } printf("\n"); } } int main() { // 动态分配二维数组 int (*arr)[3] = malloc(2 * sizeof(*arr)); // 为 2 行 3 列的数组分配内存 // 初始化数组 arr[0][0] = 1; arr[0][1] = 2; arr[0][2] = 3; arr[1][0] = 4; arr[1][1] = 5; arr[1][2] = 6; // 传递数组指针 printDynamicArray(arr, 2); // 释放内存 free(arr); return 0; }
  • 使用malloc动态分配一个 2 行 3 列的二维数组。
  • 使用数组指针arr传递到printDynamicArray函数中,打印数组内容。

3.解引用

解引用操作符*的作用是:取出指针所指向的地址中存储的值。

当您对指针进行解引用时:

  • 如果指针指向的是数组/字符串,解引用得到的是第一个元素

  • 如果指针指向的是指针,解引用得到的是被指向的指针

http://www.jsqmd.com/news/1161509/

相关文章:

  • 2026年7月天津本地本科征集报考公司推荐排行一览 - 起跑123
  • Kubernetes Secret 加密实践:ETCD 里的敏感信息不能明文存
  • CSS相关内容(七)
  • 如何在draw.io中快速创建专业C4架构图:c4-draw.io插件完全指南
  • 2026济南钻石回收市场深度调研:行情波动下的价值锚点 - 奢侈品回收中心
  • 如何快速掌握图片元数据管理:ExifToolGUI免费开源工具完整指南
  • ExifToolGUI:图像元数据管理的终极可视化解决方案
  • 2026【同城便民上门】佛山全城上门回收劳力士名表,易奢福专业鉴定当场转账结算 - 奢侈品回收实体店
  • 2026实力之选黑河名表名包奢侈品回收帝舵宝珀沛纳海爱马仕迪奥圣罗兰攻略正规机构评测全城上门当面交易 - 谊识预商务
  • 携程礼品卡回收平台甄选实录|4家主流渠道PK+全流程体验,哪里高价收、哪里会吞卡、怎么防被坑 - 京质回收
  • 2026年帝舵官方售后服务体系升级:官方地址、电话全新公示 - 帝舵官方维修中心
  • 如何用Gamdl轻松下载Apple Music无损音乐:面向新手的完整指南 [特殊字符]
  • 突破架构壁垒:如何在PowerPC平台实现vLLM高性能部署
  • 小白必看!Claude Code Windows完整指南,一篇搞定配置
  • ExifToolGUI:告别照片管理烦恼,用图形界面轻松驾驭专业元数据编辑
  • 【方案选型】一颗植物灯专用循环定时芯片EH3510-AA4E-571E
  • 英雄联盟Akari助手:终极智能游戏效率提升工具完全指南
  • DeepSeek-V4+PyPDF2+tabula自动化解析PDF财报实战
  • Pacparser:企业级网络代理自动化配置的高效解决方案
  • 2026实力之选黄冈名表名包奢侈品回收帝舵积家伯爵爱马仕迪奥圣罗兰指南实测5家门店报价高打款快服务好 - 谊识预商务
  • cpp_redis线程安全机制深度解析:多线程环境下的Redis客户端最佳实践
  • 邵阳GEO AI优化市场价大概多少 - 舒雯文化
  • 2026北京奢侈品回收哪家正规?毓典领衔全城合规资质门店梯队榜单 - 奢品流通笔谈
  • 南京有上门测漏服务吗?检测选型专业解读 - 徽顺虹
  • EulerCopilot Web未来路线图:新功能展望与社区贡献方向
  • 实战指南:NextAI Translator - 多引擎AI翻译工具深度解析与高效使用
  • 2026年海南个体户核定代办配套完善公司TOP5推荐
  • 亨得利中国官方售后服务体系全攻略|官方门店地址及客服电话全新公告(2026年7月最新) - 亨得利中国服务中心
  • 双层OLED触控屏如何重塑商务本体验上限
  • 浦东 / 静安 / 徐汇名表回收实力榜|PP 手雷、AP 离岸型高价渠道仅这几家 - 融媒生活