【问题标题】:Printing pointer to pointer [closed]将指针打印到指针[关闭]
【发布时间】:2013-07-09 05:54:55
【问题描述】:

当我想打印 2 时它打印 3。我不明白我只增加一次的原因。还让我知道这是否正确使用指针 t 指针?我只是做了一个示例代码来看看指针是如何工作的。

#include<stdio.h>
void main(){
int a1[] = {1,2,3,4,5,6};
int a2[] = {7,8,9,10,11,12};
int *a3 = a1;
int *a4 = a2;
int **a[2];
a[0] = a3;
a[1] = a4;

printf("%d",*(++(*a)));



}

【问题讨论】:

  • 你不应该在函数参数中做增量。
  • 对第二个问题的简短回答:否。更彻底的回答:他||不!这太疯狂了。
  • 我不会停止,直到它的有效代码:stackoverflow.com/questions/17540026/…
  • @Bhaskar void main 不是标准的,您应该使用 int main 代替。此外,此代码不会为我编译。但是,如果我将 int **a[2]; 更改为 int *a[2] 我会得到 2 的预期打印(而不是您的问题所暗示的 3。
  • 好问题是有效的..但他似乎没有显示他的完整代码..:)

标签: c pointers


【解决方案1】:

您将 a 声明为 int** 的数组,因此 *a 不是指向 int 的指针,而是指向指向 int 的指针。增加一个指针会增加它指向的数据类型的大小,所以++*aa[0] 处的值增加一个指针的大小。

您实际存储在a[0] 中的是指向int 的指针,而不是指向int 的指针。这是错误的,编译器应该警告你这一点。在您的体系结构中,指针似乎是 int 大小的两倍,因此增量 ++*a 将两个 int 的大小添加到指针中,因此如果将 a[0] 处的值解释为 int* 而不是 @ 987654328@,跳过2。

要获得您期望的结果,请将 a 声明为 int * 的数组。

int *a[2];

【讨论】:

  • 我很高兴我不是这里唯一一个做对的人。这里的“答案”和 cmets 是我在 SO 看到的最糟糕的盲人引导盲人案例之一。
  • 是否将 a[0] 和 a[1] 分配给指向 int 的指针的指针解决了目的?它是否正确? a[0] = &a3; a[1] = &a4;
  • @JimBalter - 既然你主张 Joni 是对的,那么你能解释一下我上面的评论吗?
  • @Bhaskar a[0] 将有指向指针的指针。所以 a[0]=&a3(其中 a3 是指针)是完全正确的。
  • 但它没有正确打印值!
【解决方案2】:
a[0] = &a3;
a[1] = &a4;

printf("%d",*(++(**a)));

根据定义,a 应该包含指向 int 指针的指针。所以需要在a3和a4前面加上&。在 printf 中,出于相同的原因需要在递增之前使用两次取消引用。

【讨论】:

    【解决方案3】:
    • *a = *(a + 0) = a[0] 包含地址 = a3int*(在您的代码中 a[0] = a3;)。

    • a3 指向a1 的第一个元素(在您的代码int *a3 = a1; 中,就是一个)因此*a 指向a1 的第一个元素。

    • 通过执行++(*a),您将指向a1 中位于索引1 的下一个元素,最后通过在++(*a) 处使用*,您正在打印1 在@987654339 中的索引值@ 输出的数组:2 那就是a1[1]

    所以,*(++(*a)) 实际上是 a1[1]

    您的代码打印 2 不是 3,请在此处查看您的工作代码 codepade

    【讨论】:

    • 但我不知道为什么我的 gcc 正在打印 3。
    • 你确定你的问题中的代码就是你正在编译的代码吗?
    • *a 不是整数。它是指向整数的指针,因此增量将是指针大小而不是整数大小。值“3”看起来正确
    • @Bhaskar google 一下,很简单:)
    • @Bhaskar gcc -Wall -pedantic Codename.c -o outexename
    【解决方案4】:

    您显然正在使用具有 64 位指针和 32 位整数的编译器。因为您错误地声明了a,所以当您增加*a 时,您将增加指针的大小——64 位,即8 字节——而不是int 的大小——32 位,即4字节——如此有效地增加了两个整数的大小。

    a的声明改为

    int* a[2];
    

    并且您的程序将正常运行。此外,使用 -Wall 编译(至少)以获得警告。

    【讨论】:

    • 我知道了,我没有准确地注意到盗用是int **a[2]; 然后分配给a[0] = 是错误的:对不起,伙计
    • @GrijeshChauhan 好吧,我很高兴你终于明白了......它只被不同的人提到过六次。无论如何,道歉接受了。
    • 你能看到已删除的答案吗?
    • 但是如果我改变 a[0] = &a1 的赋值,即指向 int 的指针,那么它也不起作用,但会抛出随机值。
    • @GrijeshChauhan 不,我看不到已删除的答案。
    【解决方案5】:

    您正在递增指针本身并再次打印它..

    所以,

    printf("%d",*(++(*a)));//would print 2
    
    printf("%d",*(++(*a)));//would print 3
    

    你应该使用*((*a)+1)

    【讨论】:

    • 不确定是否足够。初始源代码会产生警告。
    • @Korchkidu 好吧,这取决于您使用的编译器..但它的工作原理here
    • 好吧,您使用的那个甚至不会触发 C 中 func(){} 之类的警告。
    • @Bhaskar 正如我所说,您正在某处增加指针..检查您的代码..
    • 完全错误。请参阅 Joni 的回答或我的回答。
    【解决方案6】:
    #include<stdio.h>
    
    int main(void)
    {
        int a1[] = {1,2,3,4,5,6};
        int a2[] = {7,8,9,10,11,12};
        int *a3 = a1;
        int *a4 = a2;
        int **a[2];
        a[0] = &a3; // a3 is a pointer, so take its address to get a pointer to pointer
        a[1] = &a4; // same here
    
        printf("%d",*(*(a[0])+1)); // PRINTS 2
        printf("%d",*(*(a[1])+1)); // PRINTS 8
    
        return 0;
    }
    

    【讨论】:

    • a[0] 是 &a3。 *a[0] 是 a3。 **a[0] is *a3 is 1. ++(**a[0]) 会将 a1[0] 从 1 更改为 2,因此这将打印 2,但可能不是 OP 想要的方式。跨度>
    • @JimBalter:谢谢吉姆。我什至不确定他到底问了什么^^
    • 我相信他想打印 a1[1],而不是 ++a1[0]。
    • @JimBalter:那为什么要使用 ++?这里不会更清楚+1吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    • 1970-01-01
    相关资源
    最近更新 更多