char a[10][100] = {"1","2","3","4","5","6","7","8", "9","10"};

编译起在编译的时候是作为char (*)[100]来处理的,即指向数组的指针

char (*c)[100];

和a的类型是一样的,都是指向数组的指针。都有一个确定的维度,也可以认为是指针指向的对象的长度。

在内存中的存放形式

Swift 二维数组 二维数组char_Swift 二维数组

 


c++每次都取下一个数组的首地址



char **d;

这是一个指向指针的指针,

内存中的存放形式

Swift 二维数组 二维数组char_Swift 二维数组_02

 


d++每次都去下一个指针的地址

二维数组和指向指针的指针不能直接强转使用,差别就在于内存中的形式,

Swift 二维数组 二维数组char_Swift 二维数组_03

 


char**认为内存中是连续的指针,char (*)[100]认为内存中是连续的数组,对内存的解释不一样,char**会把char(*)[100]的数组的值解释成地址,而char(*)[100]会把char**的地址解释成值。当然就错误了

char**和char(*)[100]怎么互相转换。

方法1:

char a[10][100] = {0};
char *p[10];
for(int i = 0; i<10; i++)
{
    p[i] = a[i];
}
char **p2 = p;

用一个指向指针的数组保存二维数组的数组的首地址,指向指针的数组与指向指针的指针是同样的类型。

方法2:

char a[10][100] = {0};
char** p1 = (char**)a;
char (*p2)[100] = (char(*)[100])p1;

强转成指向指针的指针,在调用的地方在按照约定强转为指向数组的指针,恢复类型后使用。

方法2不如方法1通用,如果a改变了定义,而p2没有相应的改变会带来隐含的错误。

向函数传递多维数组作为参数的方法:

方法1和方法2通用

方法3:

    传递多维数组作为参数

方法4:

    传递指向数组的指针作为参数,前面说过,指向数组的指针和二维数组是同样的类型。

网友的一段代码

#include "stdafx.h" 
#include <iostream> 
using namespace std; 
int _tmain(int argc, _TCHAR* argv[]) 
{ 
    int arr1[3]; 
    int arr2[3]; 
    int arr3[3]; 
    int * ptr; 
    // ptr1是一个指向 int [3] 的指针,即ptr的类型和&arr1的类型是一样的,注意:arr1指向的内存区域定长 
    int ptr1[3][3]={{1,2,3},{1,2,3},{1,2,3}}; 
    // ptr2是一个指向 int * 的指针,即ptr2的类型和&ptr是一样的,注意:ptr指向的内存区域不定长 
    int * ptr2[3]={arr1,arr2,arr3}; 
    // ptr3是一个指向 int [3] 的指针,即ptr3的类型和&arr1的类型是一样的,注意:arr1指向的内存区域定长 
    int(* ptr3)[3]=&arr1; 
    ptr3=ptr1; // 没错,他们的类型相同 
 // ptr3=ptr2;//error 无法从“int *[3]”转换为“int (*)[3] 
 // ptr4是一个指向 int * 的指针,即ptr4的类型和&ptr是一样的,注意:ptr指向的内存区域不定长 
    int ** ptr4; 
    //ptr4=&arr1; //error 无法从“int (*)[3]”转换为“int ** 
    ptr4=ptr2; // 没错,他们的类型相同 
 //ptr4=ptr3; // error 无法从“int (*)[3]”转换为“int ** 
    return 0; 
}