数组指针与指针数组
1. 数组指针
下面部分程序的目的是想通过函数打印二维数组元素,
#include <stdio.h>
int array[3][4] = {{1, 2, 3, 4},{5, 6, 7 ,8},{9, 10, 11, 12}};
int print_array(int **p, int m, int n)
{
inti, j;
for(i= 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
printf("%d ",*(*(p+ i)+ j));
}
}
printf("\n");
return 0;
}
在main程序中这样调用 printf_array函数
print_array(array, 3, 4)
函数在执行的时候出现如下错误:
Segmentation fault (core dumped)
为什么出现段错误呢?
因为在上面的程序中,p + i 代表指针偏移( i * 4)个字节数据宽度,而array + i代表指针偏移i 行,每行4 * 4个字节的数据宽度,也就是 i * 4 * 4个字节数据宽度,所以并不能用 *(*(p+ i) + j)) 代表array[i][j]。
注:因为p是一个二级指针是一个指向数据类型为 指针 的指针,指针 宽度都是4个字节,所以p + i代表偏移( i *4)个字节数据宽度。
如果一个函数的参数是一个二维数组,那如何传参呢?这就需要用到数组指针
在上面的程序中,p可以这样定义
int (*p)[m];//这里m为4,注意别丢掉括号,否则属于另一种数据类型
这样定义的p称为数组指针,它的本质是一个指针,这个指针指向一个二维数组名代表的首地址,而且这个二维数组具有的属性是每行数组有m个元素。为什么需要这样定义呢?因为只有这样定义,编译器才知道在编译p + i时p指针每行要偏移多少个数据元素。
p = array;
p+ 0 代表 array[0]的地址
p+ 1 代表 array[1]的地址
p+ 2 代表 array[2]的地址
这样 *(*(p+ i) + j)) 就等价于 array[i][j]
2. 指针数组
在上面int (*p)[4];代表数组指针,那p丢掉括号int *p[4];就代表指针数组
为什么p带了括号就是数组指针,丢掉括号就是指针数组呢?
因为在 (*p)[]中,p先和*结合,所以p的本质就是一个指针
在 *p[] 中,[]的优先级高于*,所以p先和[]结合,所以p的本质就是一个数组
在指针数组中,数组中每个元素都是指针。
示例:
#include <stdio.h>
int main(int argc, const char *argv[])
{
charstr1[] = {"Hello"};
charstr2[] = {"world"};
charstr3[] = {"nice"};
charstr4[] = {"to"};
charstr5[] = {"meet"};
charstr6[] = {"you!"};
char*str[6] = {'\0'};
str[0]= str1;
str[1]= str2;
str[2]= str3;
str[3]= str4;
str[4]= str5;
str[5]= str6;
robot_say(str,6);
return0;
}
int robot_say(char *word[], int n)
{
inti;
for(i= 0; i < n; i++)
{
printf("%s",word[i]);
}
printf("\n");
return0;
}