当数组格式如下时,如何将二维数组传递给 C 中的函数?

How to pass a 2D array to a function in C when the array is formatted like this?

我想创建一个数组(称为 Csend),然后创建一个对其进行稍微修改的函数,例如向每个元素添加 0.05。我遇到的问题是数组的格式,我不确定如何将它正确地传递给函数。我在 this guide 之后以这种方式分配了内存,以便以后可以将其放入 MPI_Send 和 MPI_Recv.

这是我的尝试:

#include "stdio.h"
#include "stdlib.h"
#include "mpi.h"
#include "math.h"


int main(int argc, char **argv) {

  int N = 32;
  int dim = 3;
  float a = 10.0; // size of 3D box
  int size, rank, i, j, k, q;
  float **C, **Csend, **Crecv;
  float stepsize = 0.05;

  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &size);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  float **alloc_2d_float(int rows, int cols) {
    float *data = (float *)malloc(N*dim*sizeof(float));
    float **array= (float **)malloc(N*sizeof(float*));
    for(i=0; i<N; i++) {
        array[i] = &(data[dim*i]);
     }
    return array;
}

  C = alloc_2d_float(N,dim);
  Csend = alloc_2d_float(N,dim);
  Crecv = alloc_2d_float(N,dim);

if(rank == 0) {
for (i = 0; i < N; i++) {
    for (j = 0; j < dim; j++) {
        Csend[i][j] = (float)rand()/(float)(RAND_MAX/a);
  }}
}

  // FUNCTION TO MODIFY MATRIX //
  float randomsteps(float *matrix, int N, int dim) {
  int i, j;
for(i = 0; i < N; i = i+2) {
        for (j = 0; j < dim; j++) {
*((matrix+i*N) + j) = *((matrix+i*N) + j) + stepsize;
}
}
return matrix;
  } 

C = randomsteps(Csend, 32, 3);
  for (i=0; i<N; i++){
    for (j=0; j<dim; j++){
      printf("%f, %f\n", Csend[i][j], C[i][j]);
    }
  }

 MPI_Finalize();

  return 0;
}

我遇到的问题是像这里一样格式化,我收到错误消息,并且以没有给出错误消息的方式格式化,C 只是空的。

错误信息如下:

test.c: In function ‘randomsteps’:
test.c:46: error: incompatible types when returning type ‘float *’ but ‘float’ was expected
test.c: In function ‘main’:
test.c:49: warning: passing argument 1 of ‘randomsteps’ from incompatible pointer type
test.c:39: note: expected ‘float *’ but argument is of type ‘float **’
test.c:49: error: incompatible types when assigning to type ‘float **’ from type ‘float’

感谢您的帮助!

您混淆了矩阵的一维表示和它的指向指针方法的二维指针。

*((matrix+i*N) + j) = *((matrix+i*N) + j) + stepsize; -> 这一行暗示 matrix 只是线性集合,它像使用索引操作的矩阵一样访问。

float **C; -> 这意味着您需要一个可以作为 C[i][j] 访问的矩阵。

坚持任何一种表述。此外,由于您的函数 return 是一个矩阵,如果您想要没有索引操作访问权限的二维矩阵。

float* matrix = malloc(row * cols * sizeof(float)); // This is a linear version.
// matrix[i*cols + j] gives you the (i, j)th element.

float** matrix = malloc(rows * sizeof(float*)); 
for(int i = 0; i < rows; ++i)
    matrix[i] = malloc(cols * sizeof(float));
// Now you can access matrix[i][j] as the (i, j)th element.

这是一种在两种格式之间相互转换的方法。

float* linearize(float** matrix, unsigned int rows, unsigned int cols)
{
    float* linear = malloc(rows * cols * sizeof(float));
    if(linear)
    {
        for(unsigned int i = 0; i < rows; ++i)
            for(unsigned int j = 0; j < cols; ++j)
                linear[i*cols + j] = matrix[i][j] ;
    }
    return linear ;
}


float** unlinearize(float* linear, unsigned int rows, unsigned int cols)
{
    float** matrix = malloc(rows * sizeof(float*));
    if(matrix)
    {
        for(unsigned int i = 0; i < rows; ++i)
        {
            matrix[i] = malloc(cols * sizeof(float));
            if(matrix[i])
            {
                for(unsigned int j = 0; j < cols; ++j)
                    matrix[i][j] = linear[i*cols + j] ;
            }
        }
    }
    return matrix ;
}