C传递矩阵以使函数不具有非恒定的列值

时间:2018-11-16 22:05:28

标签: c matrix multidimensional-array

我想将矩阵传递给C语言中的函数。如果我想使矩阵的尺寸不恒定(例如,让用户通过键盘插入NxM尺寸),那么我就没有问题。但是,当我尝试将此传递给函数时,会遇到一些问题:

-必须在以矩阵为参数的函数标题中指定列数。如果我忽略此值,我得到:

  

错误:数组类型的元素类型“ int []”不完整   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 但对于Win10的VS,我什至不能将变量作为数组的维数:(

对于很长的信息我感到很抱歉,但我希望得到答案。感谢您的阅读

3 个答案:

答案 0 :(得分:1)

在函数调用中的数组之前传递数组尺寸。此功能已添加到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 Array declarators§6.7.6.2 Function declarators (including prototypes),但是该语言很难解析。

答案 1 :(得分:0)

“将“ M”声明为多维数组必须对除第一个维之外的所有维都具有边界”

这告诉您需要在第一个括号中指定一个值:

M [] <-可以为空[x] <-不能为空,并且必须为常数。

如果您不想获得“约束”,请使用malloc和free在运行时分配动态内存。

答案 2 :(得分:0)

  

数组类型的元素类型为'int []'

要声明一个数组,编译器需要知道数组元素的大小。

想象int arr[2][];数组元素有多大?编译器需要知道要在&arr[0]&arr[1]之间“跳”多少字节。如何增加指向arr的指针?

想象int (*arr)[2];这是一个2整数数组的指针。在&arr[0]&arr[1]之间是2个整数:恰好是arr[0][0]arr[0][1]。因此,编译器知道&arr[1]位于位置(uintptr_t)(void*)&arr[0] + 2 * sizeof(int)

可变长度数组声明(int M[])和所有数组声明(int M[5])“已调整”(“等于”)指向内部类型(int *M)的指针功能参数列表(see C11 6.7.6.3p7)。这意味着每次您写void func(int a[500*1000*320100])都和void func(int *a)相同。

您无法声明int *(a[]);指向数组的指针,该数组指向未知数量的元素。数组元素必须是完整类型。因此,编译器知道要为它们保留多少内存。

  

错误:此处未声明“ m”

想象一个这样的函数:

int main() {
  int m[i];
  int i = 5;
}

您将获得i undeclared here。好吧,现在想象一个像这样的函数:

int func(
  int m[i],
  int i
) {}

您将得到相同的错误,但在功能参数列表中。一样,变量必须在使用前声明。