【问题标题】:Using 2D arrays as multiple 1D arrays when using pointers使用指针时将 2D 数组用作多个 1D 数组
【发布时间】:2014-09-15 13:40:53
【问题描述】:

我使用下面的程序通过指针访问二维数组。

    #include<stdio.h>

void main()
{

  int num[3][2]={ {00,01},{10,11},{20,21} }; 
  int i,j;
  printf("-----------------------------------");
  /* Treating 2d array as 1d array of each row */
  for(i=0;i<3;i++)
  {
        printf("\nThe Address(&num[%d]) is %u \n \n<= WHICH IS THE SAME AS =>\n \n(num[%d]) %u \t",i,&num[i],i,num[i]);
        printf("[*(num+%d)] %u \t [(num+%d)] %u ",i,*(num+i),i,(num+i)); 
        printf("\n The Value is %d \n",*num[i]);
        printf("\n -----------------------------------");
  }
}

这是输出:

    -----------------------------------
The Address(&num[0]) is 2140353424 

<= WHICH IS THE SAME AS =>

(num[0]) 2140353424     [*(num+0)] 2140353424    [(num+0)] 2140353424 
 The Value is 0 

 -----------------------------------
The Address(&num[1]) is 2140353432 

<= WHICH IS THE SAME AS =>

(num[1]) 2140353432     [*(num+1)] 2140353432    [(num+1)] 2140353432 
 The Value is 10 

 -----------------------------------
The Address(&num[2]) is 2140353440 

<= WHICH IS THE SAME AS =>

(num[2]) 2140353440     [*(num+2)] 2140353440    [(num+2)] 2140353440 
 The Value is 20 

 -----------------------------------

我了解程序中发生了什么,并且我知道*(num+i) 用于访问每一行的地址。

但是,为什么*(num+i)(num+i) 都指向同一个地址?

要访问特定行(第 i 行)的值,我们使用 **(num+i) 这很有意义,因为 *(num+i) 指向第一个一维数组的行地址,我们可以使用另一个间接运算符来取消引用该指针。

但是为什么*(num+i)(num+i) 都指向同一个地址呢? 这个编译器依赖吗?还是一些未定义的行为?

请提供尽可能多的信息。

【问题讨论】:

  • 问题出在哪里?没关系,*(num + i) = (num + i)[0] 和 *((num + i)[0]) = num[i][0]

标签: c arrays pointers


【解决方案1】:

多维数组连续存储在内存中。这是数组的内存布局:

 [0][0] [0][1] [1][0] [1][1] [2][0] [2][1]
+------+------+------+------+------+------+
|  00  |  01  |  10  |  11  |  20  |  21  |
+------+------+------+------+------+------+
|_____________|_____________|_____________|
^             ^             ^
num[0]        num[1]        num[2]

在我的机器上,int 的大小为 4 个字节。
num 的类型为 int (*)[2] - 它是一个指向 2 个整数数组的指针。语句num+1 是一个指针算法,结果是向num 数组开始的地址添加8 个字节(即两个整数的大小)。
取消引用后 - *(num+1) 它仍然是一个指针,它指向与 num+1 相同的地址。你可以检查这个短代码来看看发生了什么:

#include <stdio.h>

int main(void)
{
    int num[3][2]={ {00,01},{10,11},{20,21} }; 
    int (*fp)[2] = num+1;
    int* fpp = *(num+1);
    printf("%d\n", (void*)fpp == (void*)fp);
    return 0;
}

输出为 1 - 这些指针拥有相同的内存地址。

【讨论】:

  • 感谢代码图帮助我理解了您的帖子。
  • 很高兴能为您提供帮助。
【解决方案2】:

但是,为什么*(num+i)(num+i) 都指向同一个地址?

因为:

  1. 数组名是指向数组第一个元素的指针(地址)。
  2. array[x] 等于 *(array+x)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-16
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    相关资源
    最近更新 更多