C指针---指针数组与数组指针
数组指针是指向数组的指针(本质上是一个指针)与指针数组不同,数组指针指向的是一个整个数组,而不是数组的单个元素。用例:声明一个指向包含 5 个int元素的数组的指针// ptr 是一个指向数组的指针// 通过数组指针访问数组元素// 也可以直接通过数组指针遍历数组i < 3;:声明了一个数组指针ptr,它指向一个包含 3 个int元素的数组。(*ptr)[i]:通过解引用数组指针ptr来访问数组元
目录
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
函数中,打印数组内容。
更多推荐
所有评论(0)