【问题标题】:Representing a two-dimensional array assignment as a pointer math?将二维数组赋值表示为指针数学?
【发布时间】:2013-03-03 21:44:00
【问题描述】:

我有一个数组 ex:

int array[3][5];

如果我想为该数组中的元素赋值,这很简单……例如:

array[1][2] = 8;

但是,我想用指针数学来表示它,这是否正确?

**(array + 5 * 1 + 2) = 8;

在这两种情况下,它都在寻找第 7 个位置...我只是不确定是否需要在(代码)之外包含第 2 个 *

**(code)

编辑:只是有点跟进。感谢所有帮助我的人。我的困惑来自教师笔记中的错误,在我展示了您提供的信息后,他意识到了错误并同意

*(*(array+row)+col) 

*(*array+MAX_COL*row+col) 

是二维数组的精确指针数学表示。

**(array+MAX_COL*row+col)类似于array[MAX_COL*row+col],用于多维数组的一维数组实现,就像这篇帖子的回复之一中提到的James Kanze(第二个是比第一个更快)。

【问题讨论】:

  • 那个问题是给 C 的……我不确定我的情况是否一样。
  • 您所做的与 C 中的相同。继续使用@Antonijn 引用的问题。
  • 好吧,我的代码看起来与其他人使用的有点不同...我的版本使用 **(array + MAX_COL * row + col) 是否正确?
  • *(*(a+1)+2) = 8;您所做的将指向未定义且错误的 a[7][0] 位置。一般*(*(数组+行)+列)。

标签: c++ c arrays pointers


【解决方案1】:

您需要知道的第一件事是二维数组不是指向指针的指针。它们在内存中是连续的,因此您可以通过指向 T 的指针来表示它们(T 是基本类型):

int arr[3][5];
int *p = &arr[0][0];

int array_1_2 = *(p + 5 * 1 + 2);

【讨论】:

    【解决方案2】:

    array[1][2] 等于 *( *(array + 1) + 2)

    【讨论】:

      【解决方案3】:

      演示指针算术运算与访问数组同义的示例。

      #include<stdio.h>
      
      int main()
      {
      int array[3][5] = {0};
      array[2][3] = 5;
      printf( "%d\n",array[2][3]);
      printf( "%d\n",*(*(array+2)+3) );
      return 0;
      } 
      

      【讨论】:

        【解决方案4】:

        您的问题中有几个错误的假设:对于 例如,array[1][2] 不看第 7 位;它是 查看第二个数组元素中的第三个位置 arrayarray的类型是int的array[5]的a​​rray[3]; 当它转换为指针时,结果类型是指针 到int 的数组[5],不是指向int 的指针。所以array + 5 * 1 + 2) 指的是数组的第八个元素,只有 5个元素;即 35 * sizeof(int) 超出array 的开头 (并且表达式仍然具有指向 int 的数组 [5] 的类型指针)。

        作为一般规则,如果您想模拟访问 一个多维数组,你应该声明一个 维数组:

        int array[columns * rows];
        

        如果你这样做,那么*(array + i * columns + j) 将 有效地执行二维索引。

        【讨论】:

          【解决方案5】:

          另一种表示是

          *(array[1]+5)=8
          

          让我解释一下简单的类似代码。

          int *p[5];
          

          这里p是一个指向第一个元素地址的指针,p等价于&amp;p[0]

          举个例子来理解这个

          #include<iostream.h>    
          void main()
          {    
          int *p[2];
          int a=0,b=1;
          p[0]=&a;p[1]=&b;
          cout<<*p<<endl<<&a<<endl;
          cout<<*(p+1)<<endl<<&b<<endl;
          cout<<p<<endl<<p+1<<endl;
          cout<<**p<<endl<<**(p+1);    
          }
          

          上面代码的输出是

          0x8fbdfff0
          0x8fbdfff0
          0x8fbdffee
          0x8fbdffee
          0x8fbdfff2
          0x8fbdfff4
          0
          1
          

          在我们的例子中,int array[3][5] 等价于 int *p1[5] int *p2[5] int *p3[5]。其中p1,p2,p3分别代表指针指向第一、二、三行的第一个元素。

          所以实际上我们可以将array[3]视为一个指针,array[1]等价于p1类似的数组[2]和3 因此,要获得array[1][2],我们可以使用*(array[1]+2)((array+1)+2) 或考虑它是以行主要形式实现的@987654340 @ 等价于 array+1*5 你得到
          *(array+1*5+2)

          【讨论】:

            【解决方案6】:

            使用以下数组:

            const int ROWS = 3;
            const int COLS = 5;
            int arr[ROWS][COLS];
            

            虽然arr 指向第一个元素所在的内存,但它的类型不是int*,因此增加此指针不会将您移动到第二个int。所以这一行:

            arr[1][2] = 8;
            

            可以替换为:

            *((int*)arr + 1*COLS + 2) = 8;
            

            或者你可以使用这个事实,这个数组驻留在连续的内存块中,其大小等于ROWS * COLS * sizeof(int),因此你可以简单地检索指向第一个元素的指针并将其用于此目的:

            int* pFirstEle = &arr[0][0];
            *(pFirstEle + 1*COLS + 2) = 8;
            

            但请注意这是错误的:

            **(arr + 1*COLS + 2) = 8;
            

            【讨论】:

            • 首先arr的类型其实是int[3][5]arr 不是指针。并将其转换为指针,然后前进 1,指向第二个元素。元素的类型当然是int[3],而不是int
            • @JamesKanze:我的意思是int[3][5] 在被视为指针时的行为类似于int (*)[5],而第二个元素当然是指第二个整数,而不是第二行。无论如何,我编辑了我的答案。
            猜你喜欢
            • 2018-10-20
            • 1970-01-01
            • 2012-05-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-04-12
            • 1970-01-01
            相关资源
            最近更新 更多