How does this code print 404?
我从堆栈溢出的404找不到错误页复制了下面的代码。
1 2 3 4 5 6 7 | # define v putchar # define print(x) main(){v(4+v(v(52)-4));return 0;}/* #>+++++++4+[>++++++<-]> ++++.----.++++.*/ print(202*2);exit(); #define/*>.@*/exit() |
上面的代码编译好并在控制台上打印404。我以为报表打印(202*2);负责打印404,但我不对,因为更改此报表中的数字也会打印404。
有人能帮我理解这个代码以及它是如何打印404的吗?
我将发布编译输出以供参考,因为有评论说此代码无法编译。包含上述代码的文件是test.c。
gcc Test.c -o Test
Test.c:3:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
main(){v(4+v(v(52)-4));return 0;}/* ^ Test.c: In function ‘main’:
Test.c:1:12: warning: implicit declaration of function ‘putchar’
[-Wimplicit-function-declaration] # define v putchar
^ Test.c:3:8: note: in expansion of macro ‘v’ main(){v(4+v(v(52)-4));return 0;}/*
^ Test.c: At top level: Test.c:6:14: warning: data definition has no type or storage class print(202*2);exit();
^ Test.c:6:14: warning: type defaults to ‘int’ in declaration of ‘exit’ [-Wimplicit-int] Test.c:6:14: warning:
conflicting types for built-in function ‘exit’./Test
404
号
代码不能在标准C编译器上编译,如
1)main必须在托管系统上返回int。2)putchar()必须有
在修复了这些初学者级别的错误并删除了所有多余的错误之后,我们只剩下以下内容:
1 2 3 | #include <stdio.h> #define v putchar int main(){v(4+v(v(52)-4));return 0;} |
这围绕着putchar返回所写的字符:
。
- 52是用于
'4' 的ASCII码。打印4. - 52-4=48,用于
0 的ASCII码。打印0。 - 4+48=52。再次打印4。
就这样。就迷惑的尝试而言,非常惨淡。
适当的、符合标准的模糊处理应该是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include <stdio.h> #include <iso646.h> ??=define not_found_404(a,b,c,d,e,f,g,h,i,j)a%:%:b%:%:c%:%:d%:%:e%:%:f(\ (g%:%:h%:%:i%:%:j<::>)<%'$'+d##o%:%:e not"good",g??=??=ompl ??-- -0163l,\ ((void)(0xBAD bito##b not"bad"),not"ugly")??>,(g%:%:h%:%:i%:%:j??(??)){\ ((c%:%:d%:%:e)- -not"lost") <:??=a??) -??-??- '<',\ ((c%:%:d%:%:e)- -not"found") <:??=b??) -??-??- 'B',\ ((c%:%:d%:%:e)- -not 0xDEADC0DE) <:??=c??) -??-??- '5',\ ((c%:%:d%:%:e)- -6##6##6 xo##b- -6##6##6)%>) int main() { not_found_404(p,r,i,n,t,f,c,h,a,r); } |
1 | # define v putchar |
这将
1 | # define print(x) |
号
这将
1 | main(){v(4+v(v(52)-4));return 0;}/* |
这可以改写为:
。
它使用ASCII代码打印"4"(代码52)、"0"(代码52-4=38),然后再次打印"4",所以是"404"。
该行以一个
1 2 | #>+++++++4+[>++++++<-]> ++++.----.++++.*/ |
下面的行是空的,但这有点棘手,因为
1 |
。
下面的行将
1 | #define/*>.@*/exit() |
。
不能将元问题用作dupe,因此明目张胆地从mso答案复制。
因为它被标记为C并提到"已编译",所以只需提取它的C部分。
学分:马克·拉沙科夫是《多语言文字》的原作者。
The C code is fairly easy to read, but even easier if you run it
through a preprocessor:Your standard
main function is declared there, andexit is also
declared as a function with an implicit return type ofint (exit
is effectively ignored).
putchar was used because you don't need any#include to use it;
you give it an integer argument and it puts the corresponding ASCII
character to stdout and returns the same value you gave it. So, we
put 52 (which is4 ); then we subtract 4 and output0 ; then we add
4 to output4 again.
号
另外,还有一点Elboration,来自[Cole Johnson's](https://meta.stackoverflow.com/users/1350209/cole-johnson)答案
Disregarding all of that, when we reformat the code a bit, and replace
52 with its ASCII equivalent ('4' ), we get:As for the
putchar declaration, it is defined by the standard to
return it's input, likerealloc . First, this program prints a4 ,
then takes the ASCII value (52 ), subtracts 4 (48 ), prints that
(ASCII0 ), adds 4 (52 ), prints that (4 ), then finally
terminates. This results in the following output:
1 404As for this polyglot being valid C++, unfortunately, it is not as
C++ requires an explicit return type for functions. This program takes advantage of the fact that C requires functions without an
explicit return type to beint .
号
您已经将v定义为putchar(),它接受要打印的char的ascii代码,并返回已打印char的ascii值。程序的执行将从主程序开始,如下所示第一个V(52)将打印4并返回52第二个V(52-4)将打印0(48是0的ASCII值)并返回48最后它将调用v(48+4)将打印4,因为52是"4"的ASCII值。