简体   繁体   中英

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). Now I don't know how to increment that pointer.

Can I just use *matrix1++ for the first and **matrix1++ for the second pointer? 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)

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.

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. 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³).

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 . It's almost never the data structure you really want (unfortunately, all C and C++ programmers learn about char** argv first). 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.

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. They also are the right width, not limited to 32 bits on 64-bit systems.

Finally, in C++, this solution would be illegal; 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

**arrayptr++;

This is because if arrayptr points to a 2d matrix, *arrayptr points to the first element in it which is a 1d array. 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.

Correct me if im wrong.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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