【问题标题】:How does ** work in a 2 dimensional array?** 如何在二维数组中工作?
【发布时间】:2017-10-07 10:43:24
【问题描述】:
int main(void) {
    unsigned int x[4][3] = {(1,2,3),(4,5,6),(7,8,9),(17,11,12)};
    printf("%d, %u, %u, %u \n",**x, **(x+1), **(x+2), **(x+3));
    return 0;
}

上面代码的输出是 3, 12, 0, 0。 不应该是 1,4,7,17​​,因为 x 存储了数组的第一个元素的地址吗?

当我尝试打印时

printf("%u, %u \n", x, &x[0][0] );

显示相同的地址 2108666688, 2108666688

但是当我尝试使用

打印数组时
for(int i = 0; i<4; ++i)
{
    for(int j = 0; j<3 ; ++j)
    {
        printf("%d ",x[i][j]);
    }
    printf("\n");
}

我看到输出为

3 6 9 
12 0 0 
0 0 0 
0 0 0 

那么,这里到底发生了什么?为什么数字没有正确分配给数组?

【问题讨论】:

  • {(1,2,3),(4,5,6),(7,8,9),(17,11,12)} 未达到您的预期。认真对待编译器的警告。
  • 是的,新代码总是使用“-Wall”

标签: c pointers multidimensional-array


【解决方案1】:
unsigned int x[4][3] = {(1,2,3),(4,5,6),(7,8,9),(17,11,12)};

在功能上等同于:

unsigned int x[4][3] = {3, 6, 9, 12};

因为comma operator 在这里工作!逗号运算符计算其所有操作数并产生其最后一个操作数的结果。

所以你看到的输出是预期的。您可能的意思是:

unsigned int x[4][3] = {{1,2,3},{4,5,6},{7,8,9},{17,11,12}};

【讨论】:

  • 如答案中所述,它返回所有操作数的最后一个数字,即 (2,3,7,4) 返回 4
【解决方案2】:

请记住,数组自然会衰减为指向其第一个元素的指针。这意味着在您的情况下,x 本身与 &amp;x[0] 相同。

因为x 是一个数组数组,所以&amp;x[0] 的类型是一个指向数组的指针,在本例中为unsigned int (*)[3]。取消引用此指针是一个数组(int [3] 类型),而该数组又可以衰减为指向其第一个元素的指针。

双重解引用的作用只是解引用两个指针,从而产生第一个数组的第一个元素,即x[0][0]

这恰好是 3 而不是 1 是因为您使用 (1, 2, 3) 初始化元素,而 (1, 2, 3) 使用 逗号表达式 导致 3

您可能想要对“内部”数组也使用花括号:

unsigned int x[4][3] = {{1,2,3},{4,5,6},{7,8,9},{17,11,12}};

现在**x 将改为1

要记住的另一件事是,对于任何数组或指针x 和索引i,表达式x[i] 等于*(x + i)

【讨论】:

    【解决方案3】:

    由于我认为此声明存在拼写错误(使用括号而不是大括号)

    unsigned int x[4][3] = {(1,2,3),(4,5,6),(7,8,9),(17,11,12)};
    

    等价于

    unsigned int x[4][3] = { 3, 6, 9, 12 };
    

    数组的所有其他元素都初始化为零。

    因此,数组看起来是通过以下方式显式初始化的

    unsigned int x[4][3] = { { 3, 6, 9 }, { 12, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } };
    

    比如这个表达式

    (1,2,3)
    

    是一个带有逗号运算符的表达式,它产生最后一个操作数的值。

    来自 C 标准(6.5.17 逗号运算符)

    2 逗号运算符的左操作数被评估为 void 表达;在它的评估和那个之间有一个序列点 的右操作数。 然后对右操作数求值;这 结果有它的类型和价值

    举个例子

    unsigned int x = ( 1, 2, 3 );
    printf( "x = %u\n", x );
    

    要获得预期的结果,您必须用大括号替换括号。例如

    unsigned int x[4][3] = { {1,2,3}, {4,5,6}, {7,8,9}, {17,11,12} };
    

    【讨论】:

      猜你喜欢
      • 2021-11-14
      • 2022-08-02
      • 2021-07-06
      • 2012-02-05
      • 2014-12-05
      • 2015-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多