首页 > 解决方案 > C-将矩阵传递给没有非常量列值的函数

问题描述

我想将矩阵传递给 C 中的函数。如果我想使矩阵的维数为非常数(例如,让用户通过键盘插入 NxM 维数),我对此没有任何问题。但是,当我尝试将其传递给函数时,我遇到了一些问题:

- 必须在具有矩阵作为参数的函数的标题中指定列数。如果我省略这个值,我会得到:

错误:数组类型的元素类型不完整'int []'void trasposeMatrix(int M [] [],int n,int m)esercizi.c:282:25:注意:将'M'声明为多维数组必须有界限除第一个维度外的所有维度

使用此功能:

void trasposeMatrix(int M[][],int n,int m)
{
    int temp=0;
    int M2[n][m];

    printf("La matrice prima della trasposizione è: \n");
    printMatrix(M,3,3);

    for (int i=0;i<n;i++)
    {
        for (int j=0;j<m;j++)
        {
            M2[i][j]=M[j][i];
        }
    }

    printf("La matrice dopo la trasposizione è: \n");
    printMatrix(M2,3,3);
}

用这个电话:

trasposeMatrix(M,3,3);

- 这个值必须是常数,否则如果我把一个参数作为值放在那些括号中,我会得到这个错误:

esercizi.c:在顶层:esercizi.c:282:29:错误:“m”未在此处声明(不在函数中) void trasposeMatrix(int M[][m],int n,int m)

使用相同的调用和此代码:

void trasposeMatrix(int M[][m],int n,int m)
{
    int temp=0;
    int M2[n][m];

    printf("La matrice prima della trasposizione è: \n");
    printMatrix(M,3,3);

    for (int i=0;i<n;i++)
    {
        for (int j=0;j<m;j++)
        {
            M2[i][j]=M[j][i];
        }
    }

    printf("La matrice dopo la trasposizione è: \n");
    printMatrix(M2,3,3);
}

这可以通过使用常量来指定矩阵维度来“避免”。但是我不喜欢这种“约束”。最后,如果我通过函数打印矩阵怎么办:如果维度是可变的,我应该在函数头中写什么?我编写的用于打印矩阵的函数适用于 3x3 矩阵,但对于 2x2 矩阵和 3x4 该怎么办。也许你明白了

注意:这种事情不会发生在我只写一个标题的数组中: void printArray(int a[], int dimension){}这有效。我不知道为什么。也许是他的发明者决定的 C 的设计行为,但我希望不是因为太乏味

注意 2::) 我使用 linux mint 和 gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 但使用 VS for Win10 我什至不能将变量作为数组的维度:(

很抱歉,很长的消息,但我希望能得到答复。谢谢阅读

标签: cmatrixmultidimensional-array

解决方案


在函数调用中的数组之前传递数组维度。此功能已添加到 C99(因此在 C11 和 C18 中);它不是标准 C++ 的一部分。这意味着有些编译器仍然不支持该符号。

你有:

void trasposeMatrix(int M[][m],int n,int m)
{

你需要:

void trasposeMatrix(int n, int m, int M[n][m])
{

也许:

void trasposeMatrix(int n, int m, int M[][m])
{

但我认为指定两个维度的先前版本的意图更清楚。

在函数声明中(例如,在标题中),您可以使用定义符号(其中extern是可选的,有时会引起争议——有些人不喜欢它,有些人喜欢它,比如我):

extern void trasposeMatrix(int n, int m, int M[n][m]);

或者你可以偏心并使用:

extern void trasposeMatrix(int n, int m, int M[*][*]);

这告诉编译器矩阵的维度将在运行时确定,但不指示它们来自哪里。我更喜欢“定义副本”版本,因为意图更清晰。您不能*在函数定义中使用该符号。

如果您想了解“全部内容”,您可以阅读标准——C11 §6.7.6.2 数组声明符和§6.7.6.2 函数声明符(包括原型) ——但该语言很难解析。


推荐阅读