c - 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 我什至不能将变量作为数组的维度:(
很抱歉,很长的消息,但我希望能得到答复。谢谢阅读
解决方案
在函数调用中的数组之前传递数组维度。此功能已添加到 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 函数声明符(包括原型) ——但该语言很难解析。
推荐阅读
- laravel-backpack - 在事件表列表中显示项目名称
- java - ProtoBuf 的媒体类型
- scala - 更改 spark _temporary 目录路径以避免删除拼花
- php - Woo-commerce 购物车验证类别
- c - 在 C 中定义和初始化一个字符串数组
- java - 将 SwipeView 放在片段中?
- bash - 如何从 Nginx 运行 bash 脚本
- python - 防止 docker-compose 在使用构建的图像时重新安装 requirements.txt
- hangouts-chat - 如何通过 API 创建带有视频会议链接的环聊聊天消息
- javascript - 运行节点文件参数时切断双引号