如何增加 C 中的指针(二维数组)

Posted

技术标签:

【中文标题】如何增加 C 中的指针(二维数组)【英文标题】:How to increment a pointer in C (2d array) 【发布时间】:2018-12-07 12:04:18 【问题描述】:

我需要在 C 中增加一个指针。 我正在研究一个计算两个矩阵之和的函数,它将这些矩阵作为指向二维数组的指针(double** matrix1 作为参数)。 现在我不知道如何增加那个指针。

我可以只使用*matrix1++ 作为第一个指针,**matrix1++ 作为第二个指针吗? 或者我如何单独增加每个指针?

编辑: 这就是函数的声明方式:

void matplus(int n, double** A, double** B, double** C)

n 是矩阵的维数(目前只有二次矩阵)A & B 是两个矩阵,C 是结果矩阵。

【问题讨论】:

double** 不能指向二维数组。我认为您使用某种指针表?能否请您发布整个功能,以便更清楚为什么需要这样做。 我目前正处于项目的开始阶段,我不使用某种指针表。我想要做的是获得一个指向二维数组的指针。还有其他方法可以做到这一点吗?我想我需要 2 个指针,每个维度一个,对吧? 指针不是数组。而且你不能改变一个数组,只能改变它的元素。 【参考方案1】:

我将稍微挑战一下问题的框架:您没有使用正确的“二维数组”作为数据结构。

在 C 中,您可以选择使用灵活的数组边界来调用您的函数。这允许您的数组是矩形,即大小相等的行在内存中连续布置。一个简单的实现:

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>

void sq_matrix_mul( const ptrdiff_t n,
                    const double left[n][n],
                    const double right[n][n],
                    double product[n][n] )

    for ( ptrdiff_t i = 0; i < n; ++i )
      for ( ptrdiff_t j = 0; j < n; ++j ) 
        product[i][j] = 0.0;

        for ( ptrdiff_t k = 0; k < n; ++k )
          product[i][j] += left[i][k] * right[k][j];
       // end for j


#define DIMENSION 4

int main(void)

  static const double a[DIMENSION][DIMENSION] = 
     1, 0, 0, 0 ,
     0, 2, 0, 0 ,
     0, 0, 3, 0 ,
     0, 0, 0, 4 
  ;
  static const double b[DIMENSION][DIMENSION] = 
     1, 1, 1, 1 ,
     1, 1, 1, 1 ,
     1, 1, 1, 1 ,
     1, 1, 1, 1 
  ;
  double c[DIMENSION][DIMENSION];

  sq_matrix_mul( DIMENSION, a, b, c );

  for ( ptrdiff_t i = 0; i < DIMENSION; ++i ) 
    fputs( "[ ", stdout );

    for ( ptrdiff_t j = 0; j < DIMENSION; ++j )
      printf( "%f ", c[i][j] );

    fputs( "]\n", stdout );
  

  return EXIT_SUCCESS;

当然还有比 O(N³) 运行时间更复杂的数组乘法算法。

由于矩形数组的元素在内存中是连续的,如果你真的想通过它们递增(例如将每个矩阵元素设置为相同的值),你只需初始化一个指向第一个元素的指针并递增它。

您使用的数据结构 double** 是一个不规则数组。它几乎从来都不是您真正想要的数据结构(不幸的是,所有 C 和 C++ 程序员都首先了解 char** argv)。参差不齐的数组需要每行动态分配,而不是为整个矩阵单独分配一次,每次访问添加一个指针查找,并且数据局部性差,这使得它们慢得多。它们还会在所有这些指针上浪费内存。

如果你的数组是稀疏的,还有更高效的数据结构,比如压缩稀疏行。如果它是密集的,并且所有行的大小无论如何都相同,那么矩形数组绝对优于不规则数组。

如果您确实想坚持使用不规则数组,只需使用您之前所做的函数原型,并保持循环不变。 a[i][k] 等数组索引适用于不规则数组或矩形数组。

我个人的偏好是使用ptrdiff_t(减去指针时得到的类型)作为数组索引,因为它们是有符号的,并且不会像无符号类型那样从静默溢出和类型提升中产生那么多错误。它们也是正确的宽度,不限于 64 位系统上的 32 位。

最后,在 C++ 中,这种解决方案是非法的;我通常写一个二维数组类来提供零成本的抽象。

【讨论】:

【参考方案2】:

我认为如果你想计算两个矩阵的和,你应该像这样增加两个指针

**arrayptr++;

这是因为如果arrayptr 指向二维矩阵,*arrayptr 则指向其中的第一个元素,即一维数组。为了计算总和,您需要迭代构成矩阵的那些一维数组中的每个单独元素。因此使用**arrayptr 来访问这些元素。

如果我错了,请纠正我。

【讨论】:

以上是关于如何增加 C 中的指针(二维数组)的主要内容,如果未能解决你的问题,请参考以下文章

如何通过c中的指针传递二维数组[重复]

C中的二维数组和指针 - 如何访问元素?

如何使用指针表达式访问 C 中的二维数组的元素?

c语言如何表示二维数组里面有#

c语言中如何通过二级指针来操作二维数组

C语言中二维数组行指针是啥