Dank Bathsheba, um Hinweise zu geben, habe ich schließlich Lösungen mit Funktionszeigern entwickelt, mit denen ich nicht vertraut bin. Das Hauptproblem ist die Erstellung der spezifischen Funktionen, die zusätzliche Parameter benötigen könnten.
Hinweis: Dank Joop benötigen wir daher einen zusätzlichen Funktionsaufruf, der bei einer Makrolösung entfallen kann.
Zum Beispiel setzt ein solcher Besucher alle Matrixelemente mit einem gegebenen Wert zurück. Ein anderer Besucher kann die Elemente mit einer Reihe von Parametern modifizieren oder braucht nicht einmal einen einzigen Parameter. Im Grunde stelle ich mich der Frage nach einer flexiblen Definition des Funktionstyps "vistor".
BTW: In C++ kann dies entweder mit std::bind
oder mit templates
gelöst werden.
Nested Funktionen:
verschachtelte Funktionen sind eine Erweiterung GCC und z.B. Nicht verfügbar mit Clang.Dennoch ist hier das Codebeispiel:
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);
}
Variadische Funktionen:
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);
}
void-Zeiger:
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);
}
Vielleicht andere Möglichkeiten gibt es, glaube ich statische Funktion des Verwendens Variablen für die Initialisierung der Besucherfunktion, auch mit variadischen Funktionen.
Vielen Dank für Ihr Feedback.
Sie könnten ein Makro erstellen, das diese Schleifen generiert. – Crozin
Ja, Sie könnten in diesen Fällen Funktion oder Makro verwenden. –
Ein Makro wäre wahrscheinlich entweder chaotisch (nicht offensichtlich für den Leser) zu rufen oder würde Phantom versteckte "i" und "j" vars (auch nicht offensichtlich für den Leser) erstellen, Wenn Sie die versteckten vars erstellen, sie auch konnte nicht verschachtelt werden. – DaveRandom