数组元素打印的地址是什么?

时间:2016-03-30 11:44:04

标签: c arrays pointers

更新:已报告此问题的可能重复。虽然提交给that question的答案部分解决了这个问题,但要解释why we can't use double pointers to represent two dimensional arrays指定如何访问存储在指针中的值的正确内存地址;这是这个问题的主题。这个问题中的明确答案可以很好地澄清给那些在未来 中困惑的人,关于为什么这是一个被误解的概念以及如何解决它的替代方法。这对于希望跟踪输出以更好地理解概念的未来读者可能是有用的(如果仔细观察comments by the OP in that question,您会发现跟踪不够清楚,无法让他理解。这个问题的 部分 提供了一个更好的跟踪示例,以便几乎任何人都可以轻松理解)

(问题的其余部分在于其未经编辑的荣耀,以便未来的读者能够反思类似的错误,如果它们碰巧成功的话。)

我想做的事情:

  • 试图查看如何使用指针而不是2D数组
  • 在这种情况下,我将值插入2D数组(,a [] []
  • 我试图用指针(,即ptr )访问该数组中的值
  • 我也在尝试跟踪从中获取这些值的内存地址
  • 试图了解我出错的地方?(希望得到适当的解释,如果可能的话,还要提供参考链接并进一步了解)

我尝试了什么:
以下是示例代码:

int main()
{
  int a[2][2]={{5,7},
               {0,1}};
  int** ptr=(int**)a;
  int i,j;
for(i=0;i<2;i++){
    for(j=0;j<2;j++){
        printf("%d printing from==>%x\n",&ptr[i][j],((&ptr[i])+j));
   }
  }
  getch();
  return(0);
}

在上面的代码中,我试图在指针ptr的帮助下打印矩阵a [] []中存在的值。在这样做时,我正在跟踪实际发生打印的地址(在内存地址中)。我似乎遇到了以下形式的灾难性输出

  

从==&gt; 12ff7c打印5   9从==&gt; 12ff80打印   7从==&gt; 12ff80打印   11从==&gt; 12ff84打印

然后我修改了一行:

printf("%d printing from==>%x\n",&ptr[i][j],((&ptr[i])+j));

用这个:

printf("%d printing from==>%d\n",&ptr[i][j],*((&ptr[i])+j));

知道这些地址中存在 实际 的值:

  

从==&gt; 5打印5   9从==&gt; 7打印   7从==&gt; 7打印   11从==&gt; 0打印

我对此的看法是:&amp; ptr [i] [j]相当于(*(&amp; ptr [i])+ j)) 和((&amp; ptr [i])+ j))并没有真正告诉我那些数字的地址,因为&amp; ptr [i]定义了一个地址,在这种情况下增加了j(但是因为j在每个外部循环迭代中重置为0;这将导致相同的内存地址被指向两次) 我对这一思路错了吗?

你怎么能帮助我?

  • Here is my code悲惨地失败了,并且基于我在阅读here 双指针和C中的二维数组 上的文章。我是否从根本上误解了它?
  • 您是否可以通过修改我的给定代码here并在评论中发布您自己的perma-link来发布正确的cpp代码?(您可以点击下面的&#34; GET URL&#34;按钮执行此操作该网站的编码区域)
  • 我非常感谢基于C而不是C ++的答案,其中typedef ans是可能的我试图更好地学习指针

1 个答案:

答案 0 :(得分:5)

2D数组和指针指针是不同的动物!

一个二维数组,比如int arr[N][M],是一个N * M个连续元素的数组,具有以下关系&arr[i][j] == &arr[0][0] + i * M + j

指针指针是指向指针数组的指针,每个指针都指向另一个数组。

那你能做什么?

  • 将数组处理为具有显式索引的一维数组

    int main()
    {
      int a[2][2]={{5,7},
                   {0,1}};
      int* ptr=a[0];  // a[0] decays to a pointer...
      int i,j;
      for(i=0;i<2;i++){
        for(j=0;j<2;j++){
            printf("%d printing from==>%x\n",ptr[j + 2 *i],ptr + j + 2 * i);
        }
      }
      //getch();
      return(0);
    }
    
  • 明确地创建一个指针数组

    int main()
    {
      int a[2][2]={{5,7},
                   {0,1}};
      int *b[] = { a[0], a[1] };  // array of pointers pointing to beginning or rows
      int** ptr=b;  // b decays to a pointer to pointer
      int i,j;
      for(i=0;i<2;i++){
        for(j=0;j<2;j++){
            printf("%d printing from==>%x\n",ptr[i][j],&(ptr[i][j]));
        }
      }
      //getch();
      return(0);
    }
    
  • 明确地使用指向确定大小的数组的指针:

    int main()
    {
      int a[2][2]={{5,7},
                   {0,1}};
      int (*ptr)[2] = a;  // a decays to a pointer arrays of size 2
      int i,j;
      for(i=0;i<2;i++){
        for(j=0;j<2;j++){
            printf("%d printing from==>%x\n",ptr[i][j],&(ptr[i][j]));
        }
      }
      //getch();
      return(0);
    }
    

另请注意,我在上面的代码中没有明确的强制转换,让编译器控制了无效级别。