【C语言学习趣事】_29_《C程序设计语言》_Secnod_Edition_习题

本文通过编译并分析HelloWorld程序,介绍了ELF文件格式、链接库的作用、GNU工具集的应用,以及如何使用readelf和objdump工具进行深入的二进制文件分析。

前天收到了K&R的中文版的书,期盼已久的书啊,心情有点小激动。

 【练习1-1】

在“Hello world”程序中制造混乱。  

      这个我倒不是很想做,因为我自己不是个制造混乱的人,虽然有时在写代码的时候不能由自己控制,我倒是希望能在代码中寻找 ladybug,嘻嘻。

这里我们来看点别的:

1、ELF

     我们在Linux下面编译好后Hello world程序后,运行的过程很简单;但是我一直想探探,这里到底发生了什么。如果你对机器码比较精通,那么

od可以帮你解决这个问题,可问题是我不明白,因此我需要“曲线救国”。

    我是这么编译的:  gcc -Wall   hello.c   -o  hello

    很幸运,没有错误,我能够运行我的程序,但是我不想看自己运行的结果,我这么做了:

less  hello, 结果Linux告诉我这个文件可能是二进制文件,问我是否依然打开,这里当然要打开了,我不打开找你Linux哥哥干嘛。

输出结果大家可以自己看看,我们先来看一行输出:

     看到什么了,一堆的^A^A和^@, 我现在对这些不感兴趣,感兴趣的是前面的四个字符:  

我们看到了:ELF,这个是啥意思呢?我们这里看一段引自维基百科的内容容:

      http://zh.wikipedia.org/wiki/%E5%8F%AF%E5%9F%B7%E8%A1%8C%E8%88%87%E5%8F%AF%E9%8F%88%E6%8E%A5%E6%A0%BC%E5%BC%8F

                           

       就是说,ELF表示这个文件一个可以连接和可执行的格式,也就是说这是一个binary格式的文件,等会我们还可以单独编译一个函数试试。

       至于ELF格式,在连接上有简要的说明。

2、链接的库

我们知道,在汇编器将.asm文件翻译成.o文件后,还需ld将.o文件链接成最终的可执行文件,这里就需要用到预编译的库文件,那么我们如何

查看文件链接了那些库文件呢?别着急,虽然唐僧被老鼠精抓了,好歹他俩成不了亲,听我慢慢道来,我们可以看到下面这样一段输出:

        

咿呀,看到了没,亲们,这里指出了我们链接时用到的库文件了,/lib/ld-linux.so.2, 大家可以搜索一下,在你的计算机里面(如果你安装的时候

选择了安装开发工具的话)应该能找到这个文件。

这个文件是一个动态连接器文件,在链接的时候需要用到,从 ld 这个前缀可以看出,他与链接器ld相关。其实这里面还提示了很多其他的库文件。

      

3、GNU

整个输出里面还有三个字母比较醒目,那就是:GNU, 没想到吧,在你编译生成的目标文件里面居然还有GNU三个字母。

      

4、Hello world 字符串

     在整个文件,还有一个比较醒目的地方:Hello world,这里也能看到

                     

这个地方就是我们将要输出的字符

5、系统信息,编译器信息,文件节区信息

       这里我们可以清楚的看到: .text、 .data 、 .bss、 .comment这些节区关键字的信息,

      我们可以看看我的GCC的版本信息,是否和这里提示的一样。

很明显,这里提示的信息与我们利用less查看的hello文件一致。

6、readelf程序

其实Linux不但提供了二进制形式的二进制文件查看工具od,还提供了一个更可视化的查看工具,readelf。我们可以看看readelf与less查看的内容有啥不一样的

     这里可以看到,里面的输出内容与less命令输出的有很多相似的地方,如果你对readelf比较熟悉的话,那么结合less 命令,是不是能更好的理解呢?

7、 objdump

如果需要查看更加具体的内容,那么我们还可以利用objdump工具,例如需要查看所有segment的内容,可以这样: objdump  -x  hello

输出结果如下:

     

可以看出,objdump提供的信息比readelf工具更详细。如果你对elf文件的分析感兴趣可以到这个链接看看:http://wenku.baidu.com/view/5ca21b28915f804d2b16c164.html

     

【练习1-2】

在printf函数使用  ‘\c’, 看看输出结果是什么,你说呢? 会输出啥玩意

      

    我们看到,printf输出的时候,并没有按照我们通常理解的那样,字符串字面值原样输出,这个很多人都是这么认为的,实际? 这个在最初【C语言学习趣事】的时候,我曾经说过这个问题

我敢猜测,我们很多人在学习的时候,你的老师说过这样话: printf函数的第一个参数的内容,如果不是用格式控制和转义序列则原样输出。想想,你的老师是否这么说过。

这是什么原因呢?   噜啦啦

【练习1-3】

【练习1-4】

【练习1-5】

这三个练习,需要注意的是整数的除法。

   

 


<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
(1)普通用户端(全平台) 音乐播放核心体验: 个性化首页:基于 “听歌历史 + 收藏偏好” 展示 “推荐歌单(每日 30 首)、新歌速递、相似曲风推荐”,支持按 “场景(通勤 / 学习 / 运动)” 切换推荐维度。 播放页功能:支持 “无损音质切换、倍速播放(0.5x-2.0x)、定时关闭、歌词逐句滚动”,提供 “沉浸式全屏模式”(隐藏冗余控件,突出歌词与专辑封面)。 多端同步:自动同步 “播放进度、收藏列表、歌单” 至所有登录设备(如手机暂停后,电脑端打开可继续播放)。 音乐发现与管理: 智能搜索:支持 “歌曲名 / 歌手 / 歌词片段” 搜索,提供 “模糊匹配(如输入‘晴天’联想‘周杰伦 - 晴天’)、热门搜索词推荐”,结果按 “热度 / 匹配度” 排序。 歌单管理:创建 “公开 / 私有 / 加密” 歌单,支持 “批量添加歌曲、拖拽排序、一键分享到社交平台”,系统自动生成 “歌单封面(基于歌曲风格配色)”。 音乐分类浏览:按 “曲风(流行 / 摇滚 / 古典)、语言(国语 / 英语 / 日语)、年代(80 后经典 / 2023 新歌)” 分层浏览,每个分类页展示 “TOP50 榜单”。 社交互动功能: 动态广场:查看 “关注的用户 / 音乐人发布的动态(如‘分享新歌感受’)、好友正在听的歌曲”,支持 “点赞 / 评论 / 转发”,可直接点击动态中的歌曲播放。 听歌排行:个人页展示 “本周听歌 TOP10、累计听歌时长”,平台定期生成 “全球 / 好友榜”(如 “好友中你本周听歌时长排名第 3”)。 音乐圈:加入 “特定曲风圈子(如‘古典音乐爱好者’)”,参与 “话题讨论(如‘你心中最经典的钢琴曲’)、线上歌单共创”。 (2)音乐人端(创作者中心) 作品管理: 音乐上传:支持 “无损音频(FLAC/WAV)+ 歌词文件(LRC)+ 专辑封面” 上传,填写 “歌曲信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值