C 指针无法读取数组中的正确元素

C 指针无法读取数组中的正确元素,c,pointers,C,Pointers,我有一个C语言的指针,我不知道它是如何工作的。 代码如下: // ptr points to an array of 2 ints int (*ptr)[2]; int torf[2][2] = {12, 14, 16}; ptr = torf; int (*ptr_2)[2]; int torf_2[2][2] = { {12}, {14, 16}}; ptr_2 = torf_2; printf("%d %d\n", **ptr, **(ptr + 2)); pr

我有一个C语言的指针,我不知道它是如何工作的。 代码如下:

// ptr points to an array of 2 ints
int (*ptr)[2];
int torf[2][2] = {12, 14, 16};
ptr = torf;

int (*ptr_2)[2];
int torf_2[2][2] = { {12}, {14, 16}};
ptr_2 = torf_2;
  
printf("%d %d\n", **ptr, **(ptr + 2));
printf("%d %d\n", **ptr_2, **(ptr_2 + 2));
我想要的答案应该是:

12 16
12 14
但实际上我在我的电脑上:

12 6422000
12 12
有什么想法吗?

试试这个:

// ptr points to an array of 2 ints
int(*ptr)[2];
int torf[2][2] = { 12, 14, 16 };
ptr = torf;

int(*ptr_2)[2];
int torf_2[2][2] = { {12}, {14, 16} };
ptr_2 = torf_2;

printf("%d %d\n", **ptr, **(ptr + 1));
printf("%d %d\n", **ptr_2, **(ptr_2+1));
当您使用指针时,它就像数组的索引一样,从0开始

干得好

试试这个:

// ptr points to an array of 2 ints
int(*ptr)[2];
int torf[2][2] = { 12, 14, 16 };
ptr = torf;

int(*ptr_2)[2];
int torf_2[2][2] = { {12}, {14, 16} };
ptr_2 = torf_2;

printf("%d %d\n", **ptr, **(ptr + 1));
printf("%d %d\n", **ptr_2, **(ptr_2+1));
当您使用指针时,它就像数组的索引一样,从0开始


很好

如果在程序末尾添加以下行:

printf("%p: %p %p\n", ptr, ptr+1, ptr+2);
printf("%p: %p %p\n", *ptr, *ptr+1, *ptr+2);
printf("%p: %p %p\n", **ptr, **ptr+1, **ptr+2);
您将注意到,在第一种情况下,数字增加8,可能是指针大小,也可能是两个整数。第二个也一样,但是第三个增加了int的大小;所以这很好

所以,为了消除2个整数或1个地址的歧义,让我们做一个s/2/3/g。 现在,我们看到第一种情况,增量现在是12(=3*4)。 第二种情况(*ptr+i)增加4,后续整数的地址也增加4 第三种情况是整数值本身

哪里弄糊涂了?快速检查表:

  • 当您试图解决指针/索引问题时,请尽可能使用唯一值

  • 当编译器警告您时,请注意。最终您将知道忽略“格式“%p”需要参数…”,但建立信心需要时间

  • 有一个方便的程序cdecl,它可以将C类型的表达式转换成类似英语的东西

  • 在几乎所有的C实现中,
    intx[2][2],y[4]具有相同的布局;也就是说,C多维数组只是一维数组的叠加,算术运算被巧妙地隐藏起来。因此,定义如
    int(*p)[2]很少使用,也很少有用。
    如果你必须沿着这条路走下去,那么最好采取以下措施:

    typedef int对[2]; 对torf[2]={{0,1},{2,3}; 对*ptr=torf


  • 如果没有其他内容,则有人有机会理解它…

    如果您在程序末尾添加以下行:

    printf("%p: %p %p\n", ptr, ptr+1, ptr+2);
    printf("%p: %p %p\n", *ptr, *ptr+1, *ptr+2);
    printf("%p: %p %p\n", **ptr, **ptr+1, **ptr+2);
    
    您将注意到,在第一种情况下,数字增加8,可能是指针大小,也可能是两个整数。第二个也一样,但是第三个增加了int的大小;所以这很好

    所以,为了消除2个整数或1个地址的歧义,让我们做一个s/2/3/g。 现在,我们看到第一种情况,增量现在是12(=3*4)。 第二种情况(*ptr+i)增加4,后续整数的地址也增加4 第三种情况是整数值本身

    哪里弄糊涂了?快速检查表:

  • 当您试图解决指针/索引问题时,请尽可能使用唯一值

  • 当编译器警告您时,请注意。最终您将知道忽略“格式“%p”需要参数…”,但建立信心需要时间

  • 有一个方便的程序cdecl,它可以将C类型的表达式转换成类似英语的东西

  • 在几乎所有的C实现中,
    intx[2][2],y[4]具有相同的布局;也就是说,C多维数组只是一维数组的叠加,算术运算被巧妙地隐藏起来。因此,定义如
    int(*p)[2]很少使用,也很少有用。
    如果你必须沿着这条路走下去,那么最好采取以下措施:

    typedef int对[2]; 对torf[2]={{0,1},{2,3}; 对*ptr=torf


  • 如果没有其他内容,则有人有机会理解它…

    编译器应该会发出几个相关警告。如果编译器没有给您任何警告,您应该查看如何打开它们。请记住,对于任何指针或数组
    ptr
    和索引
    i
    ,表达式
    *(ptr+i)
    等于
    ptr[i]
    。这意味着代码中的
    **(ptr+2)
    等于
    *ptr[2]
    ,这是不允许的。问题是
    **(ptr+2)
    -谁知道这是什么意思。只需将括号符号与指针一起使用即可。这表示
    *ptr[2]
    ,这更容易理解。编译器中应该有几个相关的警告。如果编译器没有给您任何警告,您应该查看如何打开它们。请记住,对于任何指针或数组
    ptr
    和索引
    i
    ,表达式
    *(ptr+i)
    等于
    ptr[i]
    。这意味着代码中的
    **(ptr+2)
    等于
    *ptr[2]
    ,这是不允许的。问题是
    **(ptr+2)
    -谁知道这是什么意思。只需将括号符号与指针一起使用即可。这表示
    *ptr[2]
    ,更容易理解。