高级C/C++编译技术(典藏版)
上QQ阅读APP看书,第一时间看更新

前言Preface

我花了相当长的时间才认识到,计算机编程艺术与烹饪艺术之间有着惊人的相似。

说到烹饪和编程的比较,我的脑海中首先浮现出来的是烹饪专家和程序员的工作目标非常相似:都是为了满足特定对象的需求。对一个厨师来说,他的服务对象是食客,他需要使用大量的食材,一方面满足人们的温饱与营养需求,另一方面则要让人们享受到美食带来的快乐。而对一个程序员来说,其服务对象是微处理器,程序员使用大量不同的程序来为其提供代码,不仅要让微处理器产生有意义的动作,还需要以最优的形式将代码交付给微处理器。

虽说这种对比看起来有些牵强而且过于简单,但我们会在本书中列出一些更加合适和更具说服力的对比。

介绍烹饪方法的食谱很多,几乎所有的流行杂志都会开设专栏来介绍形形色色的美食和烹饪方法,无论快餐式食谱还是精致复杂的食谱,注重食材的食谱还是注重搭配的食谱,你都能够找到。

但如果你希望自己成为烹饪大师,可供参考的资料就少得可怜了,比如食品行业经营(批量生产、饭店或餐饮企业的经营)、食品生产的供需管理、选料和食材保鲜方面的指南或资料。很显然,这就是业余烹饪爱好者和专业食品企业之间的区别。

这种情况与程序设计其实非常相似。

我们可以轻松地从成千上万的书籍、杂志、文章、网络论坛和博客中搜集到编程语言方面的各类信息,无论是入门教程,还是“谷歌编程面试指南”这样的技巧。

但是,想成为专业软件工程师,这类主题所涵盖的内容只能满足一半的要求。我们不能一直沉浸在因程序实际执行(且执行正确)而带来的喜悦当中,而需要着重考虑接下来的问题:如何组织代码结构以便将来修改,如何从功能模块中提取出可重用代码,以及如何让程序能够适应不同的运行环境(无论是用不同的人类语言和字符表达,还是在不同的操作系统环境中运行)。

相较于其他编程主题来说,人们很少讨论这类问题。时至今日,这类问题变成了只有计算机科学专业人士(绝大多数是软件架构师和构建工程师)和大学课堂上讲解编译器、链接器设计时,才会了解的“黑科技”。

由于Linux市场份额增加,而且越来越多的人都将Linux作为其编程环境,这促使开发人员开始关注Linux编程的相关问题。与在一些封装良好的平台上开发软件的开发人员不同,在Windows和Mac平台上利用IDE和SDK将程序员从一些特定的编程细节问题中解放出来,Linux开发人员在日常工作中需要将来自不同项目且编码风格迥异的代码组合起来,这需要开发人员充分理解编译器、链接器的内部工作机制和程序装载机制,以及不同库的设计细节和使用方法。

本书将许多零碎的知识点进行汇总,并讨论其中有价值的内容,再通过一系列精心设计的简单示例进行验证。需要注意的是,我并非计算机科学科班出身。在20世纪90年代末至今的数字革命中,我作为电气工程师供职于硅谷的一家多媒体行业高新技术企业,并因此掌握了相关领域的知识。希望本书的主题和内容能够让更多读者受益。

读者对象

作为一名软件设计实践顾问(虽然很忙,但我还是非常自豪的),我经常会与不同专业背景和资历的人沟通。我经常在不同的办公环境中工作,因此接触了许多开发人员(绝大多数来自硅谷),这也让我更加了解了本书的受众群体,其中包括以下几类人群:

● 第一类受众群体是来自不同工程领域(电气工程、机械、机器人技术和系统控制、航天、物理和化学等领域)的C/C++开发人员,这类人需要在日常工作中通过编程来解决问题。对缺乏正规计算机科学课程和理论教学的人来说,本书所提供的资料弥足珍贵。

● 第二类受众群体是具有计算机科学教育背景的初级程序员。本书能够帮助这类人将主修课程中学到的知识具体化,并注重实践。对资深工程师而言,将第12~14章的内容作为手册查阅也很有益。

● 第三类受众群体是操作系统集成和定制的爱好者。理解二进制文件及其内部工作机制将有助于在解决问题的过程中扫除障碍。

关于本书

我最初并没有计划去写这么一本书,甚至都没有打算写一本计算机科学领域的书。

在职业生涯中,我经常处理一些问题,这些问题当时我以为别人已经解决好了,而实际上它们并没有得到根本性解决,这是我写作此书的唯一原因。

很久以前,我决定成为一名高科技领域的“刺客”,将许多看似平静且体面的高科技公司从“恐怖问题”——复杂多媒体设计问题和大量严重缺陷所造成的破坏中解救出来。选择这样一个职业的结果就是,我并没有多少时间处理自己的生活,比如说孩子们想吃鸡肉而不是豌豆,我很难满足他们的需求。虽然我更倾向于使用傅里叶变换算法、小波、Z变换、FIR和IIR滤波器、倍频程、半音程、插值和抽取算法来解决问题(与C/C++编程一起使用),但我还是要解决那些我并不喜欢解决的问题。总要有人去做这些事情吧。

出乎意料的是,在搜索一些非常简单明了的问题的答案时,我只能找到一些散乱的网络文章,而且绝大多数都只是泛泛而谈。我很耐心地把这些散乱的内容组织到一起,不仅完成了我手头的设计任务,而且学习总结了很多资料。

在一个天朗气清的日子里,我开始整理设计笔记(记录我工作中经常遇到的一些问题和解决方案)。但在整理工作完成的时候,这些笔记看起来就像……嗯……就像一本书——就是这本书。

不管怎么说……

就目前就业市场的情况而言,我认为(自2005年左右开始)熟悉C/C++语言的复杂性,甚至是算法、数据结构和设计模式,对于找到一份好工作是远远不够的。

在开源盛行的今天,专业开发人员在日常工作中所编写的代码越来越少,取而代之的是将现有代码集成到项目中。这不仅要求开发人员能够读懂其他人编写的代码(使用不同的代码风格和实践),还需要了解如何才能以最好的方式将现有的包(绝大多数以二进制文件/库和导出头文件的形式提供)集成到代码中。

我希望本书能够兼具教学(对急需这些知识的读者而言)和快速查询的功能(对分析C/C++二进制文件相关工作的工程师而言)。

为何采用Linux进行演示

选择Linux并非我个人的偏好。实际上了解我的人都知道,我过去是多么喜欢使用Windows作为开发环境(原本这是我首选的设计平台),原因是Windows平台具有完善的文档、完美的支持和符合规范的认证组件。我设计过许多专业化软件(曾为Palm公司设计开发了Windows Mobile平台的GraphEdit,其中包含许多复杂的功能,随后又开发了多个媒体格式和DSP分析软件),当时我对Windows技术了如指掌,并感叹Windows相关技术所带来的改变。

与此同时,Linux的时代到来了。有关Linux的技术随处可见,而对开发人员来说,也必须顺应这种趋势去学习和使用它。

Linux软件开发环境具有开放、透明和简单明了的特点。在Linux中,我们可以对每个程序设计阶段进行控制。同时,Linux提供了完善的文档,再加上网络上提供的资源,就可以轻松地使用GNU工具链。

实际上,由于Linux C/C++开发经验可以直接适用于Mac OS平台的底层开发,因此我最终决定选用Linux/GNU作为本书所涵盖的主要开发环境。

别急!Linux与GNU完全是两回事

实际上,Linux是内核,而GNU中包含了Linux内核之上的所有软件。除了GNU编译器可以在其他操作系统上使用(比如Windows上的MinGW)以外,在绝大多数情况下,GNU与Linux的关系其实非常紧密。为了简单起见,同时为了符合一般开发人员对开发场景的认识,特别是为了将Linux与Windows进行对比,本书将GNU与Linux作为一个整体,简称为“Linux”。

章节概览

第1~5章讲解的内容主要为后续内容做铺垫。拥有计算机科学背景的读者可以快速阅读这些章节(幸运的是,这些章节的内容并不长)。实际上,任何计算机科学方面的教科书都会对这些内容进行类似介绍,而且内容会更为详细。我个人推荐由Bryant和O'Hallaron编写的《深入理解计算机系统》[1]Computer Systems—A Programmer's Perspective)一书,原因是该书对很多主题都进行了非常有条理的梳理和总结。

第6~11章是本书的核心章节。为求整体内容简洁明了,我花费了相当大的精力,并尝试使用一些日常生活中常见事物的文字和图片来阐述那些最为重要的核心概念。如果你不是计算机科学科班出身,那么有必要先理解这些内容。其实这些章节是本书主题的要点。

第12~14章主要概括了一些实践方面的内容,便于读者快速查找相关的概念。这些章节针对一些特定平台的二进制文件分析工具进行了总结,然后在实践部分涵盖了完成独立任务的方法。


[1] 书中文版已由机械工业出版社引进出版,ISBN:978-7-111-54493-7。