多维数组,表示网格地址的不同方式[22] [0]

时间:2018-03-07 00:16:36

标签: c arrays pointers multidimensional-array

我目前正在研究c编程语言的多维数组和指针。

我被问到以下问题

  

假设您有以下声明:

     

int grid[30][100];.

     

以两种方式表示网格[22] [0]的地址。

作者提供了以下答案

&grid[22][0] or grid[22]

我想出了

//notice for the second answer, I placed an address operator & at the front 
&grid[22][0] or &grid[22] 

我测试了以下代码

#include <stdio.h>

int main(void){

    int ar[2][3] = {
            {11, 22, 33},
            {44, 55, 66}
    };

    printf("%p\n", &ar[2][0]);
    printf("%p\n", ar[2]);
    printf("%p\n", &ar[2]);

    return 0;
}

并且所有三个表单都打印了相同的值

0062ff30
0062ff30
0062ff30

作者的答案grid[22]和答案&grid[22]是否相同?它们怎么可能相同?

1 个答案:

答案 0 :(得分:1)

首先,如果您使用%p,则必须将值转换为(void*), 因为%p期望a期望一个无效指针

printf("%p\n", (void*) &ar[2][0]);
printf("%p\n", (void*) ar[2]);
printf("%p\n", (void*) &ar[2]);

他们都有相同的地址(因为他们都在同一个地方 记忆)但他们的表达方式有不同的类型:

&ar[2][0];

int*(指向int

的指针
ar[2];

int[3](维度3的int数组),但在printf它衰变成 一个int*然后由于演员而变为void*

&ar[2];

int (*)[3](指向int[3]的指针,int维度2的数组。

当您使用int[3]数组时,您可以看到sizeof是一个数组 不会腐烂成指针:

printf("sizeof &ar[2][0]: %zu\n", sizeof &ar[2][0]);
printf("sizeof ar[2]:     %zu\n", sizeof ar[2]);
printf("sizeof &ar[2]:    %zu\n", sizeof &ar[2]);

打印(在我的系统上,x86_64):

sizeof &ar[2][0]: 8         (size of an pointer)
sizeof ar[2]:     12        (size of an array `int[3]`)
sizeof &ar[2]:    8         (size of a pointer)

如果你有这个功能

void foo(int *x)
{
    (void) x; // to silence -Wall warnings
}

然后foo(&ar[2][0])很好,foo(ar[2])也很好,因为它会衰减 成指针。但是foo(&ar[2])并不好,你会得到:

a.c: In function ‘main’:
a.c:21:6: warning: passing argument 1 of ‘foo’ from incompatible pointer type [-Wincompatible-pointer-types]
  foo(&ar[2]);
      ^
a.c:3:6: note: expected ‘int *’ but argument is of type ‘int (*)[3]’
 void foo(int *x)
      ^~~

然而

void bar(int (*x)[3])
{
    (void) x;
}

bar(&ar[2])没问题。

请记住,如果你用任何一个打印值/访问内存 这些表达式,您将访问超出范围的数据。 ar应该是

int ar[3][3] = {
    {11, 22, 33},
    {44, 55, 66},
    {77, 88, 99}
};