我读过这个骗局:https://www.gnu.org/fun/jokes/unix-hoax.html
它包含一些混淆的C代码,即:
for(;P("\n"),R--;P("|"))for(e=C;e--;P("_"+(*u++/8)%2))P("| "+(*u/4)%2);
我添加了最低限度的代码以使其正常运行,并以此方式结束:
#include <stdio.h>
#define P(...) printf(__VA_ARGS__)
#define C (7)
int main(int argc, char *argv[])
{
auto R;
auto e;
auto *u;
R = 5;
for(;P("\n"),R--;P("|"))for(e=C;e--;P("_"+(*u++/8)%2))P("| "+(*u/4)%2);
}
在编译并检查它是否可以工作(并打印出一些东西)之后,我编写了一些不太混淆的代码:
#include <stdio.h>
#define C (7)
int main(int argc, char *argv[])
{
auto R;
auto e;
auto *u;
R = 5;
while(R) {
/* for1: param 2.1 */
printf("\n");
/* for1: param 2.2 */
R--;
for(e = C; e; ) {
/* for2: param 2 */
e--;
printf("| " + (*u / 4) % 2);
/* for2: param 3 */
printf("_" + (*u++ / 8) % 2);
}
/* for1: param 3 */
printf("|");
}
/* for1: param 2.1 */
printf("\n");
}
像这样编译后:$ gcc tst.c -o tst
我看到两个不同的输出(我想是未定义的行为):
$ ./tst
| _| _ _ | _| _ |
| | _ |
_ _ | _ | _|
_ | _ |
_ | | _ | |
$ ./tst
| _| _| | _| __|
| | _ | _ |
| | | _|
| _ |
| _ _|
现在到了要点:这到底是做什么的?
printf("| " + (*u / 4) % 2)
或更糟糕的是:
printf("_" + (*u++ / 8) % 2)
答案 0 :(得分:2)
u
未在原始代码或添加的内容中初始化。假定它具有适当的值,那么,如果*u
不是负数:
"| " + (*u / 4) % 2
是根据'|'
是0-3还是4-7以8为模的指针,指向字符' '
或*u
的指针。实际上,printf
被传递"| "
或" "
。因此,printf
将打印“ | ”或“”。
并且:
"_" + (*u++ / 8) % 2
是指向'_'
或空字符的指针,该指针根据递增之前*u
是0模还是7模8来终止字符串。因此,printf
将打印“ _”或不打印任何内容。
答案 1 :(得分:1)
printf("| " + (*u / 4) % 2)
它将根据(*u / 4) % 2
的值为0或1来写入(“ |” + 0)=“ |”或(“ |” + 1)=“”
表达式只返回“ |”的地址或该地址多1
与其他印刷品相似