英文原文:To become a good C programmer

  问题的提出

  每过一段时间我总会收到一些程序员发来的电子邮件,他们会问我是用什么编程语言来编写自己的游戏的,以及我是如何学习这种编程语言的。因此,我认为在这篇博文里列出一些有关C语言的最佳读物应该能帮到不少人。如果你知道其它的优秀读物,请给我发邮件或者直接在评论栏中告诉我吧。

  问题的解答(你可以略过这部分)

  我在之前的一篇博文中已经提到过了,目前为止,所有我所编写的商业 3D 引擎 95% 都是 C89(也称作标准C,或 ANSI C)。我之所以选择 C89 而不是 C99 是因为有些编译器仍然不能完美支持 C99 标准。而且从第一天起,我就强制规定游戏需要能在 iOS、Windows 和 Xbox 360 平台上都能编译。根据我所选择的编译平台,剩下5% 的代码是 Objective-C(iOS)或者C++(Windows, Mac OS X),这是为了将引擎绑定到原生的输入/输出设备上。没想到的是,选择C还是 C++ 这个主题在 reddit曾上引发了很大的争议。我选择C的两个真正原因是:

  ● 我写引擎时对 C++ 掌握的并不算好。平台资源非常有限(iPhone 2G),而且我知道我得对我的工具(编程语言)相当熟悉才能使游戏达到每秒 60 帧的速度。

  ● 因为我研读过 id Software(著名游戏制作公司,Doom 系列、Quake 系列是其代表作,开创了 FPS 类型游戏的先河)发布过的源代码,用纯C完成一个商业游戏是我的梦想。

  这算是“好”的选择吗?我想,到最后唯一合理的问题是:“你的游戏发布了吗?”以及“它跑的够快吗?”看看那令人难以置信的帧速吧(有人提到在玩 Shmup 时会有眩晕的感觉),我想我做了正确的选择。

  糟糕的C读物(不要忽略这一段)

  我将以一些我认为不必太认真的读物说起:网络教程,博客以及大部分 Google 上得到的东西都算(没错,也包括我这篇)。通常我认为这些资料来源是不可信的,而且有潜在的危害。和这一行里大部分人一样,我曾是重度 Google 搜索使用者。过了一段时间之后,我发现不准确的答案反而对生产力的提高有反效果。这让我有了一种速度上的错觉:答案找的越快,活干的越慢。没有什么网站会比一本好书更有价值,没有什么好书比反汇编输出更有价值。

  优秀的C读物

  1. 《C程序设计语言》

  《C程序设计语言》("C Programming Language",又称 K&R)。这是你应该首先去看的有关C语言编程的经典著作。读这本书会很轻松,它只有 272 页,386幅插图。由C语言之父 Kernighan 和 Ritchie 亲自编写的短小且有清晰解释的代码示例遍布全书各个角落。在刚开始的几周里,所有你需要了解的有关C语言的知识都在这里。这本书读起来很有趣,主题都比较短小,而且可以使你很快上手。你可能会跳过附录A(有关C语言中比较晦涩的阴暗角落,比如类型提升、 类型转换、型别退化以及其它一些无用的东西)以及有关C标准库的附录B。我认为刚开始学习C语言时,这些就足够了。这本书使C显得很娇小、简洁,因此强烈推荐学习这本书。

  如果你继续学习并坚持练习,很快你就会触到一些诡异的情况,比如下面的例子:

unsigned int ui_one         = 1;
signed int i_one = 1;
signed short s_minus_one = -1;
if (s_minus_one > ui_one)
printf (“-1 > 1 \n”);
if (s_minus_one < i_one)
printf (“-1 < 1 \n”);
#./run
#
# -1 > 1
# -1 < 1

  在上面的代码示例中,由于整型提升的缘故,-1先被计算为大于1,然后又小于1。C语言里有很多这种阴暗面,此时将产生不正确的结果。

  这里还有许多细节之处:

extern void foo (void);
void (*f)();
f = &foo; // 合法
f = foo; // 同样合法!(语法糖)
f (); // 调用f
(*f)(); // 同样调用了f(语法糖)

  或者有关数组/指针/类型退化的例子:

int array[] = {0, 1, 2, 3, 4};
int *pointer = array;
if (sizeof array == sizeof pointer)
   printf (“This will never be printed!!”);
if (sizeof(int *) == sizeof &array[0])
   printf (“This will be printed!!\n”);
if (&array[2] - &array[0] == 8 )
   printf (“This will never be printed either, result is 2 not 8!!”);

  当你发现自己原来对C语言的了解还很不够时(附录A真的太轻量级了),那这时就是拿起第二本书的时候了。

  2.  《C专家编程》(Expert C Programming

  这是本神奇的书,因为该书以一种非常娱乐化的方式告诉你在代码背后究竟都发生了些什么。通过介绍了几个著名 bug 的奇闻异事(大部分跟 NASA 有关)后,读者将再次领略整型提升、下标、类型退化以及许多其他的C语言犄角。这本书是如此的迷人,你很可能会一晚上埋头读完 353 页,然后失望地说:怎么这么短?

  现在你想挖的更深些并成为一个优秀的C程序员,你应该拿起这本你所需要的最后一本C语言书籍:

  3.  《C语言参考手册》(C: A Reference Manual

  这本书全面涵盖C/C89/C99标准。从今以后你面对的就是这些冰冷无聊的语言标准。你可以把《K&R》和《C专家编程》放在书架上,而把这本C语言参考手册摆放在显示器旁,任何你想知道的C语言知识都在这里。

  附加阅读

  1.  id Software 代码库

  只看书当然是不够的。阅读优秀的开源代码将带来极大的帮助。我的最爱是 id Software 的 3D 引擎代码库:Doom、Quake、Quake2、Quake3、Wolfenstein 3D iPhone 以及 Doom iPhone。当我阅读这些代码时,我会自己撰写备忘日志。之后我会整理这些日志,写成技术文章(DoomQuakeWolfenstein 3D iPhone 以及 Doom iPhone)。

  2.  《Sh*t My Dad Says

  试着保持健康的生活,改变一下,读些有趣的东西吧 : )

  

  原文评论栏中推荐的一些补充书目:

  1. C Interfaces and Implementations: Techniques for Creating Reusable Software(C语言接口与实现:创建可重用软件的技术)

  2.  Object-Oriented Programming With ANSI-C

  3. 《 Code Complete 2nd edition / 代码大全第二版》

如何成为一名优秀的C程序员的更多相关文章

  1. 成为一名优秀的Java程序员9+难以置信的公式

    成为一名优秀的Java程序员 成为一名优秀的Java程序员并不重要,但是首先您应该了解基本的编程语言. 好吧,你知道那太好了.我们应该一步一步地精通Java编程,并应遵循所有说明,改进Java的编程逻 ...

  2. 成为一名优秀的C程序员

    英文原文:To become a good C programmer 问题的提出 每过一段时间我总会收到一些程序员发来的电子邮件,他们会问我是用什么编程语言来编写自己的游戏的,以及我是如何学习这种编程 ...

  3. 想要成为一名优秀的Java程序员,你需要这8个锦囊

    私底下,隔三差五就有读者问我:"二哥,怎么样才能像你一样,成为一名优秀的 Java 开发者呢?"假如把"怎么才能像你一样"去掉的话,这个问题就是一个好问题,否则 ...

  4. OSChina 周三乱弹 —— 致力于做一名优秀的女程序员鼓励师

    https://my.oschina.net/xxiaobian/blog/848096

  5. 你想成为优秀的Java程序员吗?

    Java是全世界最受欢迎的3大编程语言之一,它可以开发出许多实用的WEB应用程序和桌面应用程序,更重要的一点,Java是跨平台的语言——编写一次,可以再任何地方运行.另外,Java也很容易入门,如果你 ...

  6. 一个优秀windows C++程序员的知识体系

    思考一个优秀windows C++ 程序员该有哪些知识,可最终发现什么知识都不能少, 看下图: 除了上面知识,程序员还要不断学习, 保持对新知识的热情. 转自http://www.cppblog.co ...

  7. 一个优秀windows C++程序员的知识体系[转]

    转自:一个优秀windows C++程序员的知识体系 思考一个优秀windows C++ 程序员该有哪些知识,可最终发现什么知识都不能少, 看下图: 除了上面知识,程序员还要不断学习, 保持对新知识的 ...

  8. 【转】优秀的Java程序员必须了解GC的工作原理

    一个优秀的Java程序员必须了解GC的工作原理.如何优化GC的性能.如何与GC进行有限的交互,因为有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只有全面提升内存的管理效率 ,才能提高整个应 ...

  9. 转:一个优秀windows C++程序员的知识体系

    转自:http://www.cppblog.com/weiym/archive/2012/06/10/178287.html.根据自身的经历,觉得作者总结的很好. 思考一个优秀windows C++ ...

随机推荐

  1. [ACM] HDU 5025 Saving Tang Monk (状态压缩,BFS)

    Saving Tang Monk Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  2. 去掉android点击事件产生的半透明蓝色背景

    在wap开发过程当中,当你点击一个链接或者通过Javascript定义的可点击元素的时候,它就会出现一个半透明的蓝色背景,若要重设这个表现 ,可以利用css3: *{ -webkit-tap-high ...

  3. Entity Framework CodeFirst------使用CodeFirst方式建立数据库连接(一)

    本文分步演练介绍通过 Code First 开发建立新数据库.这个方案包括建立不存在的数据库(Code First 创建)或者空数据库(Code First 向它添加新表).借助 Code First ...

  4. iOS 使用Charts框架 折线,柱状,K线,饼状,雷达全攻略

    我是前言: 大约几个月前我在某平台写了一篇文章, 文中简单地介绍了Charts两种图表的样式的使用, 不过有种意犹未尽的感觉, 利用周末的空闲时间再次看了看, 有了新的收获, 今天发出来,分享给大家, ...

  5. android开发之this.finish()的使用 分类: android 学习笔记 2015-07-18 19:05 30人阅读 评论(0) 收藏

    在一个Activity用完之后应该将之finish掉,但是,之前在学校里自己摸索着开发时并没有太注意这个问题,因为activity无论是否finish掉对功能的影响貌似都不是那么明显(这是读书时候的观 ...

  6. rabbitMQ实战(一)---------使用pika库实现hello world

    rabbitMQ实战(一)---------使用pika库实现hello world 2016-05-18 23:29 本站整理 浏览(267)     pika是RabbitMQ团队编写的官方Pyt ...

  7. HTML5 Canvas实现刮刮卡效果实例

    HTML: <style> #canvas { border: 1px solid blue; position: absolute; left: 10px; top: 10px; bac ...

  8. 八、C# 值类型

    结构.枚举.装箱.拆箱 自定义值类型 如何利用结构来定义新的值类型,并使之具有与大多数预定义 类型相似的行为,这里的关键在于,任何 新定义的值类型都有它们自己的数据和方法. 一般用枚举来定义常量值集合 ...

  9. SpringMVC4+thymeleaf3的一个简单实例(篇四:form表单数据验证)

    关于表单数据验证有很多中方法,这里我仅介绍JSR303注解验证.JSR303仅仅是一个规范,这里我们要用到它的一个实现:hibernate-validator. 注意在spring的配置文件sprin ...

  10. Elasticsearch学习2--Elasticsearch数据类型简介

    1.Elasticsearch 是 面向文档型数据库,这意味着它存储的是整个对象或者 文档,它不但会存储它们,还会为他们建立索引,这样你就可以搜索他们了.你可以在 Elasticsearch 中索引. ...