处理二维数组时,例如你需要经常访问元素的矩阵。直接的方法是通过两个嵌套循环:
for( int i=0; i < n; ++i ) {
for( int j=0; j < m; ++j ) {
// do something with data[i][j]
}
}
这段代码原则经常在整个代码中反复复制。你是如何解决这个问题的?我认为解决这个问题的唯一方法是使用带函数指针的访问者函数,对吗?
编辑:为了更具建设性,我们假设你有矩阵类型typedef double** Matrix;
。
对于C ++,这可以通过这种方式解决:Loop over matrix elements applying variable function
答案 0 :(得分:3)
第一份工作:考虑将data
重新表示为代表矩阵的struct
,或者,如果没有,则为简单的typedef
。我假设你做了前者。
&#34; // do something with data[i][j]
&#34;可以是函数(一个foo
说),它将i
,j
和指向矩阵struct
的指针作为参数。
然后你只需要一个执行循环的函数:该函数将函数指针指向适当的foo
和矩阵struct
指针。
然后,您的工作就是根据您的要求实施各种foo
。
不要为此使用宏:它们使调试变得困难,特别是如果它们引入了i
和j
这样的硬编码变量名称。
答案 1 :(得分:0)
感谢Bathsheba提供的提示,我终于提出了涉及功能指针的解决方案,我对此并不满意。主要问题是创建可能需要其他参数的特定功能。
注意:感谢joop,我们需要一个额外的函数调用,宏解决方案可能会省略它。
例如,这样的访问者重置具有给定值的所有矩阵元素。另一个访问者可能使用一组参数修改元素,或者甚至不需要单个参数。所以基本上我面对的是关于vistor函数类型的灵活定义的问题。
BTW:在C ++中,这可以通过std::bind
或templates
来解决。
嵌套函数:
嵌套函数是GCC扩展名,例如不适用于Clang。尽管如此,这是代码示例:
typedef double** Matrix;
typedef void (*MatrixElementVisitor) ( double* element );
void visitMatrixElements( Matrix m, size_t rows, size_t cols, MatrixElementVisitor fn ) {
for( size_t i = 0; i < rows; ++i ) {
for( size_t j = 0; j < cols; ++j ){
fn( &m[i][j] );
}
}
}
void filM( Matrix m, size_t rows, size_t cols, double val ) {
void fill( double *element ) {
*element = val;
}
visitMatrixElements( m, rows, cols, fill );
}
Variadic功能:
typedef double** Matrix;
typedef void (*MatrixElementVisitor) ( double* element, va_list args );
void visitMatrixElements( Matrix m, size_t rows, size_t cols, MatrixElementVisitor fn, ... ) {
va_list args,copy;
va_start( args, fn );
for( size_t i = 0; i < rows; ++i ) {
for( size_t j = 0; j < cols; ++j ){
va_copy( copy, args );
fn( &m[i][j], copy );
va_end( copy );
}
}
va_end( args );
}
void fill( double *element, va_list args ) {
*element = va_arg( args, double );
}
void filM( Matrix m, size_t rows, size_t cols, double val ) {
visitMatrixElements( m, rows, cols, fill, val );
}
无效指针:
typedef double** Matrix;
typedef void (*MatrixElementVisitor) ( double* element, void *args );
void visitMatrixElements( Matrix m, size_t rows, size_t cols, MatrixElementVisitor fn, void *args ) {
if( m ) {
for( size_t i = 0; i < rows; ++i ) {
if( m[i] ) {
for( size_t j = 0; j < cols; ++j ){
fn( &m[i][j], args );
}
}
}
}
}
void fill( double* element, void *args ) {
if( !args ) {
return;
}
*element = *((double*)args);
}
void filM( Matrix m, size_t rows, size_t cols, double val ) {
visitMatrixElements( m, rows, cols, fill, &val );
}
也许存在其他方式,我想使用静态函数变量初始化访问者函数,也涉及可变函数。
感谢您的反馈。