C高级之指针(一)

数组指针与指针数组

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;

}


猜你喜欢

转载自blog.csdn.net/weixin_42048417/article/details/80171796
今日推荐