关于C语言中指针功能的混乱

时间:2014-01-25 14:33:48

标签: c pointers

我编写了一个程序来测试指针操作,但我没有得到输出背后的逻辑。

好像我使用arr+1而不是第二个位置我得到第7个,*arr+1的情况类似,我觉得奇怪的是*表达式显示的地址不是值。

任何人都可以解析输出,请!

计划是:

#include<stdio.h>
int main()
{
    static int arr[2][3][2] = {1,2,3,4,5,6,7,8,9,10,11,12};
        int i,j,k;
        printf("%d\t",arr);
        printf("%d\t",*arr);
        printf("%d\n",**arr);
        printf("%d\n",***arr);
        printf("%d\t",arr+1);
        printf("%d\t",*arr+1);
        printf("%d\n",**arr+1);
        printf("%d\n",***arr+1);
        for(i=0;i<2;i++)
        {
            for(j=0;j<3;j++)
            {
            for(k=0;k<2;k++)
                printf("%d      %u \n",*(*(*(arr+i)+j)+k),&arr[i][j][k]);
                printf("\n");
            }
        printf("\n");
        }
return 0;
}

而OUTPUT是:

4202512 4202512 4202512
1
4202536 4202520 4202516
2
1      4202512
2      4202516

3      4202520
4      4202524

5      4202528
6      4202532

7      4202536
8      4202540

9      4202544
10      4202548

11      4202552
12      4202556

2 个答案:

答案 0 :(得分:2)

你声明了一个int [2][3][2]数组,这意味着:

  • 表达式arr的类型是int [2][3][2]数组,因此您只能从该类型获取指针。
  • 表达式arr[0]的类型,或*arrint [3][2]数组,因此您只能从该类型获取指针。
  • 表达式arr[0][0]的类型,或**arrint [2]数组,因此您只能从该类型获取指针。
  • 表达式arr[0][0][0]的类型或***arrint,因此您只能从该类型中获取int值。

这个过程的变化会产生类似的结果。

你总是得到一个相同的基址,因为多维数组在内存中是平的,而维度大小则用于分区那个平坦的内存。

int [2][2]就像:

0, 1
2, 3

数字类似于内存中元素的顺序,而二维显示类似于数组的行/列访问。

答案 1 :(得分:1)

您的前3张照片显示的地址相同但含义不同(和类型) -

  1. arr是整个3d数组的地址,类型为int***(您将指针强制转换为int,这不是一个好习惯,因为在某些系统上它可能更大)
  2. *arrint**类型的“扁平”二维数组的地址,实际位于arr[0]
  3. **arrint*类型的两次“扁平”1d数组的地址,实际位于arr[0][0]
  4. 只有***arr最终会带您到实际的int值arr[0][0][0]
  5. 现在启动指针算术,这取决于所提到的指针类型和每个维度的大小(编译器已知)。所以:

    1. arr+1为您提供arr[1]的地址,该地址已从arr[0]中移除2 * 3个int元素的长度(此处6 * 4 = 24)
    2. *arr+1为您提供地址arr[0][1],该地址已从arr[0][0]中移除2个int元素的长度(此处2 * 4 = 8)
    3. **arr+1为您提供arr[0][0][1]的地址,该地址从arr[0][0][0]中移除一个int元素的长度(此处为4)
    4. ***arr+1为您提供了arr[0][0][1],这只是2
    5. 另请参阅此答案 - How are 3D arrays stored in C?