Skip to content

🔥更新:2024-12-30📝字数: 0 字⏱时长: 0 分钟

第一章:C 语言的学习技巧

1.1 如何学习 C 语言?

  • 对于大部分的初学者, 学习 C 语言的目的可能是为了成为一名合格的程序员,开发出优秀的软件。但是,在学习了 C 语言的基本语法后,却发现只能在控制台黑底白字)上玩玩,没有漂亮的用户界面以及人性化的交互。于是,开始学习数据结构和算法数据库操作系统,越陷越深,越来越迷茫,不知道学习 C 语言能做什么,认为学习编程很难,开始怀疑自己,直到放弃!!!
  • 其实,C 语言本身就是一门非常简单的语言,提供的实用功能不多,大部分的时候需要借助操作系统、第三方库以及以及一些硬件,如:单片机等,才能发挥它的威力!!!

重要

  • ① 学习 C 语言仅仅是让你踏上程序员之路的第一步而已,只学习 C 语言也做不了什么。
  • ② 系统、扎实的学习 C 语言可以让你了解底层硬件、一些简单的数据结构和算法,并培养计算机思维。
  • 前文,我们提过:C 语言是一门通用性的语言,并没有针对某个领域进行优化。并且,在实际项目中,C 语言主要用于比较底层的开发,例如:
    • Windows、Linux、Unix 等操作系统的内核 90% 以上都使用 C 语言开发(Rust 语言有望未来,在操作系统开发中占据一席之地,特别是在对安全性和性能要求极高的领域)。
    • 开发硬件驱动,让硬件和操作系统连接起来,这样用户才能更有效的使用硬件。
    • 单片机和嵌入式属于软硬件的结合,是使用 C 语言最多的地方。
    • 开发系统组件或服务,用于支撑上层应用。
    • 如果对软件某个模块,例如:算法和搜索部分的效率要求较高,也可以使用 C 语言来开发。
    • ……
  • 貌似感觉 C 语言的应用还是很多的啊,那为什么感觉学习 C 语言还是做不了什么?原因除了 C 语言通常都是开发最底层的应用之外,最重要的一点就是生态

重要

现代化的高级编程语言的流行程度,除了和编程语言的设计是否优秀有关,最主要的原因就是生态

  • ① 很多编程语言都自带标准库(语言本身提供的,开箱即用),如:Java、Go 等。
  • ② 很多编程语言都有自己的包管理器(用于管理第三方库)解决方案,如:Java 中的 Maven、Gradle、Go 中的 go modules ,JavaScript 的 npm 等。

遗憾的是,C 语言的标准库非常简单,只有输入输出文件操作日期时间字符串处理内存管理,对于网络编程GUI数据库并发需要大量的第三方库操作系统的功能来扩展 C 语言的功能(Java 语言、Go 语言等其他的现代化高级编程语言,都是直接将这些常见的开发场景内置到标准库中,开箱即用,极大的降低了软件开发的难度)。

C 语言的第三方库也不是很多(和其它现代化高级编程语言相比,C 语言的大多数的第三方库都是底层库,支持应用开发的库寥寥无几,只有一个 GTK 库能够开发出桌面软件,几乎没有网站开发以及 APP 开发相关的库),社区也不是很活跃(和其它现代化高级编程语言相比),更别提缺少自己的包管理器。

提醒

  • ① 换言之,在实际工作中,C 语言几乎是不用做软件、网站、APP 等这些应用层开发,其它的编程语言能够更好地完成任务,没必要非得使用 C 语言,C 语言基本都是用来做底层开发,也就是看不见摸不着的、在后台默默提供服务的那些项目,而这样的项目对初学者来说基本没有实用价值,初学者也不知道它们该怎么使用。

  • ② 初学者想要的 C 语言没有,C 语言能做的初学者用不到,就是这种矛盾,导致初学者非常迷茫。

  • ③ 有人可能会问,C 语言不是还可以用来开发单片机或者嵌入式吗?是的没错,但是这个方向是软硬件结合的,不是在我们的电脑上进行开发,而是在特殊的板子上进行开发,并且还需要学习数字电路、模拟电路、8051/ARM、RTOS、嵌入式 Linux 等方面的知识,只学 C 语言也没有用武之地。

  • ④ 如果你觉得学了 C 语言没用,那么恭喜你,你是对的,应用层的开发一般真的用不上它。

  • ⑤ 但是,没用也要学,学习 C 语言并不一定是要应用它,C 语言可以夯实你的编程基础,尤其是数据结构、算法、内存、线程、进程、通信、操作系统、编译原理等底层的计算机知识,没有 C 语言基础是学不好的。

  • ⑥ 这些底层知识并不一定能够直接应用在实际开发中,但是它们会让你有底气,会让你透彻地理解编程概念,会让你站的“低”看得远,会让你避免很多低级错误,会让你心中有“架构师”的思维。

重要

不过,现在 C 语言社区也开始诞生了一些包管理器,如:Conan 和 vcpkg ;也有自己的项目构建工具,如:cmake 、xmake 等。

提醒

JavaScript 的作者 Brendan Eich(布兰登·艾奇) 曾经这么说:“与其说我爱 JavaScript,不如说我恨它。它是 C 语言和 Self 语言一夜情的产物(致敬 C 语言)。十八世纪英国文学家约翰逊博士说得好:"它的优秀之处并非原创,它的原创之处并不优秀。"”

1.2 项目构建工具和包管理器

1.2.1 概述

  • 项目构建工具包管理器在软件开发中扮演着不同的角色,它们虽然有时会有重叠的功能,但主要关注的点是不同的。

1.2.2 项目构建工具

  • 项目构建工具是用于自动化编译、测试、打包、部署等一系列任务的软件工具。它们帮助开发者简化和管理整个软件开发生命周期中的各个步骤,尤其是在构建过程中的复杂性管理上。
  • 其功能有:
功能描述
编译代码自动编译源代码(如 :.java等)为可执行文件或中间文件(如:.class 文件)。
运行测试集成单元测试、集成测试,自动运行测试用例并生成报告。
打包集成单元测试、集成测试,自动运行测试用例并生成报告。
依赖管理自动下载、更新和管理项目所需的第三方库(这部分功能有时与包管理器重叠)。
部署将打包后的应用程序自动部署到测试环境、生产环境等。
任务自动化除了基本的构建流程外,还可以自动化执行一些常见任务,如:代码检查、文档生成等。
  • 常用的项目构建工具:
项目构建工具支持语言描述
MavenJava一个流行的构建工具和依赖管理工具,广泛用于 Java 项目。
GradleJava一个灵活的构建工具,支持声明式的构建脚本和多种语言。
MakeC/C++一个经典的构建工具,使用 Makefile 来定义构建规则和依赖关系。
CMakeC/C++一个跨平台的构建系统,帮助生成标准的构建文件。
.........

1.2.3 包管理器

  • 包管理器是用于自动化安装、更新、配置管理软件包及其依赖关系的工具。它主要关注于获取和管理项目所需的第三方库或工具包,并确保它们正确地集成到项目中。
  • 其功能有:
功能描述
依赖管理根据项目配置文件(如:package.json)自动下载和安装项目所需的依赖包。
版本控制管理包的版本,允许开发者指定某个特定版本或版本范围,确保项目中的库版本一致性。
包的发布和共享开发者可以通过包管理器发布自己的库,并且共享给社区或组织内部的其他项目使用。
环境隔离有些包管理器提供虚拟环境功能,可以将不同项目的依赖隔离开,避免版本冲突。
更新和卸载包管理器可以自动更新依赖包到最新的兼容版本或卸载不再需要的包。
  • 常见的包管理器:
包管理器支持语言/平台描述
npmJavaScript、Node.js用于管理 JavaScript 和 Node.js 项目的包和模块。
pipPython用于安装和管理 Python 的软件包。
CargoRustRust 编程语言的包管理器和构建工具。
yarnJavaScriptyarn 是 npm 的替代品,提供更快和更可靠的包管理体验。
HomebrewMacOS用于 MacOS系统下的命令行工具和库的管理。
.........

1.2.4 注意事项

  • 对于 Java 项目中的 MavenGradle 而言,其不仅是项目构建工具也是包管理工具

提醒

  • ① 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 等支持的特性多,用起来方便,开发效率高。

重要

  • ① C 语言的优势是运行效率极高,这正是底层开发所看重的。
  • ② 底层开发有时候就是一个模块,或者是一个服务,规模不算大,但是对效率有严格的要求,此时用 C 语言就非常合适,所以针对底层开发的 C 语言库较多,因为它们有非常大的实用价值。

第二章:嵌入式领域中的 C 语言

2.1 概述

  • C 语言在 C51、STM32 和 ARM 平台上的应用场景非常广泛,涵盖了各种嵌入式系统的开发需求。

2.2 C51(8051 系列微控制器)

  • 背景:8051 是由 Intel 于 1980 年设计的一种 8 位微控制器架构。它具有指令集简单、结构紧凑的特点,广泛应用于低端嵌入式系统中。
  • 开发工具:C51 是指针对 8051 系列微控制器的 C 语言编译器,如:Keil C51。这种编译器将 C 语言代码编译为适合 8051 架构的汇编代码。
  • C 语言的作用:C 语言在 8051 微控制器上的应用使得开发更加高效和可维护。尽管 8051 的硬件资源有限,但 C 语言仍然能够在不损失性能的前提下提供高级编程的便利。
  • 应用场景
应用场景描述
简单的控制系统家用电器(微波炉、洗衣机、空调)的控制板等。
这些设备通常不需要复杂的运算能力,但要求可靠和稳定的控制。
低功耗传感器接口常用于低功耗传感器的数据采集和传输,如:温度、湿度、压力传感器。
工业自动化设备用于简单的工业自动化控制,如:小型电机驱动、工业传感器数据处理和传输。
电子玩具许多简单的电子玩具使用 8051 系列微控制器来控制声音、LED 灯光、显示屏等。

提醒

C51 微控制器适用于资源受限、需要低成本的简单控制系统,非常适合使用 C 语言来进行开发!!!

2.3 STM32(STM32 系列微控制器)

  • 背景:STM32 是意法半导体(STMicroelectronics)推出的一系列基于 ARM Cortex-M 内核的 32 位微控制器。它们广泛用于需要高性能和低功耗的嵌入式应用中,如:工业控制、消费电子和物联网设备。
  • 开发工具:开发 STM32 微控制器通常使用 Keil、IAR Embedded Workbench 或 STM32CubeIDE 等开发环境。这些环境中使用的编程语言主要是 C(有时也包括 C++)。
  • C 语言的作用:C 语言在 STM32 上的应用非常广泛,开发者可以利用它直接控制硬件寄存器,同时也能方便地使用 STM32 提供的 HAL(硬件抽象层)库或 LL(低层)库进行开发。C 语言在这个平台上不仅能实现底层控制,还能编写复杂的应用逻辑。
  • 应用场景
应用场景描述
物联网设备常用于各种物联网设备,如:智能家居控制系统、环境监测设备、可穿戴设备等。
这些设备通常需要低功耗和强大的处理能力,并且需要支持多种通信协议,如:Wi-Fi、Bluetooth 等。
消费电子智能手表、健身追踪器、电子书阅读器、无人机等,这些设备需要具备实时处理能力、低功耗和良好的外设支持。
医疗设备广泛应用于便携式医疗设备中,如:血糖监测仪、心率监测器、便携式超声设备等,这些设备需要精确的传感器数据采集和处理。
工业自动化控制PLC(可编程逻辑控制器)、工业机器人、伺服电机控制等,STM32 能够处理复杂的控制算法和实时任务。
汽车电子用于汽车中的传感器管理、车载信息娱乐系统、车身控制系统(车窗、电动座椅调节等)。

提醒

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 系列处理器用于机器人系统的控制和通信,如:无人机、工业机器人、服务机器人等,处理复杂的运动控制、路径规划和传感器数据融合。

提醒

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++ 则被广泛用于游戏开发、图形处理、大型软件系统等需要复杂结构和抽象的领域。

提醒

  • ① C++ 是 C 语言的继承者和扩展,它保留了 C 语言的优势,并引入了更多现代编程语言的特性,使得它在更广泛的应用领域中得到应用。
  • ② 但是,目前而言,C 语言和 C++ 语言已经是完全不同的语言了,因为 C++ 语言吸收了太多其他编程语言的特性,造成 C++ 语言非常复杂和繁琐,也被人称为“史上最复杂的编程语言,没有之一”。

3.2 C 语言和 Java 语言的对比

  • C 语言 和 Java 语言的软件设计思想对比,如下所示:

提醒

  • ① Java 语言编写的应用是直接运行在 JVM(Java 虚拟机)上,体现了分层的软件设计思想;并且,这种分层的软件设计思想给 Java 语言带来了跨平台性自动内存管理等方面的功能。
  • ② C 语言编写的应用是直接运行在操作系统之上,其设计哲学是:简洁、高效、直接控制底层
  • 虽然 C 语言和 Java 语言有很多相似之处,但在设计理念、运行环境、内存管理等方面有显著差异。

提醒

点我查看 C 语言和 Java 语言之间的差异
对比角度C 语言Java 语言
编译与解释编译型语言,源代码编译为机器码直接执行,效率高。解释与编译结合,源代码编译为字节码,通过 JVM 解释运行。
平台依赖性与操作系统和硬件平台紧密结合,跨平台能力较弱。通过 JVM 实现跨平台,"编写一次,到处运行"。
内存管理手动管理内存,需显式分配与释放,容易出现内存泄漏。自动垃圾回收,简化内存管理,降低内存泄漏风险。
指针支持指针,能直接操作内存,但可能导致安全问题。不支持指针操作,避免内存安全隐患。
编程范式过程化编程,主要通过函数调用组织程序。完全的面向对象编程,一切皆为对象。
异常处理不支持异常处理,错误处理通过返回值或全局变量实现。提供强大的异常处理机制,通过 try-catch-finally 块处理。
标准库与生态标准库简洁,需大量使用第三方库开发复杂应用。标准库丰富,拥有庞大生态系统和社区支持。
运行时性能直接编译成机器码,性能高,适合高性能要求的场景。运行在虚拟机上,性能稍低,但通过 JIT 等优化提升效率。
多线程支持依赖操作系统 API(如:pthread),多线程编程较为复杂。内置多线程支持,提供 Thread 类和并发工具类。
应用场景系统级编程,如操作系统、嵌入式系统、驱动程序等。企业级应用、Web 开发、Android 开发、大数据处理等。

重要

总结:

  • ① C 语言适合底层编程、系统级开发,性能高、控制力强,但对程序员的要求也更高。
  • ② Java 语言则更适合应用层开发,拥有丰富的库和工具支持,开发效率更高,并且由于自动内存管理和异常处理,编写的代码通常更加安全和健壮。
  • ③ 两者各有优势,选择使用哪种语言应根据项目需求和开发环境来决定。

Released under the MIT License.