这段代码如何打印404?

我从Stack Overflow的404 Not Found Error Page中复制了以下代码。

# 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.c:3:1:warning:return type defaults to'int'[-Wimplicit-int] main(){v(4 + v(v(52)-4)); return 0;} / * ^ Test .c:在函数'main'中:Test.c:1:12:warning:隐式声明函数'putchar'[-Wimplicit-function-declaration] #define v putchar ^ Test.c:3:8:note:in扩展宏'v'main(){v(4 + v(v(52)-4)); return 0;} / * ^ Test.c:在顶层:Test.c:6:14:warning:数据定义没有打印类型或存储类(202 * 2); exit(); ^ Test.c:6:14:warning:在'exit'声明中输入default'''[-Wimplicit-int] Test.c:6:14:warning:内置函数'exit'

。/测试

404


# define v putchar

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

# define print(x)

这将print(x)定义为nothing(因此print(202*2)意味着什么)

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

这可以被重写为:

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

它使用ASCII码打印'4'(代码52),'0'(代码52-4 = 38)和再次'4',所以'404'。

该行以/*开始注释结束,接下来的两行继续:

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

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

print(202*2);exit();

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

#define/*>.@*/exit()

不能使用meta-question作为伪装,所以公然抄袭MSO的答案。

由于这是标记C并提到“编译”,所以只是提取其中的C部分。

积分:Mark Rushakoff是多语种的原作者。

C代码相当容易阅读,但如果通过预处理器运行它,则更容易:

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

你的标准main函数在那里被声明,并且exit也被声明为一个带有隐式返回类型int的函数( exit被有效地忽略)。

putchar被使用,因为你不需要任何#include来使用它; 你给它一个整数参数,它将相应的ASCII字符放到标准输出中,并返回你给它的相同值。 所以,我们把52(这是4 ); 然后我们减去4并输出0 ; 然后我们再次将4添加到输出4

此外,来自[Cole Johnson](https://meta.stackoverflow.com/users/1350209/cole-johnson)的更多协作答案

无视所有这些,当我们重新格式化代码时,用其等同的ASCII( '4' )代替52 ,我们得到:

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

至于putchar声明,它由标准定义为返回它的输入,如realloc 。 首先,这个程序打印一个4 ,然后取ASCII值( 52 ),减4( 48 ),打印(ASCII 0 ),加4( 52 ),打印出( 4 ),最后终止。 这导致以下输出:

404

至于这个多边形是有效的C ++ ,不幸的是,它不像C ++要求函数显式返回类型。 这个程序利用了这样一个事实,即C需要没有显式返回类型的函数为int


代码无法在标准C编译器上编译,例如gcc -std=c11 -pedantic-errors

1)main必须在宿主系统上返回int。
2)putchar()必须包含#include <stdio.h>
3)你不能在函数外面写分号。

在修复了这些初学者级别的错误并删除了除了创建编译器错误之外没有做任何事情的所有多余的绒毛之后,我们留下了这个:

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

这围绕putchar返回写入的字符:

putchar(4+putchar(putchar(52)-4));
  • 52是'4' ASCII码。 打印4。
  • 52 - 4 = 48,ASCII码为0 。 打印0。
  • 4 + 48 = 52。再次打印4。
  • 就是这样。 就模糊尝试而言,它非常暗淡。


    正确的,符合标准的混淆可能看起来像这样:

    #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);  
    }
    
    链接地址: http://www.djcxy.com/p/73605.html

    上一篇: How does this code print 404?

    下一篇: GCC C compiler warning "warning: control reaches..."