C语言中的数组指针和指针数组的概念和应用
原创作者:三玹
转载请保留相关信息
俗话说得好,C语言的指针是初学者的终点,也是高级Cer的起点。
在步入指针广袤的海洋中,会碰到各类形形色色的指针。其中,数组指针和指针数组是是一开始容易混淆的两个概念。
区分数组指针和指针数组
虽然这两个东西看着像是孪生兄弟一样,但它们的概念和工作方式是截然不同的。尤其放在代码中,有时候也分不清谁是谁。
int (*arr)[5];
int *arr[5];
在编程语言中,每个符号都具备相应的优先级。就跟我们学数学,先乘除后加减一个道理。
而在上面这两个声明中,()
和 []
的优先级算是最高的,解引用运算符 *
的优先级就要次于二者。
由此代入到声明,第一个式子中先是定义了一个指针 *arr
,指针变量 arr
指向一个长度为 5 的匿名数组,数组中存储的是 5 个 int 类型的数据。所以第一个声明的是一个数组指针。
第二个声明中,[]
的优先级最高,因此变量名先和 [5]
进行组成,构成了一个长度为 5 的 arr
数组。
每个数组中的所有元素都必须要有统一的类型,而此时的类型就是 int*
整型指针类型。即说明当前的 arr
数组中可以存储 5 个整数指针类型的值,所以第二个声明的是一个指针数组。
这么说或许有点干,也有点绕,下面就将这两个拆开看一看。
数组指针
数组指针,它首先是一个指针,是指向数组的指针类型。允许用指针的方式,来访问数组中的元素。
来看个例子,现在我们初始化了一个整形数组arr
,里面包含了 5 个元素:
int arr[5] = {1, 2, 3, 4, 5};
而后,我们再声明一个ptr
的指针,用来指向这个数组。
int *ptr = arr;
当我们将数组变量赋值给指针变量,就是将数组的第一个元素 arr[0]
所在的内存地址赋值给了指针 ptr
。
因此,我们就可以直接使用这个指针来访问数组中的元素。
printf("%d\n", *ptr); // 输出 1
ptr++; // 指向下一个元素
printf("%d\n", *ptr); // 输出 2
指针数组
指针数组则是不同于数组指针的另一个概念,它首先是一个数组,然后数组中的每个元素都是一个指针。
来看一个例子,假设我们有两个字符串:
char *str1 = "Hello";
char *str2 = "World";
此时,我们可以使用指针数组来存储这两个字符串:
char *str_arr[2] = {str1, str2};
这样一来,我们就可以使用下标来访问这个数组中的每个元素,例如:
printf("%s %s\n", str_arr[0], str_arr[1]); // Hello World
需要注意的是,这里使用的是下标来访问数组中的元素,而不是用解引用运算符。
应用场景
在C语言当中,数组变量名本身就是一个指向数组第一个元素的指针。因此,我们就可以直接将数组传递给函数来访问数组中的元素,例如:
void print_array(int *arr, int size) {
for(int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
intarr[5] = {1, 2, 3, 4, 5};
print_array(arr, 5); // 输出 "1 2 3 4 5"
return0;
}
在这个函数中,我们使用了数组指针来访问数组中的元素。
而指针数组,我们可以用来存储动态分配的内存,例如:
char *strings[MAX_STRINGS];
int main() {
for(int i = 0; i < MAX_STRINGS; i++) {
strings[i] = malloc(100);
}
// 在这里使用 strings 数组
for(int i = 0; i < MAX_STRINGS; i++) {
free(strings[i]);
}
return 0;
}
在上面的代码中,我们使用了指针数组来存储动态分配的内存块。我们在用完这些内存后,需要使用 free
函数及时释放。
总结
在C语言中,数组指针和指针数组是两种很常见的概念。它们都是用来存储和访问数据,但两者的工作方式是不同的。
数组指针是指向数组的指针类型,可以用解引用运算符来访问数组中的元素;
指针数组是存储指针的数组,可以通过下标来访问指针数组中的元素。
它们分别都有自己相应的应用场景:
数组指针,常用于函数参数中,方便在函数中访问数组中的元素;
指针数组,常用于动态分配内存,在使用完之后要及时释放内存。
学习数组指针和指针数组的时候,最重要的是要熟悉它们的工作方式,以及明白它们在 C 语言当中的应用场景。
新上课程