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

时间:2023-02-27 14:17:33

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

 【练习1-1】

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

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

这里我们来看点别的:

1、ELF

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

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

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

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

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

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

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

     看到什么了,一堆的^A^A和^@, 我现在对这些不感兴趣,感兴趣的是前面的四个字符:  【C语言学习趣事】_29_《C程序设计语言》_Secnod_Edition_习题

  我们看到了: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

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

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

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

2、链接的库

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

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

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

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

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

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

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

3、GNU

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

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

4、Hello world 字符串

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

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

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

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

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

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

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

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

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

6、readelf程序

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

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

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

7、 objdump

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

输出结果如下:

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

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

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

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

     

【练习1-2】

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

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

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

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

  这是什么原因呢?   噜啦啦

【练习1-3】

【练习1-4】

【练习1-5】

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