三次打印地址后尊重两次?

时间:2014-09-23 16:55:35

标签: c pointers multidimensional-array

为什么在解除引用两次后3D阵列打印地址?请帮我理解下面发布的代码,(假设数组从位置1002开始)。

int main()
{
   int a[2][3][4]={
                   {
                     1,2,3,4,
                     4,5,6,7,
                     9,1,1,2
                   },
                   {
                     2,1,4,7,
                     6,7,8,9,
                     0,0,0,0
                   }
                 };

   printf("%u %u %u %u\n",a,*a,**a,***a); //a == *a == **a, all print address 1002. Why? 

}

3 个答案:

答案 0 :(得分:1)

a的类型为array of size 2 of arrays of size 3 of arrays of size 4 of int *a的类型为array of size 3 of arrays of size 4 of int **a的类型为array of size 4 of int

当衰减到相应的指针时,所有三个数组都具有相同的值,因为它们指向内存中的相同位置。

答案 1 :(得分:1)

**a的类型为int *,并指向3D数组中的第一个int *a的类型为int (*)[4],并指向3D数组的第一行 a的类型为int (*)[3][4],并指向3D数组中的第一个2D数组 &a的类型为int (*)[2][3][4],并指向整个3D数组

所以它们都是指向同一地址的指针。只是指针的类型是不同的。以下代码可能有助于说明这一点。

int main( void )
{
    int a[2][3][4]={ 1,2,3,4, 4,5,6,7, 9,1,1,2,    2,1,4,7, 6,7,8,9, 0,0,0,0 };

    int *ptrInt;                // pointer to an int
    int (*ptrArray1)[4];        // pointer to an array of ints
    int (*ptrArray2)[3][4];     // pointer to a 2D array of ints
    int (*ptrArray3)[2][3][4];  // pointer to a 3D array of ints

    ptrInt    = **a;
    ptrArray1 = *a;
    ptrArray2 = a;
    ptrArray3 = &a;

    printf( "%p %p\n", ptrInt   , ptrInt    + 1 );
    printf( "%p %p\n", ptrArray1, ptrArray1 + 1 );
    printf( "%p %p\n", ptrArray2, ptrArray2 + 1 );
    printf( "%p %p\n", ptrArray3, ptrArray3 + 1 );
}

注意:我特别省略了数组初始化中的内括号,以证明内括号是可选的。最佳实践将拥有所有内部支撑。

此代码的典型输出如下所示。我添加了注释,以显示两个指针之间的差异为十进制数。

0x17b00 0x17b04  //  4 bytes, hence pointer to an int
0x17b00 0x17b10  // 16 bytes, pointer to int[4]
0x17b00 0x17b30  // 48 bytes, pointer to int[3][4]
0x17b00 0x17b60  // 96 bytes, pointer to int[2][3][4]

请注意,向任何指针添加1时,对象的大小将添加到指针中。例如,如果您有int *并且向该指针添加1,则指针的值将增加4,因为sizeof(int) == 4(是的,假设整数是32位,谢谢。)

因此,通过向指针添加1,可以确定指针指向的对象的大小。从编译器的角度来看,这可以为您提供有关指针类型的线索。在上面的示例中,请注意向ptrArray1添加1会将指针更改为16.因为ptrArray1指向大小为16的对象,特别是指向4个整数的数组。


为了让我们完全混淆,请允许我说下面一行代码会打印数字8。我选择了8,因为它只在阵列中出现一次,所以你可以知道它来自哪里。

    printf( "%d\n", ptrArray3[0][1][1][2]);

请注意,我似乎使用ptrArray3作为4维数组。这就是为什么多维数组的指针在C中如此混乱的原因。当您将数组转换为指针时,指针的维数比数组少一个。但是当您使用带有数组语法的指针时,您可以使用它,就好像它还有一个维度一样。

例如,从2D数组开始

int array[4][100];

相应的指针是指向1D数组的指针

int (*ptr)[100] = array;

但你可以像2D数组那样使用指针

ptr[2][100] = 6;

这是所有混淆的基础,以及指针到数组在C中很少使用的原因。

答案 2 :(得分:-1)

请尝试以下代码:

int main()
{
    int a[2][3][4]={
            {
                {1,2,3,4},
                {4,5,6,7},
                {9,1,1,2}
            },
            {
                {2,1,4,7},
                {6,7,8,9},
                {0,0,0,0}
            }
            };

    printf("%u %u %u u%",a,*a,**a,***a);//how a == *a == **a print address 1002 please help me to understand ? 

}

它返回地址的原因是因为你根本没有正确地声明你的3d数组。以上是更正后的代码,试一试,让我们知道它是怎么回事