简体   繁体   English

如何使用指针将多维数组传递给 C 函数?

[英]How to pass a multidimensional array to a C function using pointers?

I'm trying to write a program where you have to find the maximum and minimum number in a multidimensional array using double pointers.我正在尝试编写一个程序,您必须使用双指针在多维数组中找到最大和最小数字。 But when I try to compile it, the compiler returns to me this message:但是当我尝试编译它时,编译器会返回给我这条消息:

warning: passing argument 1 of 'MinMax' from incompatible pointer type [-Wincompatible-pointer-types]
   33 |     MinMax(V, ptm, ptM);
      |            ^
      |            |
      |            double (*)[5]

.\1-maxminarraymulti.c:18:22: note: expected 'double **' but argument is of type 'double (*)[5]'
   18 | void MinMax(double **V, double **mi, double **Ma);".

Code:代码:

#include <stdio.h>

#define N 5
#define M 5

void MinMax(double **V, double **mi, double **Ma);

void main() {
    double V[N][M] = { { 1, 5, 2, 3, 9 },
                       { 12, 6, 90, 2, 0 },
                       { -12, 41, 2, 9, 56 },
                       { 78, 2, 1, 523, 39 }, 
                       { 92, 13, 63, 2, 12 } };

    double Min, Max;

    double *ptMin = &Min;
    double *ptMax = &Max;

    double **ptm = &ptMin;
    double **ptM = &ptMax;
    
    MinMax(V, ptm, ptM);
}

void MinMax(double **V, double **mi, double **Ma) {
    
    //printf to see if the bi-dimensional array has been passed correctly to function.
    printf("%lf", V[3][0]);
}

The prototype for your function should be different: it should take a matrix of N by M doubles and pointers to double for the results.您的函数的原型应该不同:它应该采用N x M双精度矩阵和指向结果的双精度指针。 The matrix should be const qualified since the function does not modify it.矩阵应该是const限定的,因为函数不会修改它。

You could write this as:你可以这样写:

void MinMax(double const V[N][M], double *minp, double *maxp);

This prototype is somewhat confusing because arrays are not passed by value: they decay as pointers to their first element, so the array V defined as double V[N][M] is passed to MinMax as a pointer to its first element, a pointer to arrays of M double with type double (*V)[M] .这个原型有点令人困惑,因为数组不是按值传递的:它们衰减为指向其第一个元素的指针,因此定义为double V[N][M]的数组V被传递给MinMax作为指向其第一个元素的指针,一个指针到M double类型为double (*V)[M]的数组。 This conversion is implicit and the function prototype applies is implicitly as well, leading to surprising results such as `sizeof(V) == sizeof(double (*)[M]), which is the size of a pointer, not the size of the array, nevertheless that on the matrix.这种转换是隐式的,函数原型的应用也是隐式的,会导致令人惊讶的结果,例如`sizeof(V) == sizeof(double (*)[M]),它是指针的大小,而不是指针的大小数组,但在矩阵上。 The above definition is equivalent to:上述定义等价于:

void MinMax(double const (*V)[M], double *minp, double *maxp);

or或者

void MinMax(double const V[][M], double *minp, double *maxp);

Note that neither of the above prototypes specify the number of rows in the matrix, hence the function can be called with matrices of any number of rows.请注意,上述原型均未指定矩阵中的行数,因此可以使用任意行数的矩阵调用该函数。 Either the number is a convention, as double const V[N][M] may imply, or the actual number can be passed as an argument:数字是一个约定,如double const V[N][M]可能暗示的那样,或者实际数字可以作为参数传递:

void MinMax(int rows, double const V[][M], double *minp, double *maxp);

Unlike previous versions where the second and subsequent dimentions must be known at compile time, C99 allows the matrix size to be specified as variables:与在编译时必须知道第二个和后续维度的先前版本不同,C99 允许将矩阵大小指定为变量:

void MinMax(int rows, int cols, double const V[rows][cols],
            double *minp, double *maxp);

Which is still equivalent to:这仍然相当于:

void MinMax(int rows, int cols, double const V[][cols],
            double *minp, double *maxp);

and

void MinMax(int rows, int cols, double const (*V)[cols],
            double *minp, double *maxp);

Here is a modified version with an C89 implementation of MinMax for a fixed matrix size:这是一个修改后的版本,带有一个 C89 实现的MinMax ,用于固定矩阵大小:

#include <stdio.h>

#define N 5
#define M 5

void MinMax(double const V[N][M], double *minp, double *maxp);

int main() {
    double V[N][M] = { { 1, 5, 2, 3, 9 },
                       { 12, 6, 90, 2, 0 },
                       { -12, 41, 2, 9, 56 },
                       { 78, 2, 1, 523, 39 }, 
                       { 92, 13, 63, 2, 12 } };
    double Min, Max;
    
    MinMax(V, &Min, &Max);
    printf("min=%g, max=%g\n", Min, Max);
    return 0;
}

void MinMax(double const V[N][M], double *minp, double *maxp) {
    double min = V[0][0];
    double max = V[0][0];
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (min > V[i][j])
                min = V[i][j];
            if (max < V[i][j])
                max = V[i][j];
        }
    }
    *minp = min;
    *maxp = max;
}

Output:输出:

min=-12, max=523

Here is a C99 version where the matrix size is specified dynamically:这是动态指定矩阵大小的 C99 版本:

#include <stdio.h>

void MinMax(int N, int M, double const V[N][M],
            double *minp, double *maxp);

int main() {
    double V[][5] = { { 1, 5, 2, 3, 9 },
                      { 12, 6, 90, 2, 0 },
                      { -12, 41, 2, 9, 56 },
                      { 78, 2, 1, 523, 39 }, 
                      { 92, 13, 63, 2, 12 } };
    double Min, Max;
    int rows = sizeof(V) / sizeof(V[0]);
    int cols = sizeof(V[0]) / sizeof(V[0][0]);
    
    MinMax(rows, cols, V, &Min, &Max);
    printf("min=%g, max=%g\n", Min, Max);
    return 0;
}

void MinMax(int N, int M, double const V[N][M],
            double *minp, double *maxp) {
    double min = V[0][0];
    double max = V[0][0];
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (min > V[i][j])
                min = V[i][j];
            if (max < V[i][j])
                max = V[i][j];
        }
    }
    *minp = min;
    *maxp = max;
}

Output:输出:

min=-12, max=523

To handle arbitrary large matrices, rows , cols , i and j should be defined with type size_t要处理任意大矩阵, rowscolsij应该使用size_t类型定义

Note that for this problem, you could just consider the matrix as an array of rows * cols double and pass the count of elements and a pointer to the first element of the first row, an approach that does not require C99 VLA syntax:请注意,对于这个问题,您可以将矩阵视为rows * cols double的数组,并传递元素的计数和指向第一行第一个元素的指针,这种方法不需要 C99 VLA 语法:

#include <stdio.h>

void MinMax(size_t count, double const *V, double *minp, double *maxp);

int main() {
    double V[][5] = { { 1, 5, 2, 3, 9 },
                      { 12, 6, 90, 2, 0 },
                      { -12, 41, 2, 9, 56 },
                      { 78, 2, 1, 523, 39 },
                      { 92, 13, 63, 2, 12 } };
    double Min, Max;
    int rows = sizeof(V) / sizeof(V[0]);
    int cols = sizeof(V[0]) / sizeof(V[0][0]);

    MinMax(rows * cols, &V[0][0], &Min, &Max);
    printf("min=%g, max=%g\n", Min, Max);
    return 0;
}

void MinMax(size_t count, double const *V, double *minp, double *maxp) {
    double min = V[0];
    double max = V[0];
    for (size_t i = 0; i < count; i++) {
        if (min > V[i])
            min = V[i];
        if (max < V[i])
            max = V[i];
    }
    *minp = min;
    *maxp = max;
}

Output:输出:

min=-12, max=523

I would use VLAs - you can pass any size array, not only with defined compile time sizes我会使用 VLA - 您可以传递任何大小的数组,而不仅仅是定义的编译时间大小

The function assumes that you want to get pointers to cells holding max and min value该函数假定您想要获取指向具有最大值和最小值的单元格的指针

void MinMax(const size_t rows, const size_t cols, const double (*V)[cols], const double **minp, const double **maxp) 
{
    *minp = &V[0][0];
    *maxp = &V[0][0];
    for (size_t row = 0; row < rows; row++) 
    {
        for (size_t col = 0; col < cols; col++) 
        {
            *minp = V[row][col] < **minp ? &V[row][col] : *minp;
            *maxp = V[row][col] > **maxp ? &V[row][col] : *maxp;
        }
    }
}

VLAs are optional feature but will be not soon :) VLA 是可选功能,但不会很快 :)

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

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