在学习Objective-C之前先学习C语言

108
作为一个有志于成为苹果开发者的人,我想听听社区的意见,是否在学习 Objective-C 和最终的 Cocoa 框架之前先学习 C 会更好?
我的直觉告诉我应该先学习 C,这将为我打下良好的基础。
23个回答

165

我建议先学习C语言。在开始学习Obj-C之前,我学习了C语言(并且在C语言上做了很多工作)。我有很多同事从未真正成为过C程序员,他们直接从Obj-C开始学习,并只学了必要的C语言知识。

但是,我偶尔会看到他们完全用Obj-C解决问题,有时候结果是非常笨拙的。通常情况下,我会用纯C代码替换一些Obj-C代码(毕竟你可以随意混合它们,Obj-C方法的内容可以完全是纯C代码)。 没有任何侮辱Obj-C程序员的意思,但是有些方案在Obj-C上非常优雅,在面向对象编程中,这些方案比函数式编程更好用;例如,多态性是一个非常出色的功能...而且我真的很喜欢Obj-C(比C++好多了!我讨厌C++的语法,有些语言特性完全是过度的,会导致糟糕的开发模式),然而,当我重新编写同事的Obj-C代码(我只会在我认为绝对必要的情况下这样做),结果的代码通常会缩小50%,只需要使用以前的25%内存并且运行速度更快400%。

我想说的是:每种语言都有其优缺点,C语言和Obj-C也不例外。然而,Obj-C真正伟大的特性(这就是为什么我甚至比Java更喜欢它)是您可以随意跳转到纯C代码再返回来。 为什么这是一个伟大的功能?因为就像Obj-C修复了纯C的许多缺点一样,纯C也可以修复Obj-C的一些缺点。 如果混合使用它们,您将获得非常强大的团队。

如果你只学习Obj-C,并且对C一无所知或者只了解一些基础知识,从未尝试过C语言如何优雅地解决一些常见问题,实际上你只学会了Obj-C的一半。 C语言是Obj-C的基本组成部分。在任何时候和任何地方使用C语言能力是其基本特征。

一个典型的例子是我们使用的一些代码需要将数据编码为base64格式,但我们不能使用外部库来实现这个功能(没有OpenSSL库)。我们使用了一个完全使用Cocoa类编写的base64编码器。它工作得还好,但是当我们让它编码200 MB的二进制数据时,它需要很长时间,而且内存开销不可接受。我用一个非常小的、完全由一个C函数编写的base64编码器代替了它(我将函数体复制到方法体中,方法以NSData为输入并返回NSString作为输出,但是在函数内部,所有内容都是C代码)。这个C编码器非常紧凑,它的速度比纯Cocoa编码器快了8倍,并且内存开销也少得多。编码/解码数据、玩弄位和类似的低级任务正是C的强项。
另一个例子是某些绘制图形的UI代码。为了存储绘制图形所需的数据,我们使用NSArray。实际上是NSMutableArray,因为图形是动画的。结果:图形动画非常慢。我们用普通的C数组替换了所有的NSArray,用结构体代替了对象(毕竟图形坐标信息只是你必须拥有的对象),用简单的for循环替换了枚举器访问,开始使用memcopy在数组之间移动数据,而不是从一个数组中取出数据再放到另一个数组中。结果:速度提升了4倍。即使在较老的PPC系统上,图形也可以流畅地播放。
C语言的弱点是,每个更复杂的程序都会变得很丑陋。保持C应用程序可读性、可扩展性和可管理性需要程序员具备极高的纪律性。许多项目因为缺乏这种纪律性而失败。Objective-C使您可以使用类、继承、协议等轻松地组织应用程序结构。也就是说,除非必要,我不会在方法的边界处使用纯C功能。我喜欢将所有代码都放在对象的方法内部;否则,所有这些都与OO应用程序的目的相悖。然而,在方法内部,有时我会完全使用纯C。

11
如果你已经了解C++,那么你已经具备开始学习Objective-C的基础。 - Sven
这是我对这个主题的最喜欢的思考,谢谢。 - Morkrom
嗨,我也想开始移动开发。我的目标是长期的。所以我也想早点或晚点学习Java。有人能帮帮我吗?我应该从Java开始然后再学C,还是直接跳入Objective-C?或者我应该先学C或C++,然后再学Objective C,最后再学Java?我非常感谢您对这个话题的意见! - Frederik Witte
1
@FrederikWitte 初学者最好不要学习C++(而且对于移动开发来说也不是必需的语言),以免混淆。从Java开始学起,它是一种很好的教学语言,只要掌握Java就足以为Android开发做准备(除非你想编写游戏或视频播放器等)。然后再学习C语言,最后再学习Obj-C,除非你想跳过这些,直接学习Swift。由你决定。 - Mecki
太棒了,谢谢你! - Frederik Witte
显示剩余2条评论

25
你可以同时学习C和Objective-C,没有必要在开始使用Objective-C的语言增强之前学习C的细节(包括指针算术等),作为一个新手编程者,快速开始使用Objective-C可能有助于你更快地开始"思考对象"。
就可用资源而言,苹果的文档通常假定熟悉C,因此从The Objective-C 2.0 Programming Language开始不会对您有太大的帮助。我建议购买Stephen Kochan的Objective-C编程书籍(根据您想要多快开始,您可以考虑等待第二版): Programming Objective-C Developers Library Programming Objective-C 2.0 Developers Library 它假定您没有任何经验,并教授您Objective-C和所需的C知识。
如果您感到有些雄心勃勃,可以从Scott Stevenson的"Learn C"教程开始,但它确实有一些先决条件("您应该已经了解至少一种脚本或编程语言,包括函数、变量和循环。您还需要在Mac OS X终端中输入命令。")。
(仅供记录和背景参考:我在1991年同时学习了这两种语言,似乎并没有对我造成任何伤害。不过,我之前有一些BASIC、Pascal、Logo和LISP的基础知识。)

2
你绝对不需要先学习C语言,特别是如果你已经掌握了像C#或Java这样的编程语言。C#和Java在很大程度上都受到Objective C的影响,尽管C#更多地受到Helsberg在Delphi方面的经验和错误的影响。 - Daniel Honig

18
在写Objective-C书之前,我对这个问题进行了很多思考。首先,我真的认为在学习Objective-C之前学习C语言是错误的路径。C是一种过程式语言,包含许多在初学者级别编程Objective-C时不必要的特性。事实上,使用其中一些特性违背了遵循良好面向对象编程方法论的原则。在学习面向对象语言之前教授过程式语言的所有细节(并使用函数和结构化编程技术攻击问题的解决方案)也不是一个好主意。这可能会使程序员走向错误的方向,潜在地导致培养错误的取向和心态,从而无法培养良好的面向对象编程纪律。仅仅因为Objective-C是C语言的扩展,并不意味着你必须先学习C!
我认为将Objective-C和底层的C语言作为单个集成语言进行教学是正确的方法。没有理由去学习“for”语句是来自C语言而不是它的超集Objective-C语言。此外,在学习数组(NSArray)和字符串对象(NSString)之前,为什么要详细了解C数组和字符串(以及操作它们)呢?许多C文本都花费了大量时间来介绍结构体、指向结构体的指针以及使用指针迭代数组。但是,你可以在不了解这些C语言特性的情况下开始编写Objective-C程序。对于初学者来说,这是一件大事。这不仅缩短了学习曲线,而且减少了必须学习(并有选择地过滤掉其中的一些)以编写Objective-C程序的材料数量。
我确实同意你需要学习大多数甚至全部底层的C语言特性,但是许多特性可以推迟到定义类和方法、处理对象和消息表达式以及理解继承和多态概念被充分理解之后再学习。

这是为那些想快速学习而避免挣扎和深入理解的人准备的。我正在教一个完全的编程新手(而我有11年以上的编程经验)编程,并曾经教过其他人(但我不是教师,这一点要明确)。你知道吗?我们都习惯了的所有这些概念对于完全的初学者来说都太复杂和不直观了!C语言是理解足够低层次的东西的好方法,这样在未来它对他们来说就不会是什么魔法了。也就是说,对于一个更好的程序员来说,用C语言作为第一门语言学习曲线更好,因为它有着野蛮的规则=) - MANIAK_dobrii

15

如果你已经掌握了几种语言,我会建议你直接学习Objective-C,因为它的语法并不是最难掌握的部分,相对来说,Cocoa框架才是需要花费更多时间去学习和理解的。


1
现在说到这个,学习C语言的材料要多得多。我发现ObjC最困难的部分就是缺乏组织良好、清晰明了、深度足够可以与C或C++的材料进行比较,并真正帮助你理解其内部运作的材料。 - Spanky

10

我认为,学习C语言对于无论进入哪个领域都是一个好主意,至少要先掌握软件开发的内部工作原理,然后再使用预打包的产品,这样如果出现问题,你就更有可能理解内部工作原理。关于这个问题,在SO上有很多讨论,而且这是一个相当主观的问题,但总的来说,你将在Objective-C代码中固有地使用C语言,所以我想这真的取决于你自己。我是一个从基础开始的人,但有时候它会妨碍我的发展,我知道一些聪明的人是从上到下逐步发展起来的,我认为重要的是你能够理解内部工作原理,这将使你的能力与那些没有理解原理的人区别开来,并增强你的能力。


如果您还没有扎实的面向对象编程基础,学习C语言可能会扭曲您对OO编程的看法。混合结构化和过程式编程并不好。但同样也是真的,OO在许多C表现优异的领域失去了它的价值,例如编写低级别的代码。 - Daniel Honig
1
我提议每个开发者在某一时刻学习 C 语言的原因至少是基于这样一个想法:即使是面向对象的语言最终也会编译成与 C 完全相同的指令。对象的变量使用指针,垃圾回收器使用 malloc 和 free,文件使用操作系统句柄进行锁定;在 Java 或 C# 应用程序出现问题时,了解这些基础知识可以极大地提高您对问题的理解。了解将要执行的资源分配也倾向于编写更为明智、更优化特定环境下性能的代码。 - TheXenocide

7
学习Objective-C之前,学习C是一个好主意,因为Objective-C是C语言的严格超集。这意味着Objective-C可以支持所有正常的C代码,因此在Objective-C代码中也会出现普通C程序中的代码。
除了从语言角度纯粹看待事物外,您会发现Mac OS X是一个完整的Unix操作系统。所有系统级库都是用C编写的。
虽然可能同时学习两种语言,但如果您先对C有坚实的工作知识,您将更加欣赏和理解Objective-C。

5

我建议你学习Objective-C,并随着学习逐渐掌握所需的C语言知识。

C语言中你不会太依赖的领域:

  • 指针算术和数组。我根本没有使用C语言的数组。
  • C语言字符串。Objective-C的字符串更加优雅和安全。
  • 如果你在Obj-C 2.1中使用GC,就不需要手动管理内存。出于开发速度和性能方面的原因,我强烈推荐这种方法。

6
一个需要注意的问题是:Objective-C中的垃圾回收并不适用于所有平台(尤其是iPhone),这是需要注意的事情。 - Mark Bessey

5

在学习Objective-C和Cocoa的过程中,你不可避免地需要学习一些C语言。例如,矩形通常由一个C结构体CGRect表示。

如果你有时间,尽管去学习C语言。正如其他人在这里所说的那样,Kochan的书(第二版和第一版)非常适合作为参考书。


4

在Objective-C中有很多事情是无法完成的,因此学习一些基本的C技能将非常关键。至少需要了解变量声明和基本C库函数,否则您会感到沮丧。


3
更好的选择,我不清楚,因为我对Objective-C不熟悉。但是C语言的基础并不难学,它的语法并不是很复杂(掌握起来可能有些难度),所以你可以尝试一下,这不会浪费时间。个人认为学习C语言总是一个好主意,它能让你深入了解计算机的运作方式。毕竟,大多数编程语言和系统仍然是用C语言编写的。然后继续学习吧!PS: “继续学习”并不意味着“放弃”,而是“学习更多、学习不同的知识”。一旦你掌握了C语言,你可能永远不会放弃它:Java使用JNI调用C例程进行低级操作,Python、Lua等语言通常使用C代码进行扩展(Lua参考文档假定某些函数对应的C函数只是一层薄包装),等等。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接