2D char Array 和 char** 之间的区别(OR、3D char Array 和 char*** 等)

Posted

技术标签:

【中文标题】2D char Array 和 char** 之间的区别(OR、3D char Array 和 char*** 等)【英文标题】:Difference between 2D char Array and char** (OR, 3D char Array and char*** etc) 【发布时间】:2014-05-10 12:59:46 【问题描述】:

首先,我已经回顾了这些:

How are multi-dimensional arrays formatted in memory?

Memory map for a 2D array in C

由此可知,二维数组与 char** 不同,但在内存中它们看起来完全相同。这听起来很奇怪,所以我研究了以下内容:

#include <stdio.h>

char func(char** m) 
    return m[0][0]; //only works for char**, already discussed in the other SO question


int main() 

    //char a[4][2]; //a 2D char array

    int row = 4, col = 2;   //char**
    char** a = malloc(row * sizeof(char*));
    int i;
    for (i = 0; i < row; i++) 
        a[i] = malloc(col * sizeof(char));
    

    //checking the output
    printf("      &a = %u\n", &a);
    printf("   &a[0] = %u\n", &a[0]);
    printf("&a[0][0] = %u\n", &a[0][0]);
    printf("       a = %u\n", a);
    printf("    a[0] = %u\n", a[0]);

    //printf(" a[0][0] = %u\n", a[0][0]);   //char value in a[0][0], here a garbage value

    //char m = func(a); //only works for char**, already discussed in the other SO question

    return 0;

char** 的可能输出:

      &a = 3209288  //                  &a
   &a[0] = 4083720  // &(*(a+0))      =  a
&a[0][0] = 4083784  // &(*(*(a+0)+0)) = *a
       a = 4083720  //                   a
    a[0] = 4083784  // *(a+0)         = *a

二维字符数组的可能输出:

      &a = 3473104  // &a
   &a[0] = 3473104  //  a
&a[0][0] = 3473104  // *a
       a = 3473104  //  a
    a[0] = 3473104  // *a

char**的输出很容易理解。但是 2D char 数组的输出看起来很奇怪,尽管它在另一个 SO 问题中讨论过。我想不出任何数据类型的指针 x

x = &x = *x

所有 3 个东西都物理上驻留在同一个内存块中。希望我的困惑是可以理解的。谁能解释其中的奥秘?

【问题讨论】:

从那里得知,2D 数组与 char** 不同,但在内存中它们看起来完全一样。事实并非如此 @self:我刚刚从提到的其他 SO 问题中引用了该声明。我很困惑。 我找不到那句话,你能指出来吗? @self:不完全是引用,而是类似的东西。 【参考方案1】:

当您使用数组的名称是除&amp;arraysizeof array 之外的任何表达式时,此名称将自动转换为指向数组第一个元素的指针(char [5][10] 将转换为char (*)[10])。该指针的地址将等于整个数组的地址。 所以,“sizeof(char [5][10]) == 50”,没有额外的指针。

char arr[5][10];

&a = 3473104 // Address of entire array, (char (*)[5][10])
&a[0] = 3473104 // Address of first row, (char (*)[10])
&a[0][0] = 3473104 // Address of first char, (char *)
a = 3473104 // "a", (char [5][10]), converted to "&a[0]", (char (*)[10])
a[0] = 3473104 // "a[0]", (char[10]), converted ro "&a[0][0]", (char *)

【讨论】:

很好的答案,虽然没有我预期的那么清楚。阅读了几篇文章,我意识到数组不是指针,反之亦然。该语言的某些特征似乎使我认为它们是等价的。实际上不是。

以上是关于2D char Array 和 char** 之间的区别(OR、3D char Array 和 char*** 等)的主要内容,如果未能解决你的问题,请参考以下文章

将 char 2d 数组转换为 2d char 数组列表时出现问题

如何检查 char 数组中的空格?

Swig:char / char* 上的数组和警告

打印 char 2D 数组时初始化程序太多

DELPHI中byte类型和char类型区别?

WordPress:在两个菜单项之间插入char