二维数组和二级指针的传递问题

引自:http://www.wutianqi.com/?p=1822

 

借道面试题引出问题,题目:

char **p, a[16][8];  问:p=a是否会导致程序在以后出现问题?为什么?

可能有一部分朋友会回答正确,这里他们认为,a[]是一级指针,a[][]就是二级指针。那这个到底对不对呢?

OK,用事实说话:

 

// Author: Tanky Woo
// Blog:    www.WuTianQi.com
// Note:   验证二维数组与二级指针的传递问题
#include <iostream> 
using namespace std; 
 
void Test(char **p) 
{ 
    cout << p[0][0] << endl; 
} 
 
int main() 
{ 
    char a[2][3]; 
    Test(a); 
    return 0; 
}

 


结果报错:

 

// error C2664: “Test”: 不能将参数 1 从“char [2][3]”转换为“char  **”
//                          与指向的类型无关;转换要求 reinterpret_cast、C  样式转换或函数样式转换

 

于是乎,我看了下《C专家编程》里10.5节—使用指针向函数传递一个多维数组

方法一:

函数是:

1 void fun1(int arr[2][3]);

这种方法导致只能处理2行3列的int型数组。

方法二:

可以省略第一维的长度。

函数是:

void fun2(int arr[][3]);

这种方法的限制略微宽松了一些,但是还是只能处理每行是3个整数长度的数组。

函数也可以写成:

void fun2_2(int (*arrr)[3]);

方法三:

创建一个一维数组,数组中的元素是指向其他东西的指针。也可以说是二级指针。

函数是:

int fun3(int **arr)

注意:只有把二维数组改为一个指向向量的指针数组的前提下才可以这么做!

比如:

#include <iostream> 
using namespace std; 
 
void test(char **ptr) 
{ 
    cout << *ptr << endl; 
} 
 
int main() 
{ 
    char *p[3] = {"abc", "def", "ghi"}; 
    test(p); 
    return 0; 
}

在《C专家编程》10.3节的小启发里讲的很透彻:(以下这段文字及对比一定要认真分析!)

数组和指针参数是如何被编译器修改的?

数组名被改写成一个指针参数”规则并不是递归定义的。数组的数组会被改写成“数组的指针”,而不是“指针的指针”:

实参                                                     所匹配的形参

数组的数组          char c[8][10];                  char (*)[10];          数组指针

指针数组             char *c[10];                     char **c;               指针的指针

数组指针(行指针)  char (*c)[10];                  char (*c)[10];        不改变

指针的指针           char **c;                         char **c;               不改变

 

 

 

我在CSDN上专门为这个问题提问过:

http://topic.csdn.net/u/20101221/12/da817bda-4e88-44df-bdf8-40e8f44aacb8.html?2076366575

最后我总结下讨论结果:

只要实参的类型与形参的类型一致(或可转换)就行。

为什么这么说呢?

piaojun_pj朋友给了一段代码,分析得很给力:

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值