我正在努力确保我理解这里隐藏的假设是什么。
这里的代码给出了正确的结果。
#include <stdio.h>
#include <stdlib.h>
struct branch
{
char flag; //value
struct branch *l; //left child
struct branch *r; //right child
};
struct branch c={'c',NULL,NULL};
struct branch e={'e',NULL,NULL};
struct branch f={'f',NULL,NULL};
struct branch b={'b',&c,NULL};
struct branch d={'d',&e,&f};
struct branch a={'a',&b,&d};
void preorder(struct branch* t)
{
printf(&t->flag); //Seems ugly and errorprone
if(t->l) preorder(t->l);
if(t->r) preorder(t->r);
}
int main()
{
preorder(&a);
}
预期输出为abcdef
有人可以证实我的怀疑,这只能起作用,因为有两件事:
char
)未使用的字节直到n字节边界为零。我没有看到printf正常工作的其他解释,因为它期望零终止char []。
此外,做这样的事情是明智的(在单目标嵌入式代码情况之外,优化可能超过可读性和可移植性问题),即。这些假设或多或少普遍存在吗?
第一周间歇性地弄乱C,所以我很绿。
答案 0 :(得分:2)
你可以自己证明1和2(我使用x64,这就是为什么所有8bytes都在结构中对齐)
objdump ./main -s -j .data
Contents of section .data:
601030 00000000 00000000 00000000 00000000 ................
601040 63000000 00000000 00000000 00000000 c...............
601050 00000000 00000000 00000000 00000000 ................
601060 65000000 00000000 00000000 00000000 e...............
601070 00000000 00000000 00000000 00000000 ................
601080 66000000 00000000 00000000 00000000 f...............
601090 00000000 00000000 00000000 00000000 ................
6010a0 62000000 00000000 40106000 00000000 b.......@.`.....
6010b0 00000000 00000000 00000000 00000000 ................
6010c0 64000000 00000000 60106000 00000000 d.......`.`.....
6010d0 80106000 00000000 00000000 00000000 ..`.............
6010e0 61000000 00000000 a0106000 00000000 a.........`.....
6010f0 c0106000 00000000 ..`.....
答案 1 :(得分:2)
要验证您的假设,您可以使用调试器或使用某些printf在运行时检查代码。
例如,使用:
char *ptr=(char *)&t;
printf("%02X %02X %02X %02X\n",ptr[0],ptr[1],ptr[2],ptr[3]);
事实上,您确定的假设通常是正确的,但您不能依赖它们。我绝对会说那个
printf(&t->flag);
显然是错误的,因为它依赖于standard.tt
无法保证的假设