我想将矩阵传递给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,我什至不能将变量作为数组的维数:(
对于很长的信息我感到很抱歉,但我希望得到答案。感谢您的阅读
答案 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
) {}
您将得到相同的错误,但在功能参数列表中。一样,变量必须在使用前声明。