关于ioccc程序1984年anonymous.c的分析

zhangze 2003-09-13 06:57:17
源程序如下:
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);}
分析:
上述代码等同于:
int i;main(){for(;i["12345678901234"];read('-'-'-',i+++"hello,world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}
分析步骤1:i["]<i;++i){--i;}"]
这个的计算结果为引号里面的字符串的长度,所以我进行了第二步分析:
int i;main(){for(;i["12345678901234"];printf(i+++"hello,world!\n"));}
程序执行了14行,这很正常,因为程序里面包含循环,我们将循环结束的条件设置的是14,所以我们必须在printf中包含步长;i+++"hello,world!\n"实现了之一步骤,这样一来,和程序的结果不符合,也就是我们的替代出现了一些失误,这是因为我们设置了一个14次的循环,所以我们打印了14行,而由于i的值每次都在改变,printf在处理类似printf(n+"fdsaf")(n为整数)的时候,会打印从n+1个字符开始的剩余字符串,所以我们如果要完整的替换,只需要将hello,world!\n字符串一个一个输出就可以了;我没有找到write函数的用法,不过从第3个参数i/i来看,应该是一个一个输出字符串,所以程序使用了自定义了一个read函数
...全文
213 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
dximg 2003-09-15
  • 打赏
  • 举报
回复
to zhangze(喆) :
因为原来的程序用的是write,所以我当然用write输出字符了。
另对于你的“i["123"]等价于i<3”,我其实改写的程序中已有
说明,只是你没有看仔细。
解释如下:
s[i] 等价于 *(s + i)
同样 i[s] 等价于 *(i + s)
也就是说任何s[i]的形式都可写成i[s]的形式。/* 当然 s[i] 要有意义 */
你的 while (i["123"]) 等价于 while ("123"[i]) 即为:
while ("123"[i] != '\0) 当然是循环3次 /* 这里的i 为 0 */
即“123”字符窜的长度。
若你还是觉得不清楚可以令 char *s = "123";
你说 while (s[i] != '\0) 循环几次? /* 这里的i 为 0 */
zhangze 2003-09-14
  • 打赏
  • 举报
回复
我觉得你的改法过于麻烦,如果想打印出一个字母,为什么一定要用write函数呢?这是我的改法:
int i;
main()
{for(;i<14;printf("%c",(++i)==1?'h':i==2?'e':i==3?'l':i==4?'l':i==5?'o':i==6?',':i==7?'w':i==8?'w':i==9?'o':i==10?'r':i==11?'l':i==12?'d':i==13?'!':'\n'));}
zhangze 2003-09-14
  • 打赏
  • 举报
回复
我经过测试,i["123"]等价于i<3,对于原来的程序,我不知道编译器为什么要做这种处理,但确实如此。
dximg 2003-09-13
  • 打赏
  • 举报
回复
/* 没有调试, 也许原来的可以改写成如下形式 */

#include <sys/types.h>

extern ssize_t write(int, char *, size_t);
static void read(int, char *, int);

static int i = 0;
static const char *s1 = "]<i;++i){--i;}"; /* s1 与 s2 等长 */
static const char *s2 = "hello, world!\n";

int
main()
{
for (; s1[i] != '\0'; read(0, s2 + i, 1))
++i;

return 0;
}

static void
read(int fd, char *buf, int n)
{
/* 因为read调用时fd为0即标准输入并且n为1, 所以
* 下面等价于 (void)write(1, buf, 1); 其中第一
* 个1 表示标准输出 */
(void)write((fd / n) + n, buf - fd, 1);
}

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧