【问题标题】:Why Do I need that extra asterix using 2D array?为什么我需要使用 2D 数组的额外星号?
【发布时间】:2015-05-15 02:54:12
【问题描述】:

我知道如果arr 是一个数组那么arr[i]=*(arr+i);如果是二维数组,那么arr[i][j]=*(*(arr+i)+j);所以我有这个代码

main(){
    int arr[5][5];
    int arr2[25];   // same as arr[5][5];
    int i,j;


    for(i=0;i<5;i++)
        for(j=0;j<5;j++){
            arr[i][j]=i+j;
            printf("arr[%d][%d] is at %p\n",i,j,&arr[i][j]);
        }

    printf("*(arr+i)=%d\n",*(arr+1)); // why this dont work


    for(i=0;i<24;i++){
       arr2[i]=i;
       printf("arr2[%d] is at %p\n",i,(arr2+i));
    }

    printf("*(arr+i)=%d\n",*(arr2+1)); // prints 1 as expected
}

我知道在 C 中没有二维数组之类的东西,它基本上是一个线性行主要连续的内存块。所以我想知道为什么我不能使用 *(arr+1) 打印 2D arr 的值,这意味着将 1*5*4 字节添加到 arr 的基数并取消引用该地址的值。我知道**(arr+1) 有效,但我不知道为什么我需要那个额外的星号?另外,如果我这样做printf("*(arr+i)=%p\n",*(arr+1)); 与我将使用(arr+i) 解释为地址相同

【问题讨论】:

  • 魔法药水多了会怎样?
  • 每一个都有Obelix吗?
  • 这是什么黑魔法?

标签: c arrays pointers memory-management


【解决方案1】:

arrints 的数组。它的类型是int [5][5]。所以,arr 的元素是一维数组。在表达式中使用时,在大多数情况下,数组转换为指向其第一个元素的指针。在*(arr + 1) 中,arr 被转换为指向arr[0] 的指针,即第一个一维数组。添加1 将增加5*4 = 20 字节,即数组arr 的下一个元素arr[1]

由于arr[1]是一个数组,所以不能(作为一个整体)打印,但是它的地址可以。 arr[1] 本身是一个数组,它将衰减为指向其第一个元素的指针,即 arr[1][0]。要打印它的元素,您需要另一个由arr[1][j] 实现的取消引用(j 是列)。

arr[1][j] 等价于 *(arr[1] + j) 最终等价于 *(*(arr + 1) + j)

推荐阅读:What exactly is the array name in c?

【讨论】:

  • 所以基本上arr[5][5]arr[25] 相同,只是在表达式arr[0],arr[1],arr[2],arr[3]arr[4] 中使用int* 类型?
  • @BsD;你可以说。但是,有时内存管理在包含相同数量元素的 1D 和 2D 数组中有所不同。
【解决方案2】:

正如您所说,C 中的二维数组基本上是一维数组的数组。你可能会认为这是一个行数组。

最右边的* 将取消引用外部数组,选择您想要的行。

*(arr+i)      //this gives me a pointer to the row I want

左侧的* 将在内部数组中取消引用,从行中选择一个元素。

*(*(arr+i)+j) //this gives me an element in the row

**(arr+i) 只是上述列号j0 的特例。

【讨论】:

    【解决方案3】:

    *(arr+1)的类型=arr[1]的类型=int [5],在printf使用时会衰减为int*

    要打印指针,请使用:

    printf("*(arr+i)=%p\n", *(arr+1));
    

    要打印它指向的对象,请使用:

    printf("*(*(arr+i))=%d\n", *(*(arr+1)));
    

    您可以使用以下方法使您的代码更易于阅读:

    printf("arr[1] = %p\n", arr[1]);       // Print the pointer
    printf("arr[1][0] = %d\n", arr[1][0]); // Print the value
    

    【讨论】:

    • arr[1] 的类型是 int [5]
    • 如果你写arr[1]arr[1][0],这一切都会更清楚
    猜你喜欢
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 2015-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多