在 LIST_FOREACH() 宏中添加 _node 变量只是为了代码的可读性吗?
Is _node variable in LIST_FOREACH() macro added only for code readability?
在一个宏中,我注意到有一个变量 _node
似乎是多余的,因为它可以被删除并完全替换为 V.
它唯一一次单独使用是在 for 循环中的测试表达式中。
_node
甚至有一个下划线前缀,这意味着它是一个仅供内部使用的变量。
_node
出现在这个宏中是为了让人们更容易阅读吗?
宏
#define LIST_FOREACH(L, S, M, V)\
ListNode *_node = NULL;\
ListNode *V = NULL;\
for(V = _node = L->S; _node != NULL; V = _node = _node->M)
用法示例
void List_destroy(List * list)
{
LIST_FOREACH(list, first, next, cur) {
if (cur->prev){
free(cur->prev);
}
}
free(list->last);
free(list);
}
已创建 Typedef
typedef struct ListNode {
struct ListNode *next;
struct ListNode *prev;
void *value;
} ListNode;
typedef struct List {
int count;
ListNode *first;
ListNode *last;
} List;
我认为 _node
变量的要点是使循环主体可以自由修改 V
而不会影响迭代。我不会这样写的;我会改用
#define LIST_FOREACH(L, S, M, V) \
for(ListNode *V = (L)->S; V; V = V->M)
因为我认为不要用变量声明污染外部作用域,并允许 LIST_FOREACH
嵌套,这些更为重要。但是我可以看到单独的 V
和 _node
.
的论点
宏使代码不可读。这是一种非常糟糕的编程风格。
如果要替换此函数中的宏
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
和_node
应该在使用它们的for循环中声明。此外,变量 _node
只是多余的。
函数可以改写成下面的方式
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
类型的对象不必动态分配。
另外,完全不清楚数据成员value
是否指向一个动态分配的对象,以及为什么它没有被释放。
所以一般来说函数应该是这样的
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;
}
所以在我看来,您在某个地方发现了一段非常糟糕的代码,不值得讨论。:)
在一个宏中,我注意到有一个变量 _node
似乎是多余的,因为它可以被删除并完全替换为 V.
它唯一一次单独使用是在 for 循环中的测试表达式中。
_node
甚至有一个下划线前缀,这意味着它是一个仅供内部使用的变量。
_node
出现在这个宏中是为了让人们更容易阅读吗?
宏
#define LIST_FOREACH(L, S, M, V)\
ListNode *_node = NULL;\
ListNode *V = NULL;\
for(V = _node = L->S; _node != NULL; V = _node = _node->M)
用法示例
void List_destroy(List * list)
{
LIST_FOREACH(list, first, next, cur) {
if (cur->prev){
free(cur->prev);
}
}
free(list->last);
free(list);
}
已创建 Typedef
typedef struct ListNode {
struct ListNode *next;
struct ListNode *prev;
void *value;
} ListNode;
typedef struct List {
int count;
ListNode *first;
ListNode *last;
} List;
我认为 _node
变量的要点是使循环主体可以自由修改 V
而不会影响迭代。我不会这样写的;我会改用
#define LIST_FOREACH(L, S, M, V) \
for(ListNode *V = (L)->S; V; V = V->M)
因为我认为不要用变量声明污染外部作用域,并允许 LIST_FOREACH
嵌套,这些更为重要。但是我可以看到单独的 V
和 _node
.
宏使代码不可读。这是一种非常糟糕的编程风格。
如果要替换此函数中的宏
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
和_node
应该在使用它们的for循环中声明。此外,变量 _node
只是多余的。
函数可以改写成下面的方式
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
类型的对象不必动态分配。
另外,完全不清楚数据成员value
是否指向一个动态分配的对象,以及为什么它没有被释放。
所以一般来说函数应该是这样的
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;
}
所以在我看来,您在某个地方发现了一段非常糟糕的代码,不值得讨论。:)