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.解引用解引用操作符*的作用是取出指针所指向的地址中存储的值。当您对指针进行解引用时如果指针指向的是数组/字符串解引用得到的是第一个元素如果指针指向的是指针解引用得到的是被指向的指针