100分,求C语言高手讲解此程序,只有四行代码。越详细越好,我是新手,谢谢!

main(a)
{
printf(a,34,a="main(a){printf(a,34,a=%c%s%c,34);}",34);
}
问题一:该程序的执行步骤是什么?第一步直到最后一步的详细过程。
问题二:main参数问题。
问题三:printf的参数问题。
此程序汇编代码如下,供大家参考:

首先是第一个问题执行步骤,这程序实际上执行的关键语句只有printf一句,printf首先读取参数,一共是四个参数a,34,a="main(a){printf(a,34,a=%c%s%c,34);}",34。
第一个参数a为打印的内容,因为后面第三个参数a="main(a){printf(a,34,a=%c%s%c,34);}"实际上同时也是一条赋值语句,将a的值设为后面的一串字符串,这里可以将第一个参数a代换为"main(a){printf(a,34,a=%c%s%c,34);}",同时一条赋值语句的值也为所赋予的值即后面的字符串,这样可以把这条printf语句看做

printf("main(a){printf(a,34,a=%c%s%c,34);}",34,"main(a){printf(a,34,a=%c%s%c,34);}",34);

这样之后可以看出现在此语句已经是很直白的标准的打印语句形式了,打印双引号中的内容,其中包含有%c%s%c三个参数,分别即后面的34,,"main(a){printf(a,34,a=%c%s%c,34);}",34。
%c是字符型,对照ASCII码可知34对应符号即双引号",%s是字符串,即后面的字符串,接着又是一个%c的字符双引号。打印的步骤为
1.首先打印main(a){printf(a,34,a=
2.然后打印参数%c,值是34,因此打印出双引号"
3.然后打印参数%s,参数是a="main(a){printf(a,34,a=%c%s%c,34);}",其值即等号后的"main(a){printf(a,34,a=%c%s%c,34);}",因此打印双引号内的内容,即main(a){printf(a,34,a=%c%s%c,34);}
4.然后打印%c,参数还是34,打印双引号"
5.最后是剩下的部分,34);}
拼接起来,最后打印的总结果就是
main(a){printf(a,34,a="main(a){printf(a,34,a=%c%s%c,34);}",34);}
即是程序代码本身。

你的第二个问题main的参数问题,参数中的那个a其实就是一个形式参数,在本程序中并没有实际意义,只是为了让程序正好打印出本身的加工而已。main函数的实际形式为
main(int argc,char *argv[]),argc为程序参数数量,argv为程序各个参数,其中argv[0]为程序名称,往后为输入的参数。这个因为与你提问的程序本身不产生影响,感兴趣可以额外看一看。

至于第三个问题printf参数问题,我在前面讲执行步骤的时候已经详细说过了。
最后这类打印自身的程序有个通称叫quine,有兴趣的话你可以搜索一下。

写了挺多字不容易,你觉得可以的话奖励就直接给了吧。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2012-09-25
首先a是一个整形。
main函数代参数的情况下是这样定义的。
main(int i,char *m[]);有几种情况。
1.main(int i)
2.main(int i,char *m[])
3.main(int 1,char *m[],char *n[])
//以上更改,因为我发现编译的时候报错。然后查了下发现的。
我们遇到的是第一种情况
其实当a被赋值指针的时候会报错,因为变量赋值不对称的。但是也是能用。如何使用不报错,后面会说。
然后调用函数的时候,都是先进行赋值运算。如:
fun(i=1); 是先赋值,使i等于1,然后调用fun函数。那么上面的函数可以简化为:
main(a)
{
a="main(a){printf(a,34,a=%c%s%c,34);}";
printf(a,34,a,34);
}

有TC的话,可以看出,这个程序和原来的程序的结果是一样的。

然后上面可以写成这样,看着明白:
main(a)
{
a="main(a){printf(a,34,a=%c%s%c,34);}";
printf("main(a){printf(a,34,a=%c%s%c,34);}",34,a,34);
}

然后就非常清晰了。34 以字符输出为:"。指针a指向的字符串以%s字符串输出。然后在输出:"
结果就是:main(a){printf(a,34,a="main(a){printf(a,34,a=%c%s%c,34);}",34);}

然后这里有个重点是a是int变量,这里被用作字符串指针来用,指针地址位数与int位数其实在TC中是一致的(远指针除外)。
想编译的时候不报错,仅仅需要一步强制转换:
main(a)
{
(char *)a="main(a){printf(a,34,a=%c%s%c,34);}";
printf(a,34,a,34);
getch();
}追问

你太厉害了!我居然明白了!分给你了!

追答

a在这个函数中其实是整形。main(a)的时候已经默认定义了。
然后类型不匹配,其实也是可以赋值的,只不过在TC中会警告而已。
如 :
int a;
a="123";
这样在TC中虽然语法错误,但是可以正常运行的,只不过整形a的值是123字符串的地址而已。
如:
int a;
(char *)a="123";
将a强制转换成字符串指针。这里就不会报错了。也就是说int 和char * 定义的变量的取值范围一样。其实不一样的位数也是可以强制转换的,只不过最高位会被丢弃

本回答被提问者采纳
第2个回答  2012-09-25
这是一个输出自身源代码的程序.
需要修改下main参数的定义才能在vc6中运行.另外要加上#include <stdio.h>
main(char* a)
{
printf(a,34,a="main(char* a){printf(a,34,a=%c%s%c,34);}",34);
}
具体执行步骤自己在vc中看看汇编代码吧.你可以理解为拿a代表的字符串放在printf第一个a处,然后%c%s%c带入相应的值
main参数a是一个字符指针,printf第一个参数需要,而第3个参数又同时初始化了他.
printf参数就更好理解了,第一个是格式字符串,后三个是字符串中3个%所要带入的值.printf("%c",34)正好是双引号.
第3个回答  2012-09-25
据我估计啊,这是递归调用main()函数,至于具体怎么调用呢,容我18年后再来讲解。
第4个回答  2012-09-25
汗,看的蛋疼乳酸。。。
相似回答