2024-10-17 17:21:42 +08:00

341 lines
29 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 第一章C 语言的学习技巧
## 1.1 如何学习 C 语言?
* 对于大部分的初学者, 学习 C 语言的目的可能是为了成为一名合格的程序员,开发出优秀的软件。但是,在学习了 C 语言的基本语法后,却发现只能在`控制台``黑底白字`)上玩玩,没有漂亮的用户界面以及人性化的交互。于是,开始学习数据结构、算法、数据库、操作系统,越陷越深,越来越迷茫,不知道学习 C 语言能做什么,认为学习编程很难,开始怀疑自己,直到放弃!!!
* 其实C 语言本身就是一门非常简单的语言,提供的实用功能不多,大部分的时候需要`借助`操作系统、第三方库以及以及一些硬件,如:单片机等,才能发挥它的威力!!!
> [!IMPORTANT]
>
> * ① 学习 C 语言仅仅是让你踏上程序员之路的第一步而已,只学习 C 语言也做不了什么。
> * ② 系统、扎实的学习 C 语言可以让你了解底层硬件、一些简单的数据结构和算法,并培养计算机思维。
* 前文我们提过C 语言是一门通用性的语言并没有针对某个领域进行优化。并且在实际项目中C 语言主要用于比较底层的开发,例如:
* Windows、Linux、Unix 等操作系统的内核 90% 以上都使用 C 语言开发Rust 语言有望未来,在操作系统开发中占据一席之地,特别是在对安全性和性能要求极高的领域)。
* 开发硬件驱动,让硬件和操作系统连接起来,这样用户才能更有效的使用硬件。
* 单片机和嵌入式属于软硬件的结合,是使用 C 语言最多的地方。
* 开发系统组件或服务,用于支撑上层应用。
* 如果对软件某个模块,例如:算法和搜索部分的效率要求较高,也可以使用 C 语言来开发。
* ……
* 貌似感觉 C 语言的应用还是很多的啊,那为什么感觉学习 C 语言还是做不了什么?原因除了 C 语言通常都是开发最`底层`的应用之外,最重要的一点就是`生态`
> [!IMPORTANT]
>
> 现代化的高级编程语言的流行程度,除了和编程语言的设计是否优秀有关,最主要的原因就是`生态`。
>
> * ① 很多编程语言都自带`标准库`语言本身提供的开箱即用Java、Go 等。
> * ② 很多编程语言都有自己的`包管理器`用于管理第三方库解决方案Java 中的 Maven、Gradle、Go 中的 go modules JavaScript 的 npm 等。
>
> 遗憾的是C 语言的`标准库`非常简单,只有`输入输出`、`文件操作`、`日期时间`、`字符串处理`、`内存管理`,对于`网络编程`、`GUI`、`数据库`、`并发`等`需要`大量的`第三方库`或`操作系统的功能`来扩展 C 语言的功能Java 语言、Go 语言等其他的现代化高级编程语言都是直接将这些常见的开发场景内置到标准库中开箱即用极大的降低了软件开发的难度。C 语言的`第三方库`也不是很多和其它现代化高级编程语言相比C 语言的大多数的第三方库都是`底层库`,支持应用开发的库寥寥无几,只有一个 GTK 库能够开发出桌面软件,几乎没有网站开发以及 APP 开发相关的库),社区也不是很活跃(和其它现代化高级编程语言相比),更别提缺少自己的包管理器。
> [!IMPORTANT]
>
> * ① 换言之在实际工作中C 语言几乎是不用做软件、网站、APP 等这些应用层开发,其它的编程语言能够更好地完成任务,没必要非得使用 C 语言C 语言基本都是用来做底层开发,也就是看不见摸不着的、在后台默默提供服务的那些项目,而这样的项目对初学者来说基本没有实用价值,初学者也不知道它们该怎么使用。
>
> * ② 初学者想要的 C 语言没有C 语言能做的初学者用不到,就是这种矛盾,导致初学者非常迷茫。
>
> * ③ 有人可能会问C 语言不是还可以用来开发单片机或者嵌入式吗是的没错但是这个方向是软硬件结合的不是在我们的电脑上进行开发而是在特殊的板子上进行开发并且还需要学习数字电路、模拟电路、8051/ARM、RTOS、嵌入式 Linux 等方面的知识,只学 C 语言也没有用武之地。
>
> * ④ 如果你觉得学了 C 语言没用,那么恭喜你,你是对的,应用层的开发一般真的用不上它。
> * ⑤ 但是,没用也要学,学习 C 语言并不一定是要应用它C 语言可以夯实你的编程基础,尤其是数据结构、算法、内存、线程、进程、通信、操作系统、编译原理等底层的计算机知识,没有 C 语言基础是学不好的。
> * ⑥ 这些底层知识并不一定能够直接应用在实际开发中,但是它们会让你有底气,会让你透彻地理解编程概念,会让你站的“低”看得远,会让你避免很多低级错误,会让你心中有“架构师”的思维。
> [!IMPORTANT]
>
> 不过,现在 C 语言社区也开始诞生了一些包管理器Conan 和 vcpkg 也有自己的项目构建工具cmake 、xmake 等。
> [!NOTE]
>
> JavaScript 的作者 Brendan Eich布兰登·艾奇 曾经这么说:“与其说我爱 JavaScript不如说我恨它。它是 C 语言和 Self 语言一夜情的产物(`致敬 C 语言`)。十八世纪英国文学家约翰逊博士说得好:"它的优秀之处并非原创,它的原创之处并不优秀。"”
>
## 1.2 项目构建工具和包管理器
### 1.2.1 概述
* `项目构建工具``包管理器`在软件开发中扮演着不同的角色,它们虽然有时会有重叠的功能,但主要关注的点是不同的。
### 1.2.2 项目构建工具
* `项目构建工具`是用于`自动化编译、测试、打包、部署`等一系列任务的软件工具。它们帮助开发者简化和管理整个软件开发生命周期中的各个步骤,尤其是在构建过程中的复杂性管理上。
* 其功能有:
| 功能 | 描述 |
| ---------- | ------------------------------------------------------------ |
| 编译代码 | 自动编译源代码(如 `.java`等)为可执行文件或中间文件(如:`.class` 文件)。 |
| 运行测试 | 集成单元测试、集成测试,自动运行测试用例并生成报告。 |
| 打包 | 集成单元测试、集成测试,自动运行测试用例并生成报告。 |
| 依赖管理 | 自动下载、更新和管理项目所需的第三方库(这部分功能有时与包管理器重叠)。 |
| 部署 | 将打包后的应用程序自动部署到测试环境、生产环境等。 |
| 任务自动化 | 除了基本的构建流程外,还可以自动化执行一些常见任务,如:代码检查、文档生成等。 |
* 常用的项目构建工具:
| 项目构建工具 | 支持语言 | 描述 |
| ------------ | -------- | ------------------------------------------------------------ |
| Maven | Java | 一个流行的构建工具和依赖管理工具,广泛用于 Java 项目。 |
| Gradle | Java | 一个灵活的构建工具,支持声明式的构建脚本和多种语言。 |
| Make | C/C++ | 一个经典的构建工具,使用 Makefile 来定义构建规则和依赖关系。 |
| CMake | C/C++ | 一个跨平台的构建系统,帮助生成标准的构建文件。 |
| ... | ... | ... |
### 1.2.3 包管理器
* `包管理器`是用于`自动化安装、更新、配置``管理软件包及其依赖关系`的工具。它主要关注于获取和管理项目所需的第三方库或工具包,并确保它们正确地集成到项目中。
* 其功能有:
| 功能 | 描述 |
| -------------- | ------------------------------------------------------------ |
| 依赖管理 | 根据项目配置文件(如:`package.json`)自动下载和安装项目所需的依赖包。 |
| 版本控制 | 管理包的版本,允许开发者指定某个特定版本或版本范围,确保项目中的库版本一致性。 |
| 包的发布和共享 | 开发者可以通过包管理器发布自己的库,并且共享给社区或组织内部的其他项目使用。 |
| 环境隔离 | 有些包管理器提供虚拟环境功能,可以将不同项目的依赖隔离开,避免版本冲突。 |
| 更新和卸载 | 包管理器可以自动更新依赖包到最新的兼容版本或卸载不再需要的包。 |
* 常见的包管理器:
| 包管理器 | 支持语言/平台 | 描述 |
| -------- | ------------------- | ---------------------------------------------------- |
| npm | JavaScript、Node.js | 用于管理 JavaScript 和 Node.js 项目的包和模块。 |
| pip | Python | 用于安装和管理 Python 的软件包。 |
| Cargo | Rust | Rust 编程语言的包管理器和构建工具。 |
| yarn | JavaScript | yarn 是 npm 的替代品,提供更快和更可靠的包管理体验。 |
| Homebrew | MacOS | 用于 MacOS系统下的命令行工具和库的管理。 |
| ... | ... | ... |
### 1.2.4 注意事项
* 对于 `Java` 项目中的 `Maven``Gradle` 而言,其不仅是`项目构建工具`也是`包管理工具`
> [!NOTE]
>
> * ① Gradle 也支持原生项目的开发C 和 C++ 。
> * ② 不过,目前而言,业界开发 C/C++ 项目时,使用最多的项目构建工具和包管理器是 Cmake 和 Conan 。
## 1.3 C 语言为什么没有应用层开发的库?
* C 语言是一门“古老”的语言了它只支持面向过程编程不支持面向对象编程和泛型编程在中大型的应用层项目开发中C 语言已经显得捉襟见肘了C++、Java、Python、C#、JavaScript 等其他编程语言能够更好地胜任,为 C 语言开发应用层的库简直是费力不讨好,所以几乎没人这么做。
* GTK 算是一个应用层的库,它使用 C 语言开发但是为了适应市场GTK 也提供了其它编程语言的接口C++、Python 等。
* 先不用管面向过程、面向对象、泛型这些晦涩的编程概念。简单地理解就是C 语言支持的特性少,用起来费劲,开发效率低,而 C++、Java、Python、C#、JavaScript 等支持的特性多,用起来方便,开发效率高。
> [!IMPORTANT]
>
> * ① C 语言的优势是运行效率极高,这正是底层开发所看重的。
> * ② 底层开发有时候就是一个模块,或者是一个服务,规模不算大,但是对效率有严格的要求,此时用 C 语言就非常合适,所以针对底层开发的 C 语言库较多,因为它们有非常大的实用价值。
# 第二章:嵌入式领域中的 C 语言
## 2.1 概述
* C 语言在 C51、STM32 和 ARM 平台上的应用场景非常广泛,涵盖了各种嵌入式系统的开发需求。
## 2.2 C518051 系列微控制器)
* `背景`8051 是由 Intel 于 1980 年设计的一种 8 位微控制器架构。它具有指令集简单、结构紧凑的特点,广泛应用于低端嵌入式系统中。
* `开发工具`C51 是指针对 8051 系列微控制器的 C 语言编译器Keil C51。这种编译器将 C 语言代码编译为适合 8051 架构的汇编代码。
* `C 语言的作用`C 语言在 8051 微控制器上的应用使得开发更加高效和可维护。尽管 8051 的硬件资源有限,但 C 语言仍然能够在不损失性能的前提下提供高级编程的便利。
* `应用场景`
| 应用场景 | 描述 |
| ---------------- | ------------------------------------------------------------ |
| 简单的控制系统 | 家用电器(微波炉、洗衣机、空调)的控制板等。<br>这些设备通常不需要复杂的运算能力,但要求可靠和稳定的控制。 |
| 低功耗传感器接口 | 常用于低功耗传感器的数据采集和传输,如:温度、湿度、压力传感器。 |
| 工业自动化设备 | 用于简单的工业自动化控制,如:小型电机驱动、工业传感器数据处理和传输。 |
| 电子玩具 | 许多简单的电子玩具使用 8051 系列微控制器来控制声音、LED 灯光、显示屏等。 |
> [!NOTE]
>
> 总结C51 微控制器适用于资源受限、需要低成本的简单控制系统,非常适合使用 C 语言来进行开发!!!
## 2.3 STM32STM32 系列微控制器)
* `背景`STM32 是意法半导体STMicroelectronics推出的一系列基于 ARM Cortex-M 内核的 32 位微控制器。它们广泛用于需要高性能和低功耗的嵌入式应用中,如:工业控制、消费电子和物联网设备。
* `开发工具`:开发 STM32 微控制器通常使用 Keil、IAR Embedded Workbench 或 STM32CubeIDE 等开发环境。这些环境中使用的编程语言主要是 C有时也包括 C++)。
* `C 语言的作用`C 语言在 STM32 上的应用非常广泛,开发者可以利用它直接控制硬件寄存器,同时也能方便地使用 STM32 提供的 HAL硬件抽象层库或 LL低层库进行开发。C 语言在这个平台上不仅能实现底层控制,还能编写复杂的应用逻辑。
* `应用场景`
| 应用场景 | 描述 |
| -------------- | ------------------------------------------------------------ |
| 物联网设备 | 常用于各种物联网设备,如:智能家居控制系统、环境监测设备、可穿戴设备等。<br>这些设备通常需要低功耗和强大的处理能力并且需要支持多种通信协议Wi-Fi、Bluetooth、LoRa。 |
| 消费电子 | 智能手表、健身追踪器、电子书阅读器、无人机等,这些设备需要具备实时处理能力、低功耗和良好的外设支持。 |
| 医疗设备 | 广泛应用于便携式医疗设备中,如:血糖监测仪、心率监测器、便携式超声设备等,这些设备需要精确的传感器数据采集和处理。 |
| 工业自动化控制 | PLC可编程逻辑控制器、工业机器人、伺服电机控制等STM32 能够处理复杂的控制算法和实时任务。 |
| 汽车电子 | 用于汽车中的传感器管理、车载信息娱乐系统、车身控制系统(车窗、电动座椅调节等)。 |
> [!NOTE]
>
> 总结STM32 微控制器在物联网、消费电子、医疗设备和工业控制等领域表现出色,非常适合使用 C 语言来进行开发,因为 C 语言允许直接进行硬件控制并支持复杂的应用开发。
## 2.4 ARM 架构(特别是 ARM Cortex 系列)
* `背景`ARM 是一种广泛使用的处理器架构特别是在嵌入式系统中ARM Cortex 系列处理器(如 Cortex-M、Cortex-R 和 Cortex-A非常流行。Cortex-M 系列主要用于微控制器Cortex-R 用于实时系统Cortex-A 则用于高性能嵌入式系统。
* `开发工具`:针对 ARM 架构的开发,常用工具包括 ARM Keil MDK、IAR、GCC for ARM 和 ARM Development Studio。这些工具均支持使用 C 语言进行开发。
* `C 语言的作用`C 语言在 ARM 架构上的应用广泛。它被用于操作系统内核(如 FreeRTOS、Zephyr、设备驱动、应用层逻辑等。在 ARM Cortex-M 和 Cortex-R 系列中C 语言的高效性和低级别硬件访问能力是开发实时、低延迟系统的关键。
* `应用场景`
| 应用场景 | 描述 |
| ------------------ | ------------------------------------------------------------ |
| 高级嵌入式操作系统 | ARM Cortex-A 系列处理器广泛用于运行 Linux、Android 等操作系统的嵌入式设备,如:智能手机、平板电脑、智能电视和车载娱乐系统。 |
| 实时系统 | ARM Cortex-R 系列处理器用于实时系统,如:汽车的 ABS防抱死制动系统、ESC电子稳定控制系统以及航空电子设备这些系统要求极低的延迟和高可靠性。 |
| 高性能物联网网关 | Cortex-A 系列处理器可以用来开发支持多协议、多设备管理的物联网网关,这些网关通常需要强大的计算能力和多线程处理能力。 |
| 边缘计算设备 | 在边缘计算场景中ARM Cortex-A 处理器用于执行本地数据处理和决策,如:视频分析、图像处理、语音识别等。 |
| 智能家居设备 | ARM Cortex-M 系列微控制器广泛应用于智能家居产品,如:智能灯泡、智能音箱、家庭安全系统,这些设备需要高效的处理能力和低功耗。 |
| 机器人控制系统 | ARM Cortex-M 和 Cortex-A 系列处理器用于机器人系统的控制和通信,如:无人机、工业机器人、服务机器人等,处理复杂的运动控制、路径规划和传感器数据融合。 |
> [!NOTE]
>
> 总结ARM Cortex 系列适用于从实时系统到高级嵌入式操作系统的各类应用,支持从低功耗控制到高性能计算的多种需求,非常适合使用 C 语言来进行开发,因为 C 语言不仅用于控制硬件,还广泛应用于操作系统和应用程序的开发。
# 第三章C 语言和其他编程语言的对比
## 3.1 C 语言和 C++ 语言的对比
* 起源和发展:
* C 语言C 语言由丹尼斯·里奇Dennis Ritchie在 1972 年开发,最初用于开发操作系统,特别是 UNIX。它是一种结构化的编程语言提供了对硬件的低级访问且效率高因此在系统编程中广泛使用。
* C++ 语言C++ 由比雅尼·斯特劳斯特鲁普Bjarne Stroustrup在 20 世纪 80 年代初开发,作为 C 语言的扩展。它引入了面向对象编程的概念,同时保留了 C 语言的高效性和底层操作能力。C++ 最初被称为 “C with Classes”带类的 C后来发展成一种独立的编程语言。
* 兼容型:
* 语法兼容C++ 几乎完全兼容 C 语言的语法,这意味着大多数 C 代码可以在 C++ 编译器下直接编译运行。C++ 可以看作是 C 语言的超集(虽然不完全是 100% 兼容,但差异较少)。
* 扩展性C++ 在 C 的基础上增加了许多新特性,如:类和对象、继承、多态、模板和异常处理等。这使得 C++ 不仅适合系统编程,还可以用于开发复杂的应用程序。
* 编程范式:
* C 语言:主要是面向过程编程,强调的是函数调用和控制结构。
* C++ 语言:支持多种编程范式,包括:面向过程、面向对象和泛型编程,使得开发者可以更灵活地选择适合的编程风格。
* 性能与应用:
* 性能:由于 C++ 包含了更多的高级特性,它的编译时间和运行时开销可能比 C 稍高。但得益于其优化机制C++ 仍然可以实现与 C 语言相近的性能。
* 应用场景C 语言仍然在嵌入式系统、驱动程序开发和其他对性能要求极高的场合中占据重要地位。而 C++ 则被广泛用于游戏开发、图形处理、大型软件系统等需要复杂结构和抽象的领域。
> [!NOTE]
>
> * ① C++ 是 C 语言的继承者和扩展,它保留了 C 语言的优势,并引入了更多现代编程语言的特性,使得它在更广泛的应用领域中得到应用。
> * ② 但是目前而言C 语言和 C++ 语言已经是完全不同的语言了,因为 C++ 语言吸收了太多其他编程语言的特性,造成 C++ 语言非常复杂和繁琐,也被人称为“史上最复杂的语言,没有之一”。
## 3.2 C 语言和 Java 语言的对比
* C 语言 和 Java 语言的软件设计思想对比,如下所示:
> [!NOTE]
>
> * ① Java 语言编写的应用是直接运行在 JVMJava 虚拟机)上,体现了`分层`的软件设计思想;并且,这种`分层`的软件设计思想给 Java 语言带来了`跨平台性`和`自动内存管理`等方面的功能。
> * ② C 语言编写的应用是直接运行在操作系统之上,其设计哲学是:`简洁、高效、直接控制底层`。
![](./assets/10.svg)
* 虽然 C 语言和 Java 语言有很多相似之处,但在设计理念、运行环境、内存管理等方面有显著差异,如下所示:
| 对比角度 | C 语言 | Java 语言 |
| ------------ | ----------------------------------------------------- | ------------------------------------------------------- |
| 编译与解释 | 编译型语言,源代码编译为机器码直接执行,效率高。 | 解释与编译结合,源代码编译为字节码,通过 JVM 解释运行。 |
| 平台依赖性 | 与操作系统和硬件平台紧密结合,跨平台能力较弱。 | 通过 JVM 实现跨平台,"编写一次,到处运行"。 |
| 内存管理 | 手动管理内存,需显式分配与释放,容易出现内存泄漏。 | 自动垃圾回收,简化内存管理,降低内存泄漏风险。 |
| 指针 | 支持指针,能直接操作内存,但可能导致安全问题。 | 不支持指针操作,避免内存安全隐患。 |
| 编程范式 | 过程化编程,主要通过函数调用组织程序。 | 完全的面向对象编程,一切皆为对象。 |
| 异常处理 | 不支持异常处理,错误处理通过返回值或全局变量实现。 | 提供强大的异常处理机制,通过 try-catch-finally 块处理。 |
| 标准库与生态 | 标准库简洁,需大量使用第三方库开发复杂应用。 | 标准库丰富,拥有庞大生态系统和社区支持。 |
| 运行时性能 | 直接编译成机器码,性能高,适合高性能要求的场景。 | 运行在虚拟机上,性能稍低,但通过 JIT 等优化提升效率。 |
| 多线程支持 | 依赖操作系统 APIpthread多线程编程较为复杂。 | 内置多线程支持,提供 Thread 类和并发工具类。 |
| 应用场景 | 系统级编程,如操作系统、嵌入式系统、驱动程序等。 | 企业级应用、Web 开发、Android 开发、大数据处理等。 |
> [!IMPORTANT]
>
> 总结而言:
>
> * ① C 语言适合底层编程、系统级开发,性能高、控制力强,但对程序员的要求也更高。而 Java 语言则更适合应用层开发,拥有丰富的库和工具支持,开发效率更高,并且由于自动内存管理和异常处理,编写的代码通常更加安全和健壮。
> * ② 两者各有优势,选择使用哪种语言应根据项目需求和开发环境来决定。
# 第四章 C 语言的优缺点
## 4.1 概述
* 当今繁荣昌盛的互联网世界是建立在 C 语言基础之上的,如:
* ① 操作系统C 语言设计的初衷就是用来编写操作系统。目前所有的主流操作系统内核,所采用的编程语言都是 C 语言。
* ② 网络协议栈:一般和内核采用相同的语言实现,也就是 C 语言。
* ③ WEB 服务器和 HTTP 服务器Apahce、NGINX 是采用 C 语言编写的Tomcat 是采用 Java 语言编写的,只能运行 Java 应用程序。
* ④ 关系型数据库MySQL 是采用 C/C++ 语言编写的,而 PostgreSQL 和 SQLite 主要由 C 语言编写的。
* ⑤ 非关系型数据库Redis 主要由 C 语言编写的MongoDB 是由 C++ 语言编写的,而 Elasticsearch 由 Java 语言编写的。
* ...
> [!NOTE]
>
> * ① C/C++ 非常适合做基建开发,而 Java 和 Go 等非常适合做业务开发。
> * ② 近几年Rust 语言很火,有望替代 C/C++ 做基建开发,因为其是内存安全的,并且没有 GC垃圾收集器
* C 语言是一门接近“低级语言”的“中级语言”,如下所示:
![](./assets/24.svg)
## 4.2 C 语言的优点
* ① C 语言是一门接近硬件层面的编程语言,提供了接近硬件的操作能力。
> [!NOTE]
>
> * ① C 语言通过提供直接内存访问、指针操作和系统调用等功能,允许程序员以接近硬件的方式编写代码。
> * ② 这种能力使得 C 语言特别适合用于嵌入式系统开发以及系统编程。
* ② C 语言拥有在所有编程语言中几乎独一档的高运行效率。
> [!NOTE]
>
> * ① C 语言提供了接近硬件的操作能力,这意味着 C 程序可以更好的利用硬件资源。
> * ② C 语言编译器将源代码直接编译成机器代码(或非常接近的汇编语言),而非解释执行或编译为中间代码。
> * ③ C 语言还提供了各种特性使得程序员可以控制优化 C 程序的几乎每一个细节。如C 语言的手动内存分配控制,这意味着可以精确地管理资源使用,从而提高效率。
> * ④ 在平均一般情况下如果一个C程序的执行速度是 100%,那么:
> * C++ 可能由于复杂性的影响,性能会轻微下降,一般是 95% 左右。
> * Java 由于JVM等特性的影响运行效率一般低于 C/C++,大概在 50%-80% 范围内。
> * Python 是一种脚本语言,需要解释执行,效率很差,可能在 5%-30% 之间。
* ③ C 语言的语法非常简洁,没有太多复杂的特性。
> [!NOTE]
>
> * ① 作为一门接近硬件的编程语言C 语言的抽象层次很低,没有很多高级的抽象特性。
> * ② 这使得 C 语言简单易学同时对于想要深入理解计算机原理的人来说C 语言的低抽象性也可以使得学习者可以更好的忽略语言特性,关注具体原理。
* ④ C 语言作为一门"中级语言"市面上流行的编程语言基本都可以找到它的影子C-like 语言),所以学习 C 语言对于学习其他编程语言也有很大的帮助。
> [!NOTE]
>
> 很多类 C 的编程语言都有 C 语言的身影C++、Java 等。
* ⑤ C 语言的生命力旺盛,从诞生到如今始终都是最流行的开发语言之一。
## 4.3 C 语言的缺点
* ① C 语言是一门非常容易出错,却非常不容易发现错误的编程语言。
> [!NOTE]
>
> * ① C 语言的语法相对`非常宽松`和`灵活`,给予了程序员很大的自由度,但出错的概率也大大增加了。
> * ② C 语言给程序员很大的自主性和控制权限,但即便是熟练的 C 程序员也无法保证能够完美的控制程序,如:内存管理,手动的内存管理不仅增加了编程的复杂性,而且非常容易出错,非常容易造成内存泄漏和使用未初始化的内存导致未定义行为。
> * ③ C 语言追求效率所以没有专门的异常机制来指示程序出现的问题。C 程序甚至不会去检查数组下标越界的问题。
> * ...
* ② C 语言缺少一些必要的高级特性,使得 C 程序的可维护性很差。
> [!NOTE]
>
> 一个复杂的 C 程序,如果在设计之初没有考虑到维护问题,那么将很难对它做出修改或扩展。(这也是 C++ 出现的目的)
* ③ 相比较现代的高级语言C 语言经常可以写出可读性十分差的代码。
> [!NOTE]
>
> * ① 一方面是由于 C 语言作为一门小型语言,它缺乏一些现代高级语言中的特性,并且其标准库相对较小。因此,程序员往往需要自行编写复杂的代码实现,这些代码对于其他人可能难以理解。
> * ② 另一方面C 语言诞生于编程发展的初期,那时的编程哲学倾向于代码的极致简洁性。这种风格有时会导致代码过于晦涩难懂,尤其是当程序员过分追求聪明的技巧时,可能会编写出只有自己能理解的代码。
> * ③ 在现代编程中,尤其是团队协作环境下,高度重视代码的可读性和维护性。因此,强调编写清晰易读的 C 代码,而不是单纯追求代码的简洁。
* ④ C 语言的核心语法特性在不同编译器和平台之间是保持一致的,这是因为不同平台的编译器实现都必须遵循 C 语言的标准ISO C标准。这确保了无论在 Windows 还是 Linux 平台上,基本的语法、控制结构和数据类型等基础元素都是相同的。
> [!NOTE]
>
> * ① 由于 C 语言提供了接近操作系统层面的编程能力,当涉及到与操作系统直接交互的特定功能,如:系统调用或使用特定平台的库函数时,就会出现不同平台间的实现差异。
> * ② `这些差异并不是由 C 语言本身的语法差异引起的,而是由不同操作系统平台的不同特点所引起的`。
> * ③ 这种差异性一方面影响了 C 语言的跨平台性,也增加了 C 语言的学习成本,例如:尽管 Windows 和 Linux 平台上的 C 语言核心编程逻辑相似,但在实现平台特定功能时所需的 API 调用和编程细节可能大不相同。
> * ④ 需要注意的是,尽管存在平台间的差异,但这并不意味着 Windows 和 Linux 下的 C 语言是两种截然不同的语言。适应不同的平台环境和编程接口对程序员而言,不算什么特别困难的事情。