首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >#ifndef (*destroy) (*match)

#ifndef (*destroy) (*match)
EN

Stack Overflow用户
提问于 2011-02-16 06:30:03
回答 2查看 488关注 0票数 1

谁能解释一下#indef,void (*destroy)(void *data)的定义?

代码语言:javascript
复制
int (*match)(const void *key1,const void *key2)

在以下内容中:

代码语言:javascript
复制
#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);

void *list_data(const ListElmt *element);

ListElmt *list_next(const ListElmt *element);
#endif
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-02-16 06:42:53

#ifndef指令是include guard的一部分,它是一段C代码,可以在几乎所有的头文件中找到,以防止多个包含。C头文件的一般结构是

代码语言:javascript
复制
#ifndef Some_Symbol
#define Some_Symbol

/* ... body of the header file ... */

#endif

这些以散列开头的行被称为预处理器指令,并指示预处理器在编译器开始将其转换为代码之前对其进行更改。#ifndef指令代表"IF Not DEFined“,是一种编译时if语句。上面代码的含义是

代码语言:javascript
复制
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;
}

(这不是有效的C语言,但它可以理解这一点)。

这种结构背后的思想是,如果你将同一个文件#include两次,那么第一次,因为编译器没有出现给定的符号,它会继续并包括头文件的内容。但是,在任何后续迭代中,编译器都会看到该符号,因此它不会尝试在第二次中放置相同的代码。

至于你的神秘台词

代码语言:javascript
复制
void (*destroy)(void *data);

这是一个函数指针,它指向一个接受void *并返回void的函数。例如,它可以指向函数

代码语言:javascript
复制
void FreeMyData(void *data);

代码语言:javascript
复制
void FreeMyStringData(void *data);

虽然不是

代码语言:javascript
复制
int printf(const char* fmtString, ...);

这个函数背后的直觉是,如果您在C中构建一个通用链表,那么当列表被回收时,列表需要知道应该如何处理列表中存储的元素。为了做到这一点,用户必须指定一个函数,指定如何完成这项工作。它存储在destroy指针中,以便在释放列表时,您可以执行以下操作:

代码语言:javascript
复制
myList->destroy(myUserData);

这允许列表作者确保正在清理内存,即使她不知道那里会有什么类型的数据。她可以假设用户将提供适当的清理代码,然后在列表清理中指定何时应该运行该清理代码。

希望这能有所帮助!

票数 1
EN

Stack Overflow用户

发布于 2011-02-16 06:37:57

#ifndef行是header guard的开始。这可以防止在同一上下文中包含两次报头。

void (*destroy)(void *data)定义了一个function pointer。这是一个指向以void*作为参数并返回void的函数的指针,该指针的名称为destroy

变量match也是一个函数指针。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5010286

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档