一、指针数组和数组指针的定义
指针数组:首先说明一点,它是一个数组,可以理解为存放指针的数组。
举例:int *arr1[10] = {0};
char *arr2[10] = {0};
//如果在32位的程序中,这里sizeof(arr1)和sizeof(arr2)它们的值都是40
//元素类型都是指针,在32位的程序里面,指针类型变量占4个字节,故4*10 = 40。
数组指针:它是一个指针,可以理解为指向一个数组的首元素的地址的指针。
举例:int (*pa)[10];
其实要区别指针数组和数组指针很简单,只需要记住运算符的优先级关系:即[]的优先级比*要高。
如果遇到*a[],a会先跟[]结合说明它是一个数组,再跟*结合说明该数组里面存放的是指针,即指针数组。
如果遇到(*a)[],括号优先级要高于[],所以a先与 *结合说明它是一个指针,再一个与[]结合说明该指针向了一个数组的首地址,及数组指针。
二、指针数组和数组指针的参数传递
1.指针数组的参数传递
读者请注意以下代码,我在主函数中定义了一个指针数组,当要把指针数组传递给子函数时,我们都知道不能直接将整个数组传递过去,如果数组太大的话,会使得内存的利用率很低,所以通常都是将数组的首元素的地址传给子函数。
下面的代码实现的功能是通过调用子函数来打印指针数组所指向的内容,arr的类型为 char*[],那么子函数该如何接收呢,首先,arr是数组名,作为实参进行传递时代表数组的首地址 (这里多提两句吧,数组名只有在两种情况下代表整个数组:(1)sizeof()括号里面单独放置数组名;(2)&数组名。其它情况下都代表数组首元素的地址),所以需要用指针来接收,又因为数组元素的类型是指针类型,要想访问指针数组所指向的内容,需要用二级指针作为子函数的形参来接收。
#include <stdio.h>
void Test(char **p, int n)
{
int i = 0;
for (i = 0; i < n; ++i)
{
printf("%s\n", p[i]); //p[i] 等价于 *(p + i)
}
}
int main()
{
char *arr[4] = { "Hello", "Welcome", "to", "China" };
Test(arr, sizeof(arr)/sizeof(arr[0]));
return 0;
}
2.数组指针的参数传递
下面的代码实现的功能是打印二维数组中的字符串。主函数传递二维数组时,被调函数可通过一个数组指针接收。
#include <stdio.h>
void Test(char (*p)[12], int n)
{
int i = 0;
for (i = 0; i < n; ++i)
{
//通过p[i],访问二维数组的第i行的字符
printf("%s\n", p[i]);
}
}
int main()
{
//定义一个二维数组,此处的12是列数
char str[][12] = { "I", "am", "a", "programmer"};
Test(str, sizeof(str)/sizeof(str[0]));
return 0;
}