基本信息
编辑推荐
C程序员必读经典
原版畅销11年
“毒舌程序员”为你揭开指针的真实面纱
内容简介
作译者
作者主页:http://kmaebashi.com/。
吴雅明 13年编程经验。其中7年专注于研发基于JavaEE和.NET的框架和代码生成工具。目前主要关注的方向有:Hadoop、HTML5、智能手机应用开发等。
目录
第0章 本书的目标与结构——引言 1
0.1 本书的目标 1
0.2 目标读者和内容结构 3
第1章 从基础开始——预备知识和复习 7
1.1 C是什么样的语言 7
1.1.1 比喻 7
1.1.2 C的发展历程 8
1.1.3 不完备和不统一的语法 9
1.1.4 ANSI C 10
1.1.5 C的宝典——K&R 11
1.1.6 C的理念 12
1.1.7 C的主体 14
1.1.8 C是只能使用标量的语言 15
1.2 关于指针 16
1.2.1 恶名昭著的指针究竟是什么 16
1.2.2 和指针的第一次亲密接触 17
1.2.3 指针和地址之间的微妙关系 23
1.2.4 指针运算 26
1.2.5 什么是空指针 27
译者序
本书的作者不是大学老师,更不是那些没有写过几行程序的学究,而是一位至今还工作在开发一线的程序员(在国内,工作了5年的你如果还在做“码农”,肯定会坐立不安了吧)。他带给大家的不是教科书中死板的说教,而是十多年经验沉淀下来的对无数个“脑残”问题的解答。在这本书初版面世的11年后,我在东京一个大型书店的C语言类别的书架上,依然还能看见这本书被放在一个非常醒目并且触手可及的位置上。
能从书架上挑出本书的人,我想大多都是对C语言指针带有“恐惧感”的程序员吧!其实所谓的“恐惧感”来源于“困惑”,而“困惑”又来自于“对知识点不够透彻的理解”。作者运用幽默风趣并且不失犀利的笔法,从“究竟什么是C语言指针”开始,通过实验一步一步地为我们解释了指针和数组、内存、数据结构的关系,以及指针的常用手法。另外,还通过独特的方式教会我们怎样解读C语言那些让人“纠结”的声明语法。
带着学习的态度,我对原著的每一个章节阅读三次以上后才开始动笔翻译。每次阅读我都会有新的收获,建议购买本书的读者不要读了一遍就将其束之高阁(甚至一遍读不下来就扔到一边)。隔一段时间再来读一遍,收获会更多。
在翻译的过程中,我身边的许多人给了我莫大的支持和鼓励。我的同事的宋岩、王红升在C语言方面都具有10年以上的编程经验,他们经常牺牲个人的休息时间帮我试读译稿,提出了诸多宝贵的意见和建议。开始翻译这本书时,我儿昀好刚出生三个月。新的生命改变了一家的生活状态,带给我们更多的是感动和欢乐。妻子葛亚文在我翻译本书的期间默默承受了产后在身体上和精神上的巨大压力,这不是一句感谢能够回报的。借此祝愿一家——四季有昀,岁月静好!
吴雅明
2012/11/26于北京
前言
一定有很多人感到纳闷:“都哪朝哪代了,还出版C语言的书。”
C语言确实是非常陈旧的语言,不过也不可能马上放弃对它的使用。至少在书店里,C语言方面的书籍还是汗牛充栋的,其中专门讲解指针的书也有很多。既然如此,还有必要旧瓶装新酒吗?这才是最应该质疑的吧。
但是,每当我看到那些充斥在书店里的C语言入门书籍,总会怀疑这些书的作者以前根本没有使用C开发过大规模的系统。当然,并不是所有书的作者都这样。
指针被认为是C语言中最大的难点,对它的讲解,很多书都搞得像教科书一样,叙述风格雷同,让人感觉有点装腔作势。就连那些指针的练习题,其中的说明也让人厌倦。
能够炮制出这样的书籍,我想一般都得归功于那些连自己对C语言语法都是一知半解的作者。特别是面对那些在封面上堂堂正正地印上“第2类信息处理考试” 字样的书,这种感觉更加强烈。
当我还是个菜鸟的时候,也曾对数组和指针的相关语法感到非常“纠结”。
正是抱着“要是那个时候上天能让我遇见这样一本书,那可真帮了大忙”的想法,我写了这本书。
本书的内容,是基于我很久以前(1998年7月)就开始在网上公开的内容:
“深入学习数组和指针”
http://kmaebashi.com/programmer/pointer.html
“当我傻呀?既然可以在网上阅读,我干嘛还买你的书?”我想对有此想法的人说:“我敢打包票,绝不会让你吃亏的,请放心地拿着这本书去收款台结账吧!”因为此书在出版过程中追加了大量的文字和插图,实际上已经比网上公开的内容丰富了许多。
另外,在阅读本书的过程中,请留心以下几点。
本书的读者群虽然定位于“学习过C语言,但是在指针的运用上遇到困难”的读者,但还是能随处可见一些高难度的内容。那是因为我也不能免俗,偶尔也喜欢把自己掌握的知识拿出来显摆一下。
对于初学者,你完全没有必要从头开始阅读。遇到还不太明白的地方,也不要过分纠结。阅读中可以跳跃章节。对于第0章和第1章,最好还是按顺序阅读。如果认为第2章有点难度,你可以先去啃第3章。如果第3章也不懂,不妨尝试先去阅读第4章。这种阅读方式是本书最大的卖点。
在本书中,我会经常指出一些“C的问题点”和“C的不足”。可能会有一些读者认为我比较讨厌C语言。恰恰相反,我认为C是一门伟大的开发语言。倒不是因为有“情人眼里出西施”、“能干的坏小子也可爱”这样的理由,毕竟在开发现场那些常年被使用的语言中,C语言还是有相当实力的。就算是长得不太帅,但论才干,那也是“开发现场的老油条”了。
所以,因阅读本书而开始抱怨“C语言真是很差劲”的读者,你即使计划了什么“去揍Dennis Ritchie 之旅”,我也不会去参加的。如果有“去揍James Gosling 之旅”,那还是有点心动的。哈,还是算了吧,得过且过就行啦。
在本书的写作过程中,我得到了很多人的帮助。
繁忙之中阅读大量原稿并指出很多错误的泽田大浦先生、山口修先生、桃井康成先生,指出本书网上公开内容的错误的人们,还有那些受到发布在公司内部的内容的影响而沦为“实验小白鼠”的人们,以及通过fj.com.lang.c和各种邮件列表进行讨论并且提供各种信息的人们,正是因为你们,本书的内容才能更加可靠。当然,遗留的错误由我来承担所有责任。
发现我的网页,并给予出版机会的技术评论社的熊谷裕美子小姐,还有给予初次写书的我很多指导的编辑高桥阳先生,如果没有他们的大力协助,这本书是不可能诞生的。
书摘
0.1本书的目标
在C语言的学习中,指针的运用被认为是最大的难关。
关于指针的学习,我们经常听到下面这样的建议:
“如果理解了计算机的内存和地址等概念,指针什么的就简单了。”
“因为C是低级语言,所以先学习汇编语言比较好。”
果真如此吗?
正如那些C语言入门书籍中提到的那样,变量被保存在内存的“某个地方”。为了标记变量在内存中的具体场所,C语言在内存中给这些场所分配了编号(地址)。因此,大多数运行环境中,所谓的“指针变量”就是指保存变量地址的变量。
到此为止的说明,所有人都应该觉得很简单吧。
理解“指针就是地址”,可能是指针学习的必要条件,但不是充分条件。现在,我们只不过刚刚迈出了“万里长征的第一步”。
如果观察一下菜鸟们实际使用C指针的过程,就会发现他们往往会有如下困惑。
声明指针变量int ?a;……到这里还挺像样的,可是当将这个变量作为指针使用时,依然悲剧地写成了?a。
给出int &a;这样的声明(这里不是指C++编程)。
啥是“指向int的指针”?不是说指针就是地址吗?怎么还有“指向int的指针”,“指向char的指针”,难到它们还有什么不同吗?
当学习到“给指针加1,指针会前进2个字节或者4个字节”时,你可能会有这种疑问:“不是说指针是地址吗?这种情况下,难道指针不应该是前进1个字节吗?”
scanf()中,在使用%d的情况下,变量之前需要加上&才能进行传递。为什么在使用%s的时候,就可以不加&?
学习到将数组名赋给指针的时候,将指针和数组完全混为一谈,犯下“将没有分配内存区域的指针当做数组进行访问”或者“将指针赋给数组”这样的错误。
出现以上混乱的情形,并不是因为没有理解“指针就是地址”这样的概念。其实,真正导演这些悲剧的幕后黑手是:
C语言奇怪的语法
数组和指针之间微妙的兼容性