关于C#:这段代码如何打印404?

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编译器上编译,如gcc -std=c11 -pedantic-errors

1)main必须在托管系统上返回int。2)putchar()必须有#include 。3)不能在函数外写分号。

在修复了这些初学者级别的错误并删除了所有多余的错误之后,我们只剩下以下内容:

1
2
3
#include <stdio.h>
#define v putchar
int main(){v(4+v(v(52)-4));return 0;}

这围绕着putchar返回所写的字符:

1

  • 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

这将v定义为putchar()函数。它打印一个字符并返回它。

1
# define print(x)

这将print(x)定义为"无"(因此print(202*2)表示"无")。

1
main(){v(4+v(v(52)-4));return 0;}/*

这可以改写为:

1
2
3
4
5
main()
{
  putchar(4 + putchar(putchar(52) - 4));
  return 0;
}

它使用ASCII代码打印"4"(代码52)、"0"(代码52-4=38),然后再次打印"4",所以是"404"。

该行以一个/*结尾,开始一个注释,然后继续执行以下两行:

1
2
#>+++++++4+[>++++++<-]>
++++.----.++++.*/

下面的行是空的,但这有点棘手,因为exit()在行本身之后被定义为空的。这是因为C预处理器在编译之前运行。

1
print(202*2);exit();

下面的行将exit()定义为空,用于上面的行。

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:

1
main(){putchar(4+putchar(putchar(52)-4));return 0;};exit();

Your standard main function is declared there, and exit is also
declared as a function with an implicit return type of int (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 is 4); then we subtract 4 and output 0; then we add
4 to output 4 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:

1
2
3
4
int main() {
    putchar(4 + putchar(putchar('4') - 4));
    return 0;
}

As for the putchar declaration, it is defined by the standard to
return it's input, like realloc. First, this program prints a 4,
then takes the ASCII value (52), subtracts 4 (48), prints that
(ASCII 0), adds 4 (52), prints that (4), then finally
terminates. This results in the following output:

1
404

As 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 be int.


您已经将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值。