char [][n]和char (*)[n]

二维数组:

如 char a[3][4] = {"aaa", "bbb", "ccc"};

那么内存中的排布是:


可以看出二维数组的元素仍然是地址连续的,

所以我们

要打印 "aaa" : printf("%s", (char *)a);   // 这里将a强制转换类型:char (*)[4] -> char *  ,当然这里不使用强制转换也行,

                                                            // 因为只需要给printf函数正确的地址就行了。

要打印"bbb": printf("%s", (char *)(a+1)); // 这里 a + 1,注意 a 是 char (*)[4],所以a+1实际上地址偏移 4*sizeof(char)

要打印"ccc" :printf("%s", (char *)(a+2));

当然也可以这样写:

printf("%s", a[0]); //这里 a[n]是一维数组,数组做右值表示数组首元素的首地址,a[n]的首元素是char类型,首地址就是char

                            //类型,所以不需要写成 printf("%s", (char *)a[0]);

printf("%s", a[1]);

printf("%s", a[2]);

说下为什么这个二维数组一般使用 char (*)[4]指向:

char (*p)[4] = a;

首先数组做右值,表示数组首元素的首地址,这里首元素是一个4个元素的一维数组,所以首地址就是以这个一维元素为单位取地址,首元素是char [4]类型,所以指针是 char (*)[4].


与二维数组容易混淆的是指针数组

如 char *[5]

这个指针数组在内存中排布如下:


可以看出 char *[5]的数组元素是指针,指针指向不同的 char *或者char[],

如果:

char *a[5] = {0}, char c = 'c', char str[] = "abc";

char **ap = a;

a[0] = &c;

a[1] = str;

printf("%c", *a[0]);

printf("%s", a[1]);

printf("%c", **(ap+0));

printf("%s", *(ap+1));

说下为什么用 char ** 指向指针数组,

因为指针数组也是数组,数组做右值表示首元素的首地址,这里首元素是char *类型,所以指向他的指针就是 char **类型。

猜你喜欢

转载自blog.csdn.net/blank2019/article/details/79648649
今日推荐