二维数组的传递

来源:互联网 发布:2018年四川省大数据 编辑:程序博客网 时间:2024/05/16 19:18

问题描述:于习题中碰到关于数组传递的问题,不熟悉相关。引发运行错误

//二维数组传递的几种方式(1) void function(char a[][20])  //数组名传递   {   }(2) void function(char *p[])  // 指针数组传递   {   }(3) void function(char (*p)[20])  //数组指针传递   {   }   #include void function(char a[][10]){           for(int i = 0 ;i < 4; i++)       {              printf(" %s /n", a[i]);              printf(" %c /n", a[i][2]); // 每行输出最后一个元素       }       printf(" %s /n", a[i]);  //越界访问} void function2(char *p[]){       for(int i = 0; i < 4; i++)       {              printf(" %s /n", *p++);              printf(" %c /n", *(*p +2));  // 每行输出最后一个元素       }       printf(" %s /n", *p++);  //越界访问} void function3(char (*p)[10]){           for(int i = 0; i < 4; i++)       {              printf(" %s /n", *p++);              printf(" %c /n", *(*p +2));  // 每行输出最后一个元素       }        printf(" %s /n", *p);  //越界访问} void main(){                 printf("test for parameters/n");        char a[][10] = {"sat", "sun", "mon", "tue"} ;       char *p[] = {*a, *(a+1), *(a+2), *(a+3)} ;             //a[][10]       printf("============a[][10]==========/n ");       function(a);             //*p[]       printf("==========*p[]============/n ");       function2(p);        //(*p)[10]       printf("==========(*p)[10]============/n ");       function3(a);      }

分析:
   去调越界访问语句后, 三种方式输出都是一样 完全正常,
从本质意义上来将*p[] 和 (*p)[10] 其实应该是一样的。*p[]比较麻烦,因为还要把各行的地址初始化给它。
*p[] 指针的数组 每个元素指向数组的指针,经过初始化后 存放的是二维数组中行的地址。P++后指向都是下一行的地址;
(*p)[10] 数组的指针 p指向一个含有十个元素的数组 ,因为指向了a的第一行 所以p++按照指针变量的运算,(指向下一个变量的地址),也就是指向了下一行的地址(这里的变量就成了a的一行)。如果说a只有一行,那么p++肯定是要越界了
       关于越界:
  char a[][10] 和 (*p)[10] 中因为传递的都是数组的指针, 该数组存储空间位于栈上,所以当地址越界 p++后 指向的是栈中的莫名元素,故输出乱码,程序却不会崩溃。而且二者的输出内容也是完全一致的。
  同时*p[] 中被初始化为各行的首地址, p++越界后,指针变量p 也是位于栈上,关键是还有一个运算*p ,(p越界后其内容是随机的 *p之后指向随机的内存 而不是像(*p)[10]那样还是指在栈空间), 故程序输出崩溃。
 
再进一步 数组寻址跟指针寻址本质上还是一样的。2 和3 函数其实都是可以写成数组方式的形式的:  *(*(p + i ) + j ) 访问数组中a[i][j]元素。
 
三者的共同不方便处,函数内部都无法知道数组维数大小(指针传递的不方便处)。可以增加想关的维数变量来解决这个问题。