我前几天在C大学里做了一些矩阵计算,我开始使用5x5矩阵,所以我把它硬编码到源代码中。这是一个二维的二维数组,如:
/**
* This is the probability-matrix for reaching from any profile
* to another by randomly selecting a friend from the friendlist.
*/
static const double F[5][5] = {
/* P , F , L , A , S */
/* Peter */ {0 , 0.5 , 0.5 , 0 , 0 },
/* Franz */ {1.0 , 0 , 0 , 0 , 0 },
/* Lisa */ {0 , 1/3.0, 0 , 1/3.0, 1/3.0},
/* Anna */ {0 , 0 , 0 , 0 , 1 },
/* Sepp */ {0 , 0.5 , 0.5 , 0 , 0 }
};
我希望我的函数不被修复以在5乘5矩阵上运行,所以我总是将行数和/或列数传递给函数。这迫使我不要使用double [][X]
语法,因为它不能完全“变量”,而是使用double*
作为函数参数。
inline size_t matrix_get(int rows, int i, int j);
inline void matrix_print(double* m, int rows, int cols);
inline void matrix_copy(double* d, const double* s, int rows, int cols);
void matrix_multiply(
int m, int n, int l,
const double* a, const double* b, double* d);
但是当我通过double*
时调用接受double [5][5]
的函数时,我总是会收到此警告。
fuenf_freunde.c:138:17: warning: incompatible pointer types passing 'double [5][5]' to parameter of
type 'double *' [-Wincompatible-pointer-types]
matrix_print( R, 5, 5);
^
fuenf_freunde.c:54:27: note: passing argument to parameter 'm' here
void matrix_print(double* m, int rows, int cols)
^
使用(double*) F
进行投射可解决警告问题。
现在我的问题是
编辑:这对我来说很清楚:Accesing a 2D array using a single pointer
所以我应该使用double[x*y]
代替double[x][y]
我认为。但是将double[]
投射到double*
是否合法?
答案 0 :(得分:2)
我认为你做的事情没有错。你的代码只缺少一个明确的演员表,可以摆脱警告,表明你的作业是故意的。
您可以通过指向其元素的指针访问一维数组,并递归应用,可以通过指向原子元素的指针访问n维矩阵。
C保证了它们的连续内存布局。这种模式很常见。实际上,传递数组很难或不可能做到不同,因为C存储的信息很少(与C#相反)。因此,矩阵衰减到指向其第一个元素的指针(在您的情况下是第一个一维数组),可以安全地将其转换为其第一个元素的地址,即double。它们都共享相同的数字地址。
指针类型转换的典型问题是现代优化编译器的别名问题(编译器可以假设您不通过除char *之外的不相关类型的指针访问内存),但标准草案1570中有明确的豁免,我有,相提并论6.5.7,我认为适用于此:
一个对象[在矩阵中为双精度型,-ps]的存储值只能由左值访问 具有以下类型之一的表达式:
- 与对象的有效类型兼容的类型[将是一个解除引用的双指针,-ps] [...]
- 汇总[例如数组,-ps] [...]类型包括其中的上述类型之一 成员(包括,递归地,子集合或成员) 包含union)[这将是你的矩阵变量,最终包含双精度数,-ps]
[...]