#ifndef (*destroy) (*match)
Can anyone explain the definition of #indef , void (*destroy)(void *data)
int (*match)(const void *key1,const void *key2)
in the following:
#ifndef LIST_H
#define LIST_H
#include <stdio.h>
typedef struct _ListElmt{
void *data;
struct ListElmt *next;
} ListElmt;
typedef struct _List{
int size;
int (*match)(const void *key1, const void *key2);
void (*destroy)(void *data);
ListElmt *head;
ListElmt *tail;
} List;
void list_init(List *list, void (*destroy)(void *data));
void list_destroy(List *list);
int list_ins_next(List *list, ListElmt *element, const void *data);
int list_rem_next(List *list, ListElmt *element, void **data);
int list_size(const List *list);
ListElmt *list_head(const List *list);
ListElmt *list_tail(const List *list);
int list_is_head(const ListElmt *element);
int list_is_tail(const ListElmt *element开发者_StackOverflow中文版);
void *list_data(const ListElmt *element);
ListElmt *list_next(const ListElmt *element);
#endif
The #ifndef
line is the beginning of a header guard. This prevents a header from being included twice in the same context.
The line void (*destroy)(void *data)
defines a function pointer. This is a pointer to a function that takes a void*
as an argument and returns void
, and the name of the pointer is destroy
.
The variable match
is also a function pointer.
The #ifndef
directive is part of an include guard, a piece of C code found in virtually all header files that prevents multiple inclusion. The general structure of a C header file is
#ifndef Some_Symbol
#define Some_Symbol
/* ... body of the header file ... */
#endif
These lines starting with hashes are called preprocessor direectives and instruct the preprocessor to make changes to this code before the compiler begins translating it into code. The #ifndef
directive stands for "IF Not DEFined" and is sort of a compile-time if
statement. The meaning of the above code is
if (I haven't seen the symbol "Some_Symbol") {
Define the symbol "Some_Symbol", so now I have seen it;
Compile the body of the header file;
}
(This isn't valid C, but it gets the point across).
The idea behind this structure is that if you #include
the same file twice, then the first time, since the compiler hasn't seem the given symbol, it goes and includes the contents of the header. However, on any successive iteration, the compiler will have seen the symbol, and so it won't try putting the same code in a second time.
As for your mysterious line
void (*destroy)(void *data);
This is a function pointer that points to a function that takes in a void *
and returns void
. For example, it could point at the function
void FreeMyData(void *data);
or
void FreeMyStringData(void *data);
Though not
int printf(const char* fmtString, ...);
The intution behind this function is that if you're building a generic linked list in C, the list needs to know some way in which it should dispose of the elements stored in the list when the list is reclaimed. In order to do this, the user must specify a function specifying how this work is to be done. This is stored in the destroy
pointer so that when the list is being freed, you can do something like this:
myList->destroy(myUserData);
This allows the list author to ensure that memory is being cleaned up, even when she has no idea what sort of data will be there. She can just assume that the user will provide the proper cleanup code, and then just specify when in the list cleanup that cleanup code should be run.
Hope this helps!
精彩评论