A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© wuqiong 金牌黑马   /  2018-5-16 17:23  /  653 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

今天在网上看到了一个C语言趣味小程序:打印自身代码。

程序代码如下:

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

main()

{

printf(s,34,s,34);

}

程序的运行结果如下: char*s="char*s=%c%s%c;main(){printf(s,34,s,34);}";main(){printf(s,34,s,34);}

输出结果和程序的源代码一样。是不是觉得这一段代码很神奇?让我们来分析一下这段“神奇”的代码。

首先我将源代码整理了一下,就变成了下面的这个样子:

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

第一行代码初始化一个字符串指针,指针指向了一个字符串常量的首地址。第四行代码调用printf函数。而就是这个printf函数输出了整个程序的源代码。

printf(s,34,s,34);

s在程序是什么呢?就是字符串 “char*s=%c%s%c;main(){printf(s,34,s,34);}” 的首地址。也就是说printf(s)就代表了printf(“char*s=%c%s%c;main() {printf(s,34,s,34);}”)。字符串里面有3个格式化输出的代码:%c %s %c。所以上面printf后面3个参数就是这几个格式化输出的值。

如果你调用

printf("%c",34)

程序将会打印出一个引号 ” 。

所以我们知道了这个打印自身的程序就是将程序的源代码保存在一个字符串中,然后在输出函数中打印这个字符串,由于源代码中char *s = 后面有引号和printf函数中的引号有冲突,不能直接输出,于是程序就通过printf函数的%c打印32打印出了引号。

整个程序的原理就是这样,关键点在字符串s中的%c%s%c。当然在我的C-Free中上面的代码无法编译成功。因为缺少头文件。于是我稍稍修改了一下源代码,成了下面这样:

#include char*s="#include char*s=%c%s%c;main(){printf(10,s,34,s,34);}"; main(){printf(s,10,34,s,34);}

看我关于换行符的处理,我没有直接输出”\n”,而是使用%c打印它的ascii值10。你想知道为什么吗?自己动手写代码吧。:)


3 个回复

倒序浏览
666666
回复 使用道具 举报
6666666
回复 使用道具 举报
奈斯
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马