我是C的新手,我急切地想知道这段代码的工作原理是什么?
int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hell\
o, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}
Run Code Online (Sandbox Code Playgroud)
来源可以在这里找到:http://www.ioccc.org/1984/anonymous.c
以下是代码附带的提示:
不光彩的提及:匿名
作者太尴尬了他/她可以写这样的垃圾,所以我答应保护他们的身份.我要说的是,这个程序的作者与C编程语言有着众所周知的联系.该计划是古老的"Hello,world"计划的独特变体.阅读的内容可能就像写一样!版权所有(c)1984,Landon Curt Noll.版权所有.允许个人,教育或非营利性使用,前提是此版权和通知全部包含在内并保持不变.所有其他用途必须事先得到Landon Curt Noll和Larry Bassel的书面许可.
R S*_*ahu 13
当你有一个混淆的代码时,你需要清理物理布局,添加一些空格,添加必要的缩进,然后编译代码.编译器的警告会告诉你很多关于程序隐藏的东西.
First Cut Simplification - 添加空格
int i;
main()
{
for( ; i["]<i;++i){--i;}"];
read('-'-'-', i+++"hell\o, world!\n", '/'/'/'));
}
read(j,i,p)
{
write(j/p+p,i---j,i/i);
}
Run Code Online (Sandbox Code Playgroud)
使用编译程序时gcc -Wall,我收到以下警告:
soc.c:2:1: warning: return type defaults to ‘int’ [enabled by default]
main()
^
soc.c: In function ‘main’:
soc.c:4:4: warning: implicit declaration of function ‘read’ [-Wimplicit-function-declaration]
for( ; i["]<i;++i){--i;}"]; read('-'-'-', i+++"hell\o, world!\n", '/'/'/'));
^
soc.c:4:50: warning: unknown escape sequence: '\o' [enabled by default]
for( ; i["]<i;++i){--i;}"]; read('-'-'-', i+++"hell\o, world!\n", '/'/'/'));
^
soc.c: At top level:
soc.c:7:1: warning: return type defaults to ‘int’ [enabled by default]
read(j,i,p)
^
soc.c: In function ‘read’:
soc.c:7:1: warning: type of ‘j’ defaults to ‘int’ [enabled by default]
soc.c:7:1: warning: type of ‘i’ defaults to ‘int’ [enabled by default]
soc.c:7:1: warning: type of ‘p’ defaults to ‘int’ [enabled by default]
soc.c:9:4: warning: implicit declaration of function ‘write’ [-Wimplicit-function-declaration]
write(j/p+p,i---j,i/i);
^
soc.c:9:17: warning: operation on ‘i’ may be undefined [-Wsequence-point]
write(j/p+p,i---j,i/i);
^
soc.c:9:17: warning: operation on ‘i’ may be undefined [-Wsequence-point]
soc.c:10:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
Run Code Online (Sandbox Code Playgroud)
第二次简化 - 非混淆
根据上述警告,该程序可以无混淆地:
int i;
void read(int j, char* i, int p);
void write(int j, char* i, int p);
int main()
{
for( ; i["]<i;++i){--i;}"];
read('-'-'-', , '/'/'/'));
return 0;
}
void read(int j, char* i, int p)
{
write(j/p+p, (i--) - j, 1);
}
Run Code Online (Sandbox Code Playgroud)
上面的版本没有编译器警告并产生相同的输出.
第三次简化简化 - 不要混淆更多
该表达式i["]<i;++i){--i;}"]用于运行循环14次.就那么简单.它可以简化为i < 14.
'-'-'-'是0.
'/'/'/'是1.
i++ + "hello, world!\n"是相同s + i++,其中s可以char const* s = "hello, world!\n";
该for环可以被简化为:
char const* s = "hello, world!\n";
for( ; i < 14; read(0, s+i++, 1));
Run Code Online (Sandbox Code Playgroud)
由于jin 的值read始终为零,因此read可以将实现简化为:
void read(int j, char* i, int p)
{
write(0, (i--), 1);
}
Run Code Online (Sandbox Code Playgroud)
由于副作用不会改变函数的运算,因此表达式(i--)可以简化为i自递减以来.换句话说,上述功能是:
void read(int j, char* i, int p)
{
write(0, i, 1);
}
Run Code Online (Sandbox Code Playgroud)
当我们意识到参数的值j总是0并且参数的值p总是1,我们可以for将main函数中的循环更改为:
for( ; i < 14; i++)
{
write(0, s+i, 1);
}
Run Code Online (Sandbox Code Playgroud)
因此,整个程序可以简化为:
void write(int j, char const* i, int p);
int main()
{
int i = 0;
char const* s = "hello, world!\n";
for( ; i < 14; i++ )
{
write(0, s+i, 1);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
第四次削减简化 - 让它变得微不足道
以上版本具有硬编码14.那是中的字符数s.因此,通过将程序更改为以下内容,可以使程序变得微不足道:
void write(int j, char const* i, int p);
int main()
{
write(0, "hello, world!\n", 14);
return 0;
}
Run Code Online (Sandbox Code Playgroud)