将2D数组传递给相应的指针参数有什么问题?

时间:2015-04-16 05:37:58

标签: c clang c99

我前几天在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进行投射可解决警告问题。

现在我的问题是

  • 我错误地将2D双数组转换为双指针?
  • 为什么它非法有效?
  • 将n维任意大小的数组传递给函数的正确方法是什么?

编辑:这对我来说很清楚:Accesing a 2D array using a single pointer

所以我应该使用double[x*y]代替double[x][y]我认为。但是将double[]投射到double*是否合法?

1 个答案:

答案 0 :(得分:2)

我认为你做的事情没有错。你的代码只缺少一个明确的演员表,可以摆脱警告,表明你的作业是故意的。

您可以通过指向其元素的指针访问一维数组,并递归应用,可以通过指向原子元素的指针访问n维矩阵。

C保证了它们的连续内存布局。这种模式很常见。实际上,传递数组很难或不可能做到不同,因为C存储的信息很少(与C#相反)。因此,矩阵衰减到指向其第一个元素的指针(在您的情况下是第一个一维数组),可以安全地将其转换为第一个元素的地址,即double。它们都共享相同的数字地址。

指针类型转换的典型问题是现代优化编译器的别名问题(编译器可以假设您不通过除char *之外的不相关类型的指针访问内存),但标准草案1570中有明确的豁免,我有,相提并论6.5.7,我认为适用于此:

  

一个对象[在矩阵中为双精度型,-ps]的存储值只能由左值访问   具有以下类型之一的表达式:

     

- 与对象的有效类型兼容的类型[将是一个解除引用的双指针,-ps]   [...]

     

- 汇总[例如数组,-ps]   [...]类型包括其中的上述类型之一   成员(包括,递归地,子集合或成员)   包含union)[这将是你的矩阵变量,最终包含双精度数,-ps]

     

[...]