前言
大家好,好久不写博客了,久违的感觉。这篇文章是 C/C++ 程序设计
专栏的第一篇文章。说实话这个专栏申请了有半年多了,但是到目前为止仍然没有文章产出,本来打算今年年初开始动笔,其中又因为毕业的相关事宜耽误了很长时间,想想真的是非常惭愧。从另一个方面也暴露出了自己在时间管理方面能力的不足。以后真的是得多注意这方面的东西。好了,我们还是进入正题吧。说实话 C语言是我最早接触的编程语言,大一大二写算法代码的时候都是用的 C
和 C++
,当时觉得 C语言从某些方面来看非常鸡肋,比如说我们用标准 C语言
语法无法写出漂亮的图形化界面,只适用于做数据处理。后来当我真正对 C语言有了一个更加深入的了解了之后才发现以前的自己太年轻。想要写出图形界面我们随便使用一种图形化框架(MFC、QT 等)就可以达到目的。这些图形化框架是遵循标准 C/C++ 语法的,在这个基础上各种图形库框架提供了各种类库来供开发者使用,这些类库就包括了一些图形化控件(窗口、按钮、对话框等)。因此我们借助这些框架提供的各种类库组合起来就可以写出漂亮的界面。而当我们熟悉了这些框架的相关原理(当然这里面包括很多东西,比如窗口的声明周期、组件的绘制原理和时间、整个程序框声明周期、消息处理机制等)后。回过头来我们会发现这些框架是在 C/C++ 语法的基础上将操作系统提供的一些接口以某种思想(面向对象编程)封装了起来,让我们可以通过调用其封装的相关 API 来间接的调用操作系统的相关接口。其本质上还是需要遵循 C/C++ 语法规则(当然,能设计出一款图形库框架是非常了不起的)。因此本专栏的重点是放在 C/C++ 的语言特性和一些必要的底层原理上,不会从 0 开始介绍 C/C++ 的语法。同时,对于图形化相关的东西不会过多介绍。也算是对 C/C++ 做一个学习总结。作者水平有限,如果文章中有不正确之处还望多多指点,谢谢大家。
在正式开始之前我们还是有必要了解一下 C/C++ 语言的相关背景。C语言最早是在贝尔实验室为了开发 Unix 操作系统而设计的,在此之后 C语言由于其高效、可移植(相对于当时来说)、强大、灵活等特性广为流传。之后在 1989 年 美国国家标准协会(ANSI)发布了第一个 C语言标准,国际标准化组织于 1990 年采用了这套 C 标准(ISO C)。ISO C 和 ANSI C 是完全相同的标准。ANSI/ISO 标准的最终版本通常叫作 C89(因为 ANSI 于 1989 年批准该标准)或 C90(因为 ISO 于 1990 年批准该标准)。1994 年,ANSI/ISO 联合委员会开始修订 C 标准,为了弥补 C89 标准中存在的一些缺陷。最终在 1999 年发布了 C99 标准。而在 2011 年发布了 C11 标准。关于 C11,我们之后还会介绍。20 世纪 90 年代,许多软件公司开始改用 C++来开发大型的编程项目。C++在 C 语言的基础上嫁接了面向对象编程工具。C++几乎是 C 的超集,这意味着任何 C 程序差不多就是一个 C++程序。我们在写 C语言程序的时候将源文件后缀名改为 .cpp
就可以在其中使用 C++ 的语言特性了。
在定制了语言标准之后,许多编译器提供商就开始根据标准来设计并制作对应的编译器,当然编译器厂商可能并不会完全按照标准来,就好像浏览器内核厂商并不会完全按照 W3C 定制的 html 等前端标准来制作内核一样,因此同一份 html 代码在不同厂商的浏览器上可能会有不同的表现。当然不必对这些过于担心,因为大部分编译器厂商还是紧跟标准来制作编译器的。这其中包括两个非常有名的编译器:GCC 和 Clang。其中,GCC 作为 GNU(“GNU’s Not UNIX” )的产品之一,GNU 是一个致力于开发大量免费 Unix 产品的项目。而 GCC 用来作为语言编译器。编译 C/C++ 源代码是它的功能之一。Clang 隶属于 LLVM 项目,该项目是与编译器相关的开源软件集合,Clang 是该项目的产品之一,用于处理 C/C++ 代码。在本专栏中我们主要采用 GCC 作为编译器。
程序的编译和运行
CPU 负责处理指令和数据,每一个 CPU 指令都有一个对应的二进制数字编码表示,而我们书写的 C语言程序都是文本文件(当然,本质上文本文件也是二进制文件),这种文本文件是 CPU 不能直接识别的,因此我们需要一个“翻译官”,负责将我们书写的源程序代码文件翻译成 CPU 可以识别的二进制指令和数据。这个“翻译官”就是我们上面提到的编译器。拿 C语言来说,我们在写好一个 C语言源程序之后,需要对源程序成功编译、链接等步骤之后才可以得到对应的可执行程序文件,具体步骤为:预处理->编译->汇编->链接。这些具体步骤中细节内容颇多,我们将在放在下一篇文章中介绍 GCC 相关知识点时一起探讨。
当我们书写的源程序经过上述编译步骤后,编译器会生成一个可执行的二进制文件,这个二进制文件的格式是符合操作系统对可执行文件内容格式要求的。这种文件在 Windows 系统上的后缀名一般为 .exe
。当然后缀名本身并不能改变文件内容和相关属性,它能决定的是操作系统默认用什么方式来处理该文件而已。比如一个后缀名为 .txt
的文件,Windows 系统会默认使用记事本程序打开它,当然你也可以改变这种默认行为,比如你可以通过浏览器打开一个 .txt
的文件,通过右键->打开方式即可选择打开这个文件的应用程序。当一个文件的后缀名是操作系统无法识别的时候,操作系统就会弹框提醒你选择一个本地存在的应用程序去打开它或者从互联网上下载并安装一个程序来打开它。而某些时候通过某些应用程序打开一些文件的结果可能并不是你想要的,比如你试图用一个只支持 GBK
编码的文本查看器去打开一个以 UTF-8
编码的文本文件,就会出现乱码现象。出现这些现象的原因终归来说都是文件的二进制内容格式不符合打开这个文件的程序可以识别的二进制内容格式的要求。如果你经常使用电脑,这些现象你应该都遇见过。
好了,回到刚刚的话题,当我们得到了一个可执行程序文件之后,我们运行它(