【问题标题】:How to get column of a multidimensional array in C/C++?如何在 C/C++ 中获取多维数组的列?
【发布时间】:2013-02-21 21:03:56
【问题描述】:
int matrix[9][9],*p;
p=matrix[0]; 

这有效并给出matrix 的第一行,但是如何获得matrix 的第一列我试过p=matrix[][0]; ?我也不明白为什么下面的代码会出现编译器错误?

int matrix[9][9],p[9];  // it looks really ugly, byt why it doesn't work ?
p=matrix[0];            // compiler gives "invalid array assigment"

是不是因为多维数组是数组的数组 - 我们应该将matrix[i][j] 解释为第 i 个嵌套数组的第 j 个元素?

【问题讨论】:

    标签: c++ c arrays multidimensional-array variable-assignment


    【解决方案1】:

    在 C/C++ 中,多维数组实际上存储为一维数组(在内存中)。您的 2D 矩阵存储为具有行优先顺序的一维数组。这就是为什么要从中取出一列并不容易,并且默认情况下不提供。 内存中没有连续的数组,您可以获取指向该指针的指针,该指针表示多维数组的列。见下文:

    当您执行p=matrix[0] 时,您只是获得了指向第一个元素matrix[0][0] 的指针,这让您认为您获得了指向第一行的指针。实际上,它是一个指向包含matrix的整个连续数组的指针,如下:

    matrix[0][0]
    matrix[0][1]
    matrix[0][2]
    .
    .
    matrix[1][0]
    matrix[1][1]
    matrix[1][2]
    .
    .
    matrix[8][0]
    matrix[8][1]
    matrix[8][2]
    .
    .
    matrix[8][8]
    

    如上所示,任何给定列的元素都由相应行中的其他元素分隔。

    因此,作为旁注,使用指针 p,如果您愿意,您可以遍历矩阵的全部 81 个元素。

    【讨论】:

    • “存储为一维数组”的说法有点奇怪。它们只是数组的数组,所以我承认内存布局是相似的,但语义有点不同。
    • 语义不同是的,我指的是内存布局。我会重写那部分。
    • @meyumer 错了,对不起,他们在记忆中真的是挨着的
    【解决方案2】:

    您可以使用类似的循环获取第一列

    for(int i = 0; i < 9; i++)
    {
        printf("Element %d: %d", i, matrix[i][0]);
    }
    

    我认为分配不能正常工作,因为您试图将不是地址的东西分配给指针。

    (对不起,这是c代码)

    【讨论】:

    • 抱歉,我想要通用解决方案,很高兴这是您的第一篇文章 +1
    • 我认为应该是matrix[i][0],因为 C 和 C++ 使用 0 作为第一个元素。
    • 这就是这样做的方法。您必须遍历数组才能获得所需的元素。没有简单的方法,因为如上所述,元素不在连续的内存位置。
    【解决方案3】:

    指定matrix[81]matrix[9][9]没有区别

    matrix[r][c]matrix[9*r+c] 的意思相同

    还有其他更适合用于多维数组的容器,例如 boost::multi_array

    http://www.boost.org/doc/libs/1_53_0/libs/multi_array/doc/index.html

    将裸数组想象成分配一块连续的内存。你,程序员然后必须自己处理这块内存。数组的裸名,例如matrix 是指向这块已分配内存的第一个元素的指针。那么*(matrix+1)matrix[0][1]matrix[1] 相同。

    【讨论】:

    • 您确定matrix[81]matrix[9][9] 相同吗?我的理解是matrix[9][9]等价于int * matrix[9],也就是说它是一个指针容器,而不是连续的内存位置。
    • 当你问我时,我变得不确定。所以我查了一下,现在我确定了。见这里例如stackoverflow.com/questions/7784758/…
    • 我需要对此做一个小的修正。从内存布局的角度来看,没有区别。但是如果编译器有关于原始数组声明的信息,那么它的解释方式就会有所不同。例如matrix[R][C] 可以从指针int* mp (int*)matrix 线性访问,需要强制转换以避免警告。您可以使用int (row_ptr*)[C] = matrix 访问行,然后指针算术将确保您移动一整行,例如(row_ptr+1) 将指向第二行。值访问也必须是 **(row_ptr+1)。但是内存中没有指针。
    【解决方案4】:

    p 是一个 int 数组,matrix[0] 是一个指针..

    【讨论】:

    • @Qbik *(matrix[0]) 是一个 int,您不能将一个 int 分配给一个 int 数组
    • 现在我明白了!我打印了 *p 并且数据是正确的,但它只是指向单个 int 的指针
    【解决方案5】:

    matrix 本身是最接近数组列的值,因为(matrix + 1)[0][0]matrix[1][0] 相同。

    【讨论】:

      【解决方案6】:

      如果您希望矩阵位于连续位置,请将其声明为一维数组并自行执行行和列计算:

      int contiguous_matrix[81];
      
      int& location(int row, int column)
      {
        return contiguous_matrix[row * 9 + column];
      }
      

      您还可以遍历一行的每一列:

      typedef void (*Function_Pointer)(int&);
      
      void Column_Iteration(Function_Pointer p_func, int row)
      {
        row = row * MAXIMUM_COLUMNS;
        for (unsigned int column = 0; column < 9; ++column)
        {
          p_func(contiguous_matrix[row + column]);
        }
      }
      

      【讨论】:

        【解决方案7】:

        对于静态声明的数组,您可以像连续一维数组一样访问它们,p = matrix[0] 将为您提供第一行的第一列。然后可以像p[i]*(p+i)p[current_raw * raw_size + current_column) 一样访问一维数组。

        如果二维数组用**p 表示,事情就会变得棘手,因为它将被解释为指向一维数组的指针数组。

        【讨论】:

          【解决方案8】:

          我不知道这是否是一个有效的解决方案,但通过这种方式我能够获得该列,

          int arr[9][2] = { {2,  57}, {3,  66}, {4,  73}, {5,  76}, {6,  79}, {7,  81}, {8,  90}, {9,  96}, {10, 100}};
          
          int c[18];
          int co = 0;
          for (auto & i : arr) {
              for (int j : i) {
                  c[co++] = j;
              }
          }
          
          for (int i = 0; i < co; ++i) {
              if (i % 2 != 0)
                  std::cout << c[i] << " ";
          }
          

          【讨论】:

            猜你喜欢
            • 2012-03-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-09-15
            • 1970-01-01
            • 2015-09-24
            相关资源
            最近更新 更多