我声明了一个用 C 实现的链表,如下所示:
struct node_List {
int i;
char * name;
struct node_List* next;
};
typedef struct node_List nodeList;
然后我将全局列表头声明为:
nodeList list; // head of the list - does not contain relevant data
最后,我有一个函数 id(char * s)
,其中字符串 s
作为唯一的参数。
nodeType id(char *s)
{
nodeType *p; // another List type
if ((p = malloc(sizeof(nodeType))) == NULL) {
// error: out of memory;
}
nodeList * node = &list;
// printf(" ");
while (node->next != NULL){
node = node->next;
if (strcmp(node->name, s) == 0){
// printf(" ");
// assign node to an attribute in p
return p;
}
}
// error: not found;
}
问题是,当我运行这个程序并调用 foo("somestring")
时,程序会执行 error: not find
部分并中止执行,尽管字符串somestring
在列表中。
我尝试通过插入一些 printf()
来执行相同的程序以进行调试,并且它工作得很好,只是它在输出中打印了附加字符。
每次我添加一些打印行时都会发生这种情况,例如如果我取消注释上面示例中编写的两个 printf() (其中之一或两者,我会得到相同的成功结果)。但如果调用 printf 时不带参数或使用空字符串 ""
,则它不起作用。
我不知道发生了什么,我仔细检查了列表创建和填充函数,我完全确定它们工作正常。我尝试更改 while
中断条件,但这也不起作用。我在 Linux(使用 gcc)和 Windows(使用 CodeBlocks 编辑器的集成编译器)上观察到类似的行为
printf 指令如何对程序产生如此大的影响?
编辑:此代码是用 Yacc 编写的语法分析器的一部分。完整代码可以在下面找到。这是一篇很长的文章,而且还没有完成,但是上面的代码已经过测试,并且可以按说明工作。
最佳答案
在查看提供的源代码时,探索链表的算法有两种方式在 while 循环比较中丢失节点。
方式 1 - 仅从列表的第二个节点开始。
在比较之前放置 node = node->next;
将强制第一个比较为 &(list)->next
而不是 &(list )
。
To start from the first node, simply place
node = node->next;
after the comparison.
方式 2 - 永远不会结束到列表的最后一个节点。
在 while 条件中使用 (node->next != NULL)
将在比较最后一个节点之前强制退出循环 => node->next = NULL;
.
To end by the last node, simply change the while condition to
(node != NULL)
.
解决方案:
while (node != NULL){ // end from the last node
if (strcmp(node->name, s) == 0){
// printf(" ");
// assign node to an attribute in p
return p;
}
node = node->next; // explore link after comparison
}
关于c - 遍历C指针列表: weird printf behaviour,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42075855/