假设我有。
char c[500];
我具有为分配编写的以下功能: (基本上,它是一棵树,以不固定顺序排列,如果存在左节点,则在i位置的缓冲区中写入0(右为1,否则写入'\ 0'并打印缓冲区)。
void imprimer_codes (node *b, char *c, int i) {
assert(c);
if (!b) return;
if (est_feuille(b)) {
c[i] = '\0';
printf("%s:%c\n",c,b->symbol);
}
if (b->fg) {
c[i] = '0';
imprimer_codes(b->fg,c,i+1);
}
if (b->fd) {
c[i] = '1';
imprimer_codes(b->fd,c,i+1);
}
}
由于我递归使用它。我不明白该函数如何实际打印多个不同的缓冲区,因为缓冲区中有多个\ 0。
指向c [500]的指针是否已复制到堆栈存储器?这可能是我能找到的唯一解释。
答案 0 :(得分:0)
由于我递归使用它。我不明白该函数如何实际打印多个不同的缓冲区,因为缓冲区中有多个\ 0。
这很简单。例如,考虑一棵树
*
/ \
x ...
也就是说,左边有一片叶子,右边有一些子树。我们从
开始i = 0, c = []
您的算法先左移(仍然必须向右移),
i = 1, c = [0]
这是一片叶子,因此添加了空值,
i = 1, c = [0, \0]
并打印。该分支已经完成,因此可以回溯,我们有
i = 0, c = [0, \0]
请记住,i
是通过值传递的,但是c
是一个数组,并且数组是通过引用传递的。然后我们就对了,
i = 1, c = [0, 1]
,null消失了。
再一个示例,其中不覆盖null。考虑,
*
/ \
/ y
x
您向左走了两次,
i = 0, c = []
i = 1, c = [0]
i = 2, c = [0, 0]
然后添加null并打印
i = 2, c = [0, 0, \0]
因为在根只有一个正确的分支,所以它将回溯到该分支
i = 0, c = [0, 0, \0]
然后正确,
i = 1, c = [1, 0, \0]
这是一片叶子,所以我们将添加null并将其打印出来,
i = 1, c = [1, \0, \0]
我认为这足以了解正在发生的事情。
插入\0
之后的点将使您回溯到较小的i
,并从那里继续构建新字符串。因此,永远不会在当前\0
之前的位置放置i
。