标题:第一次接触混乱代码,求大神指导解释
只看楼主
pangshch
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:2
帖 子:443
专家分:1966
注 册:2013-4-9
得分:0 
以下是引用Knocker在2014-3-6 21:52:59的发言:

你说得都没有问题,能不能按原来程序的逻辑把它简化一下?就是规范书写
您问的这两个问题我都回答不出, 我只知道它是这样的, 我不知道它为什么会是这样,知其然而不知其所以然. 如果可以, 望不吝赐教.
2014-03-07 10:03
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
回复 11楼 pangshch
很简单呀,这是 K&D 语法,不是7楼啥扯的什么C98(C根本就没有什么C98,只有 K&D(非标准)、C89、C90(非标准)、C99、C11 ),而且这还是 K&D语法中的最古老版本。

原代码是
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);}

有几个问题,第一个用到的外部函数write,却无定义。这是因为K&D时代的编译器默认包含一些常用函数,即编译器默认#include了一些头文件。
第二个问题,main和read没有明确写明返回类型。(理由在第三点讲)
第三个问题,read参数没有明确写明参数类型。这是因为最早的C语言,只有一种类型,即现在的int类型,所以它不需要写任何类型,因为只有一种类型嘛。
也就是在K&D版本中,read(j,i,p)等同于int read( int j, int i, int p ) (其实i是const char*类型,但C语言并不检查这一点)
我之所以未将第二个问题和第三个问题合并,是因为C89是允许第二点的。
另外,还有一个细节就是使用 read 之前未声明,这是因为K&D库有个read函数,同时某些编译器对本编译模块的函数作 强链接 处理。也就是它利用库本身的声明,但不使用库本身的定义。

现在,将原代码排版一下,并使之尽量符合现在C标准,得:
程序代码:
int read( int j, int i, int p)
{
    write(j/p+p,i---j,i/i);
    return 0;
}

int i;
int main()
{
    for( ; i["]<i;++i){--i;}"]; read('-'-'-',i+++"hello, world!\n",'/'/'/') );
}

再将 '-'-'-' 换成 0,'/'/'/' 换成 1,得:
程序代码:
int read( int j, char* i, int p)
{
    write(1,i,1);
    return 0;
}

int i;
int main()
{
    for(;i["]<i;++i){--i;}"];read(0,i+++"hello, world!\n",1));
}

write(1,i,1)是个POSIX函数,并非C函数,因此我用 putchar(*i) 替代之;将全局变量int i变成局部变量需要初始化为0;再将for的第三点移动到循环体内,得:
程序代码:
#include <stdio.h>

int read( char* i )
{
    putchar( *i );
    return 0;
}

int main()
{
    for( int i=0; i["]<i;++i){--i;}"]; )
    {
        read(0,i+++"hello, world!\n",1);
    }
}

自此,已经比较清爽了,但还不够,i++移动到for中,read函数直接在调用处展开,得:
程序代码:
#include <stdio.h>

int main()
{
    for( int i=0; i["]<i;++i){--i;}"]; ++i )
    {
        putchar( *("hello, world!\n"+i) );
    }
}

 *("hello, world!\n"+i) 其实就是  "hello, world!\n"[i]; 同时,i["]<i;++i){--i;}"] 等同于 "]<i;++i){--i;}"[i],简化代码得:
程序代码:
#include <stdio.h>

int main()
{
    for( int i=0; "]<i;++i){--i;}"[i]; ++i )
        putchar( "hello, world!\n"[i] );
}

这两行代码,一眼就可以看出"]<i;++i){--i;}"[i]只是用于限定下面的"hello, world!\n"[i]打印次数,因此只要保证字符串长度一致就可以了,保证长度一致最简单的方法就是用同一个字符串呗。得:
程序代码:
#include <stdio.h>

int main()
{
    for( int i=0; "hello, world!\n"[i]; ++i )
        putchar( "hello, world!\n"[i] );
}

这段代码就是我在二楼贴的代码。
混乱代码竞赛是很有意思,从中能学到很多技巧,但楼主给的这段混乱代码是毫无任何美感或惊奇的。
收到的鲜花
  • pangshch2014-03-07 11:41 送鲜花  5朵   附言:原来是这样, 我懂了. 抱歉, 你之前的回复我 ...
2014-03-07 11:18
pangshch
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:2
帖 子:443
专家分:1966
注 册:2013-4-9
得分:0 
原来是这样, 抱歉, 你之前的回复我当时没赞同, 不过现在赞同了..谢谢.
2014-03-07 11:43
Knocker
Rank: 8Rank: 8
等 级:贵宾
威 望:47
帖 子:10454
专家分:603
注 册:2004-6-1
得分:0 
12楼的这下看懂了,我到是出了个大糗 C89 说成C98

九洲方除百尺冰,映秀又遭蛮牛耕。汽笛嘶鸣国旗半,哀伤尽处是重生。     -老K
治国就是治吏。礼义廉耻,国之四维。四维不张,国之不国。   -毛泽东
2014-03-07 15:34



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-428101-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.022886 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved