简体   繁体   English

如何在C(2d数组)中增加指针

[英]How to increment a pointer in C (2d array)

I need to increment a pointer in C. I am working on a function that calculates the sum of two matrices and it get's these matrices as pointers to a 2d array ( double** matrix1 as a paramter). 我需要在C中增加一个指针。我正在一个函数,该函数计算两个矩阵的总和,并将这些矩阵作为指向2d数组的指针( double** matrix1作为参数)。 Now I don't know how to increment that pointer. 现在我不知道如何增加该指针。

Can I just use *matrix1++ for the first and **matrix1++ for the second pointer? 我可以仅将*matrix1++用于第一个指针,并将**matrix1++用于第二个指针吗? Or how do i increment each pointer individually? 或者我如何分别增加每个指针?

EDIT: This is how the function should be declared: 编辑:这是应如何声明函数:

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

n is the dimension of the matrix (only a quadratic matrix for now) A & B are the two matrices and C is the result matrix. n是矩阵的维数(目前仅是二次矩阵),A和B是两个矩阵,C是结果矩阵。

I'm going to challenge the frame of the question slightly: you're not using the right kind of “two-dimensional array” as your data structure. 我将对这个问题的框架进行一些挑战:您没有使用正确的“二维数组”作为数据结构。

In C, you have the option to call your function with flexible array bounds. 在C语言中,您可以选择使用灵活的数组范围来调用函数。 This allows your arrays to be rectangular , that is, rows of equal size laid out contiguously in memory. 这使您的数组可以是矩形的 ,即,大小相等的行连续排列在内存中。 One simple implementation: 一个简单的实现:

#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;
}

There are of course more complex array-multiplication algorithms with a better runtime than O(N³). 当然,还有比O(N³)更复杂的数组乘法算法,其运行时间更好。

Since the elements of a rectangular array are contiguous in memory, if you literally want to increment through them (such as to set every matrix element to the same value), you just initialize a pointer to the first element and increment it. 由于矩形数组的元素在内存中是连续的,因此,如果您确实想在它们中进行递增(例如将每个矩阵元素设置为相同的值),则只需初始化指向第一个元素的指针并对其进行递增。

The data structure you're using, a double** , is a ragged array . 您使用的数据结构double**是一个参差不齐的数组 It's almost never the data structure you really want (unfortunately, all C and C++ programmers learn about char** argv first). 几乎从来没有真正想要的数据结构(不幸的是,所有C和C ++程序员都首先了解char** argv )。 Ragged arrays require a dynamic allocation per row rather than a single one for the entire matrix, add a pointer lookup per access, and have poor data locality, making them much slower. 参差不齐的数组需要每行动态分配,而不是整个矩阵分配一个动态行,每次访问都添加一个指针查找,并且数据局部性差,这使得它们慢得多。 They also waste memory on all those pointers. 它们还会在所有这些指针上浪费内存。

If your array is sparse, there are more efficient data structures, such as compressed sparse row. 如果数组是稀疏的,则存在更有效的数据结构,例如压缩的稀疏行。 If it is dense, and all the rows are the same size anyway, a rectangular array is strictly superior to a ragged array. 如果它很密集,并且所有行的大小都相同,则矩形阵列严格优于粗糙的阵列。

If you do want to stick with a ragged array, simply use the function prototype you did before, and keep the loop the same. 如果您确实想使用粗糙的数组,只需使用之前做过的函数原型,并保持循环不变即可。 Array indices such as a[i][k] will work for either a ragged or a rectangular array. 数组索引(例如a[i][k]适用于参差不齐的数组或矩形数组。

My personal preference is to use ptrdiff_t (the type you get when subtracting pointers) for array indices, since these are signed and don't create as many bugs from silent overflows and type promotions as unsigned types do. 我个人的喜好是对数组索引使用ptrdiff_t (减去指针时得到的类型),因为它们是有符号的,不会像无符号类型那样从静默溢出和类型提升中产生许多错误。 They also are the right width, not limited to 32 bits on 64-bit systems. 它们也是正确的宽度,不限于64位系统上的32位。

Finally, in C++, this solution would be illegal; 最后,在C ++中,此解决方案将是非法的。 I usually write a two-dimensional array class to provide a zero-cost abstraction. 我通常会编写一个二维数组类来提供零成本的抽象。

I think if you want to calculate the sum of 2 matrices, you should increment both pointers like this 我认为如果要计算2个矩阵的总和,就应该像这样增加两个指针

**arrayptr++;

This is because if arrayptr points to a 2d matrix, *arrayptr points to the first element in it which is a 1d array. 这是因为如果arrayptr指向2d矩阵,则*arrayptr指向其中的第一个元素即1d数组。 For calculating the sum, you would want to iterate over each individual element in those 1d arrays that make up the matrix. 为了计算总和,您需要对构成矩阵的一维数组中的每个元素进行迭代。 Hence use **arrayptr to access those elements. 因此,使用**arrayptr访问这些元素。

Correct me if im wrong. 如果我错了纠正我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM