Dzięki Batszebie za udzielenie wskazówek, w końcu wymyśliłem rozwiązania dotyczące wskaźników funkcyjnych, z którymi nie jestem pewien. Głównym problemem jest tworzenie konkretnych funkcji, które mogą wymagać dodatkowych parametrów.
Uwaga: Dzięki Joop potrzebujemy więc dodatkowego wywołania funkcji, które można pominąć przy pomocy rozwiązania makro.
Na przykład taki użytkownik resetuje wszystkie elementy macierzy o danej wartości. Inny użytkownik może modyfikować elementy za pomocą zestawu parametrów lub nawet nie musi mieć jednego parametru. Więc w zasadzie mam do czynienia z pytaniem o elastyczną definicję typu funkcji vistor.
Przy okazji: W języku C++ można to rozwiązać za pomocą std::bind
lub z templates
.
zagnieżdżone funkcje:
funkcje zagnieżdżone są rozszerzeniem GCC, a na przykład niedostępne z Clangiem.Niemniej jednak tutaj jest przykład kodu:
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);
}
o zmiennej liczbie argumentów funkcje:
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);
}
nieważne wskaźnik:
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);
}
Być może istnieją inne sposoby, myślę o użyciu funkcji statycznej zmienne do inicjalizacji funkcji odwiedzającej, również obejmujące funkcje wariancji.
Dziękujemy za opinię.
Można utworzyć makro, które wygeneruje te pętle. – Crozin
Tak, w takim przypadku można użyć funkcji lub makra. –
Makro najprawdopodobniej byłoby niechlujne (nieoczywiste dla czytelnika) do wywołania lub utworzyłoby widmowe ukryte 'i' i' j' vars (również nieoczywiste dla czytelnika), Jeśli utworzysz ukryte vary, oni również nie można zagnieździć. – DaveRandom