c - 如何在 C 中增加指针(二维数组)

标签 c pointers matrix

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

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

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

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

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

最佳答案

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

在 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(N3) 更好。

由于矩形数组的元素在内存中是连续的,因此如果您确实想对它们进行递增(例如将每个矩阵元素设置为相同的值),只需初始化指向第一个元素的指针并递增它即可。

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

如果您的数组是稀疏的,则有更有效的数据结构,例如压缩稀疏行。如果它是密集的,并且所有行的大小都相同,则矩形数组严格优于参差不齐的数组。

如果您确实想坚持使用不规则数组,只需使用之前所做的函数原型(prototype),并保持循环相同即可。诸如a[i][k]之类的数组索引适用于不规则数组或矩形数组。

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

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

关于c - 如何在 C 中增加指针(二维数组),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53669185/

相关文章:

python - 检查矩阵键是否按运行顺序 - python

c++ - ']' 标记之前的预期表达式? C

将 "int* pointer"与常量内存地址进行比较

c - 在为副本进行转换后,我是否需要再次对 void 指针进行类型转换以进行算术?

c++ - 在CUDA中乘以矢量化二维方阵和压缩三对角矩阵

r - 从现有矩阵构建 block 矩阵并在 r 中保留暗名称

c - 如何计算二维数组中每行的总和并打印最大总和。 c语言

c++ - Cmake可以生成一个同时支持调试和发布的makefile吗

c - 用数组实现栈

c - 如何声明全局结构数组并在不同的函数中使用它?