|
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函数 |
|
|
|
/* 没有调试, 也许原来的可以改写成如下形式 */
#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); } |
|
我经过测试,i["123"]等价于i<3,对于原来的程序,我不知道编译器为什么要做这种处理,但确实如此。
|
|
我觉得你的改法过于麻烦,如果想打印出一个字母,为什么一定要用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'));} |
|
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 */ |