#c #function #binary-tree #generic-programming
#c #функция #двоичное дерево #generic-программирование
Вопрос:
Я работаю над общими бинарными деревьями поиска, и мне трудно понять, как работает передача функции в качестве параметра / аргумента в C. Я хочу рассказать моим родовым по британскому летнему времени, что он должен использовать compare_doubles (), когда требуется сравнение.
Как это возможно, чтобы создать указатель на функцию где-то в моем коде, когда я создаю пустой по британскому летнему времени в createBST() ?
С учетом этого по британскому летнему времени.ч. :
#include <stddef.h>
#include <stdbool.h>
typedef struct tree_t BinarySearchTree;
/* ------------------------------------------------------------------------- *
* Creates an empty BST.
* ARGUMENT
* comparison_fn_t A comparison function
* BinarySearchTree bst = newBST(amp;compare_doubles);
* ------------------------------------------------------------------------- */
BinarySearchTree* createBST(int comparison_fn_t(const void *, const void *));
bool insertInBST(BinarySearchTree* bst, const void* key, const void* value);
По британскому летнему времени.с :
#include <stddef.h>
#include <stdlib.h>
#include "BinarySearchTree.h"
struct tree_t {
const void *key;
const void *value;
const void *leftChild;
const void *rightChild;
//const void *comparison_fn_t; //try to have it as an argument 1st try
};
//int (*compare) (const void *, const void *); //try to save it for later 2nd try
BinarySearchTree* newBST(int comparison_fn_t(const void*, const void*)) {
BinarySearchTree *binarySearchTree = malloc(sizeof(BinarySearchTree));
if (!binarySearchTree)
return NULL;
binarySearchTree->value = NULL;
binarySearchTree->key = NULL;
binarySearchTree->leftChild = NULL;
binarySearchTree->rightChild = NULL;
compare = amp;comparison_fn_t; //1st try
//binarySearchTree->comparison_fn_t = comparison_fn_t //2nd try
return binarySearchTree;
}
bool insertInBST(BinarySearchTree* bst, const void* key, const void* value) {
//other code
int val = (*compare) (key, bst->key); //1st try
int val = bst->comparison_fn_t... //2nd try
}
В моем Main.c :
int compare_doubles(const void *a, const void *b) {
const double *a_ = (const double*) a;
const double *b_ = (const double*) b;
return (*a_ > *b_) - (*a_ < *b_);
}
BinarySearchTree *searchTree= createBST(amp;compare_doubles);
insertInBST(searchTree, key, value);
Комментарии:
1. Создать псевдоним типа, используя
typedef
для типа функции, и использовать его как любой другой тип при объявлении и определении переменных?
Ответ №1:
Просто используйте то же определение указателя функции в структуре:
struct tree_t {
const void *key;
const void *value;
const void *leftChild;
const void *rightChild;
int (*comparison_fn)(const void*, const void*);
};
BinarySearchTree* newBST(int (*comparison_fn)(const void*, const void*)) {
...
// assign the fn pointer here
binarySearchTree->comparison_fn = comparison_fn;
return binarySearchTree;
}
Чтобы упростить синтаксис, вы можете использовать typedef:
typedef int (*BinaryComparison)(const void*, const void*);
struct tree_t {
const void *key;
const void *value;
const void *leftChild;
const void *rightChild;
BinaryComparison comparison_fn;
};
BinarySearchTree* newBST(BinaryComparison comparison_fn) {
BinarySearchTree* binarySearchTree = malloc(sizeof *binarySearchTree);
binarySearchTree->comparison_fn = comparison_fn;
return binarySearchTree;
}
Комментарии:
1. именно то, что я искал, мой синтаксис был неправильным
Ответ №2:
Для начала неясно, почему члены данных leftChild
и rightChild
имеют тип const void *
вместо типа struct tree_t *
.
struct tree_t {
const void *key;
const void *value;
const void *leftChild;
const void *rightChild;
//const void *comparison_fn_t; //try to have it as an argument 1st try
};
Также нет особого смысла хранить указатель на функцию в качестве элемента данных этой структуры, потому что в этом случае этот элемент данных будет дублироваться в каждом узле двоичного дерева.
Вы могли бы объявить еще одну структуру, например
struct node_t {
const void *key;
void *value;
struct node_t *leftChild;
struct Node_t *rightChild;
};
и
struct tree_t {
struct node_t *head;
int ( *comparison )( const void *, const void * );
};
typedef struct tree_t BinarySearchTree;
В этом случае вы могли бы создать объект типа struct tree_t
следующим образом
BinarySearchTree * createBST( int comparison( const void *, const void * ) )
{
BinarySearchTree *tree = malloc( sizeof( *tree ) );
if ( tree != NULL )
{
tree->head = NULL;
tree->comparison = comparison;
}
return tree;
}
int compare_doubles(const void *a, const void *b) {
const double *a_ = (const double*) a;
const double *b_ = (const double*) b;
return (*a_ > *b_) - (*a_ < *b_);
}
int main( void )
{
BinarySearchTree *tree = createBST( compare_doubles );
//...
}
Комментарии:
1. спасибо за предоставление этого очень чистого примера, я упростил свой