【问题标题】:Access a dynamic array with [] operator [duplicate]使用 [] 运算符访问动态数组 [重复]
【发布时间】:2014-11-03 16:33:16
【问题描述】:

让我们考虑以下 C 代码:

char matrix[10][10];
char** array;

array = matrix;
printf("%c", array[2][3]);

我在array = matrix 在线收到警告:assignment from incompatible pointer type
我猜这是因为第一个数组是静态声明的,而第二个数组是动态声明的,但真正的问题在于printf 行。程序只是崩溃了。
我似乎无法使用 [][] 运算符访问 char**
我该如何解决?

注意:我稍微简化了上下文。在原始程序中,array 是通过一个返回类型为char** 的函数分配的,但实际上返回的是一个char[10][10]

【问题讨论】:

  • “我似乎无法使用 [][] 运算符访问 char**。”。你的理论是错误的。你一开始没有char**。你有一个char[10][10],你试图强迫它成为一个char**,你不能,这就是警告告诉你的。
  • 第二个不是“动态声明”,而是将应该是pointer to a pointer 的内容分配给pointer to an array of pointers。此外,如果您想要动态分配多维数组,您将必须指定其所有维度,但第一个维度除外。

标签: c arrays dynamic


【解决方案1】:

char**char[10][10] 不同。与 char[N][N] 的存储方式相比,当我们展示 char** 在内存中的存储方式时,可能最容易解释这个问题。

例如,想象一个 char[3][3] 数组初始化如下:

char matrix[3][3];
int count = 0;
for(int i = 0; i < 3; ++i)
{
    for(int j = 0; j < 3; ++j)
    {
        matrix[i][j] = count++;
    }
}

这将在内存中布置如下:

0 1 2 3 4 5 6 7 8 9

注意,元素在内存中是按顺序排列的,没有指针。

变量matrix 也可以解释为char[3]*,它指向数组中的第一个元素。

取消引用 char[3]* 会返回一个 char[3] 数组,该数组又可以使用另一个 [] 运算符取消引用。所以matrix的元素0可以被认为是数组[0, 1, 2]。我们可以使用另一个 [] 运算符来取消引用该数组的特定元素。

另一方面,char** 在取消引用时返回 char*。访问char** 的特定元素会得到char*。在上面的示例中,访问数组矩阵的元素 0 返回值 0。然后将其视为 char* 并使用另一个 [] 运算符取消引用它将尝试访问内存位置 0 + some 的 char抵消。这几乎肯定会导致段错误。

【讨论】:

  • 哦,好的,我明白了。 This 也有帮助。
【解决方案2】:

char array[10][10] 不会衰减为char**,而是char*。多维数组在内存中是连续的,但 char** 是指向指针的指针,这意味着不能保证每个“行”在内存中彼此相邻。

array[10][10]在内存中是这样的

&array (type char*)
|
| (points to)
|
\/
|---row/array one of length 10 chars---|---row/array two of length 10 chars---|...|---row/array ten of length 10 chars---|

其实和

没什么区别
&array (type char*)
|
| (points to)
|
\/
|---array of length 100 chars---|

所以它或多或少类似于char[100],只是访问方式不同。

另一方面,char** p2p 会像这样工作

p2p (type char **) (points to array of pointers which is contiguous in memory) 
|
| (points to)
|
\/
|---pointer to first row of chars---|---pointer to second row of chars---|...
                 |                                    |
                 | (points to)                        |  (points to)
                 |                                    |
                 \/                                   \/
|****************|--row/array of chars--|*************|-- row/array of chars--|********

其中*** 是未知大小的任意内存位。事实上,根本无法保证最后一组数组是按任何特定顺序排列的,更不用说它们彼此相邻(即最后一组箭头可以相互“交叉”。

【讨论】:

    【解决方案3】:

    如果你想要一个指向你的字符数组的指针,那么你可以创建一个指针并将它指向你需要访问的行,如下所示。

       int main()
        {
        char matrix[10][10];
        char* array;
    
        matrix[2][3] = 'c';
        array= matrix[2];
        printf("%c", array[3]);
        return 0;
        }
    

    【讨论】:

      猜你喜欢
      • 2015-04-11
      • 2018-02-08
      • 2010-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多