【在主画面加入捷径】
       
【选择语系】
繁中 简中

[C 语言] 程序设计教学:学程序设计一定要学 C 语言吗?

【赞助商连结】

    在这篇文章中,我们不急着写程序,来谈谈一些和学习 C 语言相关的议题。

    学程序设计一定要学 C 语言吗?

    如果各位读者是因一些非语言本身的因素要学 C 语言,像是学校指定用 C 语言来写程序或是因个人兴趣学习 C 语言等,那么,想学就学,同样的情境也可以套用在其他的程序语言上。不过,如果是因为单纯要学一个程序语言,好像大专院校都用 C (或 C++) 做为学习的工具,那倒不急着跳进来,其实还有很多选择。

    大专院校使用 C 语言,有其考量和历史因素。除了组合语言,C 语言大概是最贴近电脑的高阶语言,C++ 则保留 C 的特质但加入许多更高阶的语法特性。对资讯科系的学生来说,除了会数据结构、算法等抽象的思考方式之外,也要学一些电脑本身的知识,像是操作系统、计算机组织等。像 C (或 C++) 这种同时有高阶和低阶特性的语言就会是合适的工具。

    对于不是资讯出身又没学过程序设计的读者来说,C 语言不一定是最佳的第一个语言,因为从开始学习到写出东西的养成期较长,对于初心者来说易有挫折感。虽然笔者不是要吹捧 Python 最好最强,但 Python 等语言确实提供了较平滑的学习曲线,比较快就可以把程序用在实际的用途上,比较容易培养成就感。

    程序语言基本上就是在效能和易用间做权衡,不同的情境会使用不同的工具,没有一个语言可适用所有的情境。C (或 C++) 的重要性是无庸置疑的,但不一定每个人都要变成 C (或 C++) 达人。我们这系列文章是以学习 C 为出发点,之后的内容会以 C 为主。

    C 语言是资讯界的骨干

    比起其他的高阶语言,C 语言 (或 C++) 多用于电脑界的基础建设项目,像是

    • 操作系统
    • 驱动程序
    • 数据库
    • 服务器
    • 其他高阶语言的编译器或直译器
    • 其他高阶语言的延伸模块

    我们不一定会直接使用 C 语言,但很多软件或函式库背后都是使用 C 语言实现的。

    现在的程序语言大抵上是朝着简单易用的方向前进,仅在核心功能仍然需要 C (或 C++) 来撰写,甚至也有一些替代的方案来简化这个部分。像是 Cython 就是用来取代人工撰写的 C 程序代码,帮 Python 程序加速;同样的例子还有用来撰写 PHP 模块的 Zephir。许多语言都发展出 FFI (foreign function interface) 模块,用来取代原生的 C API,其实也可以用 Rust 写元件,会比直接用 C 来得简单一些。

    有些程序运行环境没有那么多运算资源,像是一些嵌入式装置 (embedded devices) 或物联网 (the Internet of Things) 装置等,这时候,我们没有太多选择,甚至 C++ 编译环境都显得过度奢华,大概还是要直接使用 C 语言来撰写程序。在少数比较高档的嵌入式装置,可以放一些相对肥大的运行环境,像是 Java 或 C# 等,但这并不是嵌入式系统的常态。

    C 语言的核心概念短小精悍

    其实 C 语言并不难,甚至可以说 C 语言相当简单,因为 C 语言的核心语法不多,很快就可以学完。C 语言定义了一小组核心语法,其他的功能都使用函式库来完成,这使得 C 语言编译器易于实现;每当我们开发出一个新的硬件,第一个想到的都是先开发一个给该硬件使用的 C 编译器,之后就可以慢慢地移植其他的函式库到这个平台上。

    由于 C 语言的概念相当精实,学完 C 语言后,同样的概念可以继续延伸到 C++、Java、C# 等语言;虽然这不代表我们马上就可以学会其他语言,但概念通了以后,我们只要学习语法的部分即可,程序设计的概念在学习 C 语言时就不知不觉打下基础了。

    不可否认地,学习 C 的确对学习 C++ 和 Objective-C 等语言有直接助益的,因为这些语言是在兼容于 C 的前提下所建立的新语言。但我们应该直接使用 C++ 和 Objective-C 的最佳实务,而非继续使用兼容于 C 但次佳的手法;例如,虽然我们可以在 C++ 和 Objective-C 中撰写 C 风格的物件,但我们应优先使用这些语言提供的物件系统,而非继续使用 C 风格的拟物件语法。

    学 C++ 或 Java 前要先学 C 语言吗?

    由于历史缘由,很多语言和 C 的确长得有点像,像是 C++、Java、C# 等语言的确有参考 C 的一些特质;甚至 JavaScript 这种本质上向 Scheme 致敬,但为了商业考量,刻意在语法上向 C 及 Java 靠拢。那么,我们是不是要先学 C,再来学 C++ 或其他语言呢?其实这是没有必要的,这些语言只是在语法上参考前人,但不会完全照抄其特性,需要学什么语言,大可以直接学习该语言即可。

    由于 C++ 的确保留一些 C 的特性,的确会有一些人会觉得要先学 C 再学 C++,像 C 程序设计艺术 (C: How to Program) 的前半部是 C 语言,却在后半部偷塞 C++,就给读者这样的暗示。如果读者真的需要学 C++,先学 C 是没有必要的。很多情境,在 C 和 C++ 的处理方式不同,实在不需要学两次。像 C++ 有 vector,我们大可不必再回头用 array;除非是为了兼容于 C 程序代码,我们也很少在 C++ 中使用 C 风格字串。连 C++ 的爸爸 Bjarne Stroustrup 都特定发了篇文章说 “Learning Standard C++ as a New Language.” (可见这里),我们大可不必在绕远路。尤其 C++ 在 C++11 标准后出现许多新的语法,和 C 的差距越来越远了,除了兼容性,我们甚少要再写 C 风格的程序代码。

    Java 和 C 就离得更远了,除了表面上一些语法相近以外,更重要的是背后运行的 Java 平台。C (或 C++) 由于贴近硬件,除了语法和标准函式库是相同的,很多系统 API 是相异的,如果去观察一些跨平台 C (或 C++) 的函式库,其实内部都用很多条件编译来处理各个平台的差异性,而 Java 基本上就直接把机器抽象化,程序设计者就不需要再烦恼这些问题了。C++ 的爸爸 Bjarne Stroustrup 对 Java 的评论是 “Java isn’t platform independent; it is a platform.“,值得我们思考。同样的情形也适用于 C#。

    程序设计有一部分是抽象思维,有一部分是实际工具,先学 A 再学 B 通常对抽象思考有帮助,但语法和工具都要重新学习。C (或 C++) 可用的开发工具会受到系统的影响,而不像 Java 或其他高阶语言那么地跨平台,我们也会在后续文章中介绍这一部分。

    【赞助商连结】
    TAGS: C 语言