Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在LIST_FOREACH()宏中添加的_node变量是否仅用于代码可读性?_C_Macros_Readability_Function Definition - Fatal编程技术网

在LIST_FOREACH()宏中添加的_node变量是否仅用于代码可读性?

在LIST_FOREACH()宏中添加的_node变量是否仅用于代码可读性?,c,macros,readability,function-definition,C,Macros,Readability,Function Definition,在一个宏中,我注意到有一个变量\u node,它似乎是多余的,因为它可以被删除并完全替换为V 它唯一单独使用的时间是在for循环的测试表达式中 \u节点甚至有一个下划线前缀,这意味着它是一个仅供内部使用的变量 此宏中是否存在\u节点,以便于人们阅读 宏 示例用法 void List_destroy(List * list) { LIST_FOREACH(list, first, next, cur) { if (cur->prev){ f

在一个宏中,我注意到有一个变量
\u node
,它似乎是多余的,因为它可以被删除并完全替换为V

它唯一单独使用的时间是在for循环的测试表达式中

\u节点
甚至有一个下划线前缀,这意味着它是一个仅供内部使用的变量

此宏中是否存在
\u节点
,以便于人们阅读


示例用法

void List_destroy(List * list)
{
    LIST_FOREACH(list, first, next, cur) { 
        if (cur->prev){
            free(cur->prev);
        }
    }
    free(list->last);
    free(list);
}
创建Typedefs

typedef struct ListNode {
    struct ListNode *next;
    struct ListNode *prev;
    void *value; 
} ListNode;

typedef struct List { 
    int count; 
    ListNode *first;
    ListNode *last;
} List;
我认为
\u节点
变量的作用是使循环体可以自由修改
V
,而不影响迭代。我不会这样写的;我会用

#define LIST_FOREACH(L, S, M, V) \
    for(ListNode *V = (L)->S; V; V = V->M)

因为我认为不使用变量声明污染外部范围,以及允许嵌套
LIST\u FOREACH
,更为重要。但是我可以看到单独的
V
\u节点的参数,宏使代码无法读取。这是一种非常糟糕的编程风格

如果要替换此函数中的宏

void List_destroy(List * list)
{
    LIST_FOREACH(list, first, next, cur) { 
        if (cur->prev){
            free(cur->prev);
        }
    }
    free(list->last);
    free(list);
}
对于它的扩展,您将获得

void List_destroy(List * list)
{
    ListNode *_node = NULL;
    ListNode *cur = NULL
    
    for( cur = _node = list->first; _node != NULL; cur = _node = _node->next )
    {
        if (cur->prev){
            free(cur->prev);
        }
    }
    free(list->last);
    free(list);
}
可以立即看到变量
cur
\u node
应该在使用它们的for循环中声明。此外,变量
\u节点
只是冗余的

该函数可以按以下方式重写

void List_destroy(List * list)
{
    for( ListNode *cur = list->first; cur != NULL; cur = cur->next )
    {
        free( cur->prev );
    }
    
    free( list->last );
    free( list );
}
但是,像这样定义函数更简单、更正确

void List_destroy( List *list )
{
    while ( list->first != NULL )
    {
        ListNode *tmp = list->first;
        list->first = lits->first->next;
        free(  tmp );
    }

    list->last = NULL;    
    list->count = 0;
}
该函数不应释放指向列表本身。例如,用户可以定义如下列表

List list = { .count = 0, .first = NULL, .last = NULL };
也就是说,不必动态分配
struct List
类型的对象

此外,还完全不清楚数据成员
值是否指向动态分配的对象,以及为什么不释放该对象

因此,一般来说,函数应该如下所示

void List_destroy( List *list )
{
    while ( list->first != NULL )
    {
        ListNode *tmp = list->first;
        list->first = lits->first->next;
        free( tmp->value );
        free(  tmp );
    }

    list->last = NULL;    
    list->count = 0;
}

因此,在我看来,您发现了一个非常糟糕的代码,不值得讨论。:/p>宏使代码无法读取。:)我相信
\u node
是此范围内的保留标识符,同样。固定名称
\u node
使得无法在同一块中使用此宏两次,因为
\u node
将被重新定义。删除
\u节点
变量允许在同一块中使用宏两次,但不能使用相同的
V
参数,因为相应的变量将被重新定义。更改宏以定义
for
循环范围内的变量可以修复这些问题。
void List_destroy( List *list )
{
    while ( list->first != NULL )
    {
        ListNode *tmp = list->first;
        list->first = lits->first->next;
        free( tmp->value );
        free(  tmp );
    }

    list->last = NULL;    
    list->count = 0;
}