import{_ as l,c as i,o as s,a6 as a}from"./chunks/framework.CZRoMP2i.js";const e="/c/assets/1.D4a42fT1.jpg",t="/c/assets/2.D2wnxl5F.png",n="/c/assets/3.Dq625oo9.jpg",o="/c/assets/4.uqu1DEK4.png",c="/c/assets/5.C6Q0Q8kf.jpg",d="/c/assets/6.B4Srsb-0.png",p="/c/assets/7._D_c8Lrn.png",r="/c/assets/8.DlIyFGDg.png",h="/c/assets/9.7zkUmpQw.png",u="/c/assets/10.h1ugtjyX.png",k="/c/assets/11.D5PWTabw.png",b="/c/assets/12.Bvs6QYjl.jpg",C="/c/assets/9.7zkUmpQw.png",g="/c/assets/14.CsR5exrN.png",m="/c/assets/15.BRG9GQdT.png",E="/c/assets/16.C2sciGZn.png",y="/c/assets/17.DdyXXyxJ.png",v="/c/assets/18.DIeb_KXW.png",A="/c/assets/19.C-kvMz2p.png",x="/c/assets/20.CQqFxmDa.png",_="/c/assets/21.CjMWyIiX.png",f="/c/assets/22.DFQhcDgs.png",P="/c/assets/23.Cco1vsW8.png",L=JSON.parse('{"title":"第一章:计算机组成原理","description":"","frontmatter":{},"headers":[],"relativePath":"notes/01_c-basic/00_xdx/index.md","filePath":"notes/01_c-basic/00_xdx/index.md","lastUpdated":1724099162000}'),S={name:"notes/01_c-basic/00_xdx/index.md"},T=a('
IMPORTANT
面向过程
的编译型
的编程语言
,其最大特点在于 运行速度极快
,仅次于汇编语言
,这使得 C 语言在需要高性能的场景中得到广泛应用,如:操作系统、硬件驱动程序和嵌入式系统。然而,开发效率较低
也是 C 语言的一大特点,程序员需要手动管理内存和处理低级别的操作,这对编程能力要求较高。编程
语言,更是计算机行业的核心
语言。它是计算机专业的基础课程,无论是操作系统的构建、硬件驱动的开发,还是数据库系统的实现,都离不开 C 语言的支持。学习 C 语言
不仅是掌握编程技能的必经之路,也是深入理解计算机底层原理的关键。如果忽视了 C 语言的学习,将难以深入理解计算机系统的工作原理,也很难在计算机行业中取得长远的发展。NOTE
总结就是一句话:C 语言重要(赞),很重要(大赞),非常重要(非常赞),绝对重要(无敌赞),史无前例的重要(一赞到底)!!!
"电脑"
,是一种能够接收和存储信息,并按照存储在其内部的程序对海量的数据进行自动、高速的处理,然后将处理结果输出的现代化智能电子设备。计算机系统
由硬件(Hardware)系统
和软件(Software)系统
两大部分组成,即:冯·诺依曼
是一位多才多艺的科学家,他在数学、物理学、计算机科学、经济学等领域都有杰出的贡献。冯·诺依曼
的主要成就: 冯·诺依曼
体系结构(1946 年),这是现代计算机设计的基础
。IMPORTANT
冯·诺依曼体系结构
是现代计算机(量子计算机除外)设计的基础
。
冯·诺依曼
体系结构的理论要点如下:
程序指令
和数据
都存储在计算机的内存中,这使得程序可以在运行时修改。数据
和指令
都以二进制
形式表示。运算器
、控制器
、存储器
、输入设备
和输出设备
组成。NOTE
上述的组件协同工作,构成了一个完整的计算机系统:
运算器
和控制器
通常被集成在一起,组成中央处理器(CPU),负责数据处理和指令执行。存储器
(内存)保存数据和程序,是计算机运作的基础。输入设备
和输出设备
负责与外界的交互,确保用户能够输入信息并接收计算机的处理结果。硬盘
的读写速率已经成为影响系统性能进一步提高的瓶颈。1 秒 = 1000 毫秒,即 1 s = 1000 ms。
1 毫秒 = 1000 微妙,即 1 ms = 1000 us 。
1 微妙 = 1000 纳秒,即 1 us = 1000 ns。
如果 CPU 的时钟周期按照 1 秒计算,
那么,内存访问就需要 6 分钟;
那么,固态硬盘就需要 2-6 天;
那么,传统硬盘就需要 1-12 个月;
那么,网络访问就需要 4 年以上。
蜉蝣
来表示时间的短暂(和其他生物的寿命比),也是类似的道理,即:鹤寿千岁,以极其游,蜉蝣朝生而暮死,尽其乐,盖其旦暮为期,远不过三日尔。
--- 出自 西汉淮南王刘安《淮南子》
寄蜉蝣于天地,渺沧海之一粟。 哀吾生之须臾,羡长江之无穷。
挟飞仙以遨游,抱明月而长终。 知不可乎骤得,托遗响于悲风。
--- 出自 苏轼《赤壁赋》
NOTE
对于蜉蝣
来说,从早到晚就是一生;而对于我们人类
而言,却仅仅只是一天。
NOTE
上图以层次化的方式,展示了价格信息,揭示了一个真理,即:鱼和熊掌不可兼得。
IMPORTANT
CPU 都是直接和内存打交道的,即:CPU 会直接从内存中读取数据,待数据处理完毕之后,会将结果再次写入到内存中;如果需要将数据持久化(永久)保存(内存是易失性存储器,内存中的数据是以电荷形式存储在存储单元中的。当计算机关闭或断电时,这些电荷很快消散,导致存储在内存中的数据丢失),那么就需要将内存中的数据再刷新到磁盘或硬盘上,即:落盘。
系统调用
:是一套已经写好的代码接口,应用程序通过调用这些接口来请求操作系统执行特定的硬件操作。它们直接与硬件交互,提供底层功能支持,如:文件操作、进程管理、内存管理等。开发者
通过系统调用可以实现对底层资源的直接控制,确保程序能够高效、安全地运行。终端命令
:是一种文本命令接口,通过命令行输入各种指令来控制操作系统和软件的行为。终端命令可以执行文件操作、系统配置、网络管理等各种任务。主要针对开发人员
和高级用户
,他们通过命令行可以快速、精确地完成各种操作,提高工作效率。图形用户界面
(GUI)是通过图形元素(如:窗口、图标、按钮等)与用户进行交互的界面。供直观、易用的操作方式,使用户能够通过鼠标点击、拖拽等简单操作完成复杂任务。主要面向普通用户
,降低了计算机操作的门槛,提高了用户体验和工作效率。用户态(User Mode)
和内核态(Kernel Mode)
是两种不同的执行模式,它们对系统资源的访问权限有着本质的区别。这种区分是为了提供一个稳定和安全的运行环境,防止用户程序直接操作硬件设备和关键的系统资源,从而可能引起系统的不稳定或安全问题。类型 | 内核态(Kernel Mode) | 用户态(User Mode) |
---|---|---|
权限 | 内核态是操作系统代码运行的模式,拥有访问系统全部资源和执行硬件操作的最高权限 。在这种模式下,操作系统的核心部分可以直接访问内存、硬件设备控制、管理文件系统和网络通信等。 | 用户态是普通应用程序运行的模式,具有较低 的系统资源访问权限。在用户态,程序不能直接执行硬件操作,必须通过操作系统提供的接口(即系统调用)来请求服务。 |
安全性 | 由于内核态具有如此高的权限,因此只有可信的、经过严格审查的操作系统核心组件才被允许在此模式下运行。这样可以保护系统不被恶意软件破坏。 | 用户态为系统提供了一层保护,确保用户程序不能直接访问关键的系统资源,防止系统崩溃和数据泄露。 |
功能 | 内核态提供了系统调用 的接口,允许用户态程序安全地请求使用操作系统提供的服务,比如:文件操作、网络通信、内存管理等。 | 用户态保证了操作系统的稳定性和安全性,同时也使得多个程序可以在相互隔离的环境中同时运行,避免相互干扰。 |
NOTE
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
public class Demo {
public static void writeFile(String filePath, String content) {
Path path = Paths.get(filePath);
try {
Files.write(path, content.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
int a = 10; // 用户态
int b = 20; // 用户态
int c = a + b; // 用户态
string filePath = "c:/demo.txt"; // 用户态
string txt = a + b + c; // 用户态
writeFile(filePath, a); // 从用户态切换到内核态完成文件写入
System.out.println(a); // 从内核态切换回用户态
System.out.println(b); // 用户态
System.out.println(c); // 用户态
}
}
NOTE
操作系统层
与由操作系统管理的应用程序
和库
分开。ABI 涵盖了低级数据类型、对齐方式和调用约定等详细信息,并定义了可执行程序的格式。系统调用在此级别定义。此接口允许应用程序和库在实现相同 ABI 的操作系统之间移植。NOTE
PE
(portable executable)格式、.dll
(dynamic link library)格式和 .lib
格式;而在 Linux 上的应用程序的运行格式是:ELF
(executable and linking format)格式、.so
(shared object)格式和 .a
格式。file /bin/ls
命令查看指定可执行应用程序的 ABI 格式;从而也可以论证,在 Windows 上可以运行的程序,在 Linux 上运行不了。一套代码,多平台编译
的方式(针对 C 或 C++ 等),即:相同的源代码,在不同平台(操作系统)上使用特定平台的编译器(如:GCC)来分别编译成符合自己平台的 ABI 规范的二进制文件。应用程序
连接到库
或底层操作系统
。NOTE
系统调用(System Call)
和函数库(Library Call)
的身影,如下:系统调用(System Call)
和函数库(Library Call)
的区别如下:类型 | 系统调用(System Call) | 函数库(Library Call) |
---|---|---|
定义 | 系统调用是操作系统提供给程序员的一组接口,这些接口允许用户空间的程序请求操作系统内核提供的服务,比如文件操作、进程控制、通信和内存管理等。 | 函数库调用是指使用高级语言编写的一组预先编译好的函数,这些函数实现了一些常用的功能,比如:字符串处理、数学计算等。程序员可以在自己的程序中直接调用这些函数,而无需重新实现它们。 |
权限 | 执行系统调用时,会从用户态切换到内核态。这是因为系统调用涉及到访问受保护的系统资源,这些操作必须由操作系统控制以确保系统的稳定性和安全性。 | 函数库调用通常在用户态执行,不涉及到用户态与内核态之间的切换。它们直接使用操作系统通过系统调用提供的服务,或者完全在用户空间内完成计算,不需要操作系统介入。 |
性能开销 | 由于涉及到用户态与内核态之间的切换,系统调用的执行成本相对较高。因此,频繁的系统调用可能会影响程序的性能。 | 相对于系统调用,函数库调用的性能开销较小。因为它们通常不涉及到模式切换,且执行的操作多在用户空间完成。 |
示例 | open(),read(),write(),fork(),exec() 等 UNIX/Linux 系统调用。 | C 标准库中的 printf() 等函数;数学库中的 sin(),cos() 等函数。 |
NOTE
人类语言
是人和人之间用于沟通的一种方式,例如:中国人和中国人之间使用普通话沟通,而中国人和美国人交流,则可以使用英语。NOTE
固定格式
和固定词汇
(即:语法规则
),英文也是自己的固定格式
和固定词汇
(即:语法规则
);同样的道理,法语、韩国等各种人类语言
都有自己的固定格式
和固定词汇
(即:语法规则
)。望其项背
原指看见对方的背影,形容差距不大,能赶上;但是,很多人却认为这是形容遥不可及或难以企及的目标。借我 5000 RMB 买 iphone
或者 5000 RMB 我买 iphone 借
。计算机编程语言
是人和计算机交流的方式。人们可以使用编程语言
对计算机下达命令(指令)
,让计算机完成人们需要的功能。NOTE
固定格式
和固定词汇
(即:语法规则
),我们必须学习其语法规则,才能控制计算机,让计算机完成我们所需要的功能。#include <stdio.h> // 这是编译预处理指令
int main() { // 定义主函数
printf("你好,世界!!!"); // 输出所指定的一行信息
return 0; // 函数执行完毕时返回函数值0
}
编写
的程序叫做源代码
,是人类能看懂;但是,计算机却不能识别。那么,我们就需要让计算机能识别我们编写的源程序,就需要将我们编写的源代码交给编译器程序,其会帮助我们将所编写的源代码转换为计算机能够识别的二进制指令。NOTE
编译器就是运行在操作系统之上的程序,其作用就是用来将程序员编写的源代码转换为计算机能够识别的二进制指令。
NOTE
总结:无论我们学习任何一门编程语言,想要将程序运行起来,都必须做如下的两件事情:
语法规则
。编译器
程序,将源程序编译为计算机能够识别的二进制指令。ENIAC
诞生,使用的是最原始的穿透卡片
。二进制代码
表示的语言,和人类语言差别极大,这种语言就称为机器语言
,如:0000,0000,000000010000 代表 LOAD A, 16
0000,0001,000000000001 代表 LOAD B, 1
0001,0001,000000010000 代表 STORE B, 16
唯一语言
,人类很难理解;换言之,当时的程序员 99.9% 都是异类!!!WARNING
汇编语言
使用助记符
(如:MOV、ADD、SUB)代替二进制操作码,使程序更易于人类编写和理解;因此,汇编语言
也被称为符号语言
。优点
是能编写高效率
的程序;但是,缺点
和机器语言没什么不同,汇编语言同样依赖于具体的计算机架构(面向机器)
,程序不具备跨平台的可移植性。WARNING
高级语言
是一种接近于人们使用习惯
的程序设计语言。它允许程序员使用接近日常英语的指令来编写程序
,程序中的符号和算式也和日常使用的数学公式
差不多,接近于自然语言和数学语言,容易被人们掌握。独立于计算机硬件
,有一定的通用性;计算机不能直接识别和执行用高级语言编写的程序,需要使用编译器
或解释器
转换为机器语言,才能被计算机识别和执行。NOTE
IMPORTANT
C 语言出现的时候,已经度过了编程语言的拓荒年代,具备了现代编程语言的特性,但是这个时候还没有出现“软件危机”,人们没有动力去开发更加高级的语言,所以也没有太复杂的编程思想;而之后出现的“面向对象”的编程思想解决了一部分在“软件危机”上的窘境。
类别 | 特征 | 优点 | 缺点 | 示例 |
---|---|---|---|---|
机器语言 | 直接由计算机执行的二进制代码 | 执行速度快 | 编写困难,可读性差,与具体硬件强绑定 | 二进制代码 |
汇编语言 | 用助记符代替二进制代码的低级语言 | 相对机器语言更易编写和理解,允许直接控制硬件资源 | 依然需要了解硬件,不够抽象,与具体硬件或平台相关 | MOV,ADD 等助记符 |
高级语言 | 接近人类语言,提供了更高层次的抽象 | 易于编写和维护,可移植性好,支持多种编程范式 | 需要通过编译器或解释器转换为机器语言,可能存在一定的性能损失 | C,Java, Python 等 |
IMPORTANT
提高开发效率
。至此,编程终于不再是只有极客才能做的事情,不怎么了解计算机的初学者在经过一定时间的训练后也可以编写出有模有样的程序。NOTE
许多著名编程语言的创造者和计算机科学领域的大佬都有学习和使用过 C 语言,如:詹姆斯·高斯林(James Gosling,Java 之父),比雅尼·斯特劳斯特鲁普(Bjarne Stroustrup,C++ 之父),吉多·范罗苏姆(Guido van Rossum,Python 之父),林纳斯·托瓦兹(Linus Torvalds,Linux 之父)等。
C 语言除了能让我们了解编程的相关概念,带领我们走进编程的大门,还能让我们明白程序的运行原理,如:
这些底层知识决定了我们的发展高度,也决定了我们的职业生涯。如果我们希望能在计算机行业中长远的发展,就必须学习这些相关的底层知识。
IMPORTANT
这些底层知识,包括不限于:数据结构和算法、计算机组成原理、操作系统、计算机网络、设计模式以及编译原理(了解即可):
数据结构和算法:主要研究数据的组织方式和处理方法,包括:线性表、树、图等数据结构,以及基本的算法思想和分析方法。
计算机组成原理:主要研究计算机系统的硬件组成和工作原理,包括:数字电路、存储器、中央处理器等内容。
操作系统:主要研究计算机系统的软件组成和工作原理,包括:进程/线程/并发(重点)、内存布局和内存管理(重点)、文件系统和磁盘 IO 等内容,以及基本的操作系统概念和设计思路。
计算机网络:主要研究计算机之间的通信原理和协议,包括:网络体系结构(OSI 模型)、传输协议、网络安全等内容,以及基本的网络概念和技术。重点学习 TCP/IP 协议栈、socket 通信(三/四次握手、select、poll、epoll)、HTTPS/HTTP、长链接等内容。
设计模式:是软件设计中常见问题的通用解决方案。不过,在 C 语言中通常是没有的,因为其是面向过程的编程语言,而 C++ 和 Java 等面向对象的编程语言是有设计模式的。
编译原理:主要研究如何将高级编程语言转换为机器语言,有词法分析、语法分析、语义分析、中间代码生成、优化、代码生成等步骤,了解即可。
NOTE
很多人之所以觉得 C 语言难,就是因为栽倒在 C 语言的指针那边(相对比其他的现代化编程语言而言,C 语言的指针确实足够底层和麻烦,需要掌握的细节很多);但是,一旦有所突破,学习之路就会一马平川。
肯·汤姆森
(Ken Thompson)和丹尼斯·里奇
(Dennis Ritchie)一起开发了 Unix 操作系统。Unix 最初是使用汇编语言
编写的,依赖于计算机硬件。为了程序的可读性
和可移植性
,它们决定使用高级语言重写。但是。当时的高级语言无法满足他们的要求,肯·汤姆森
就在 BCPL 语言的基础上发明了 B
语言。丹尼斯·里奇
(Dennis Ritchie)在 B
语言的基础上重新设计了一种新的语言,这种新语言取代了 B
语言,即 C
语言。整个 Unix 系统都使用 C 语言重写(重构)
,大大增强了 Unix 在不同硬件平台的可移植性,这标志着 Unix 的初步成熟,也标志着 C 语言的初步成熟(因为 C 语言可以用于大型项目开发了)。NOTE
C 语言最初是作为 Unix 系统的开发工具而发明的,它的初衷非常简单,就是被设计成一种非常高效的、可以操作硬件的系统级编程语言,然后帮助团队开发 Unix 操作系统。
C 语言标准化
,标志着 C 语言开始稳定和规范化。C 语言具有可移植好、跨平台的特点
:用 C 语言编写的代码可以在不同的操作系统和硬件平台上编译和运行。NOTE
C 语言在许多领域应用广泛
。 操作系统
:C 广泛用于开发操作系统,如:Unix、Linux 和 Windows。嵌入式系统
:C 是一种用于开发嵌入式系统(如:微控制器、微处理器和其它电子设备)的流程语言。系统软件
:C 用于开发设备驱动程序、编译器和汇编器等系统软件。网络
:C 语言广泛用于开发网络应用程序,例如:Web 服务器、网络协议和网络驱动程序。数据库系统
:C 用于开发数据库系统,例如:Oracle、MySQL 和 PostgreSQL 。游戏
:由于 C 能够处理低级硬件交互,因此经常用于开发计算机游戏。人工智能
:C 用于开发人工智能和机器学习的应用程序,例如:神经网络和深度学习算法。科学应用
:C 用于开发科学应用程序,例如:仿真软件和数值分析工具。金融应用
:C 用于开发股票市场分析和交易系统等金融应用。写需要和硬件交互、有极高性能要求
的程序。NOTE
Unix
操作系统的的开发者肯·汤姆森
(Ken Thompson),Go 诞生的背景据说是肯·汤姆森
(Ken Thompson)在 C++ 委员会在为其演讲 C++ 新特性的时候,觉得 C++ 新特性太多太复杂,于是就开发了 Go 语言;所以,Go 语言中有很多 C 语言的身影。学习 C 语言有助于快速上手其他编程语言
,如:C++(原先是 C 语言的一个扩展,在 C 语言的基础上嫁接了面向对象编程思想)、C#、Java 等,这些语言都继承或深受 C 语言的影响和启发。C 语言至今,依然是最广泛使用、最流行的编程语言之一
,包括很多大学将 C 语言作为计算机教学的入门语言,拥有庞大而活跃的用户社区,这意味着有许多资源和库可供开发人员使用。容易学习
,适合入门。和 Java、C++、Python 等更加现代化的高级编程语言相比,C 语言涉及的概念少,附带的标准库小,整体比较简单,容易学习,非常适合初学者入门。我们知道,这个世界上的编程语言太多太多。其中,最流行的编程语言就是 TOBIE 榜单上的前 50 名。
从应用的范围上来讲,编程语言大致可以分为以下两类,如下所示:
通用型编程语言
:这些语言设计的目的是能够用于开发多种类型的应用程序,不局限于某个特定领域。它们通常拥有丰富的库和框架支持,可以应用于系统编程、应用开发、Web开发、数据分析等多个领域。专用型编程语言
:这些语言是为了解决特定领域的问题而设计的,通常在该领域中表现出色。虽然它们可以在一定程度上用于其他领域,但其核心设计和优化是针对某个特定应用场景的。常见的专用型编程语言
,如下所示:
专用型编程语言 | 描述 |
---|---|
SQL | 专门用于数据库查询和管理,尽管可以嵌入其他编程语言中,但其主要应用是数据库操作。 |
R | 主要用于统计分析和数据可视化,广泛应用于数据科学和研究领域。 |
MATLAB | 主要用于数值计算、算法开发和数据可视化,广泛应用于工程和科学领域。 |
VHDL/Verilog | 用于硬件描述和数字电路设计,主要应用于电子工程领域。 |
通用型编程语言
,如下所示:通用型编程语言 | 描述 |
---|---|
Python | 广泛应用于Web开发、数据科学、自动化脚本、人工智能等。 |
Java | 用于企业级应用、移动应用开发(Android)、Web 开发等。 |
C++ | 可用于系统编程、游戏开发、嵌入式系统等多个领域。 |
JavaScript | 最初用于 Web 前端开发,现在也广泛用于服务器端(Node.js)、桌面应用开发(Electron)等。 |
NOTE
C 语言是一门通用型的编程语言,并没有针对某个领域进行优化。但是,C 语言也有很多常见的应用领域。
IMPORTANT
虽然 C 语言的开发场景貌似看起来很多;但是,使用 C 语言的场景几乎就是:底层/系统开发 + 关键组件/模块的开发 + 贴近硬件的开发,这些开发场景非常关注运行效率,或者响应时间,或者硬件资源。
NOTE
IMPORTANT
K
ernighan)和丹尼斯·里奇(Dennis R
itchie)合写了一本著名的教材《C 编程语言》(The C programming language)。NOTE
由于 C 语言还没有成文的语法标准,这本书就成了公认标准,以两位作者的姓氏首字母作为版本简称 “K&R C”。
NOTE
目前常用的编译器,如:MSVC(Microsoft Visual C++)、GCC、LLVM Clang 等,都能很好地支持 ANSI C 的内容。
大型修订
,发生在 1999 年,增加了许多语言特性,如:双斜杠( //
)的注释语法,可变长度数组、灵活的数组成员、复数、内联函数和指定的初始值设定项,这个版本称为 C99,是目前最流行的 C 版本
。NOTE
这个时候的 C 语言编译器基本已经成熟,各个组织对 C99 的支持所表现出来的兴趣不同:
最终导致不同的编译器在部分语法上存在差异。典型的例子就是:ANSI C 规定,只能用常量表示数组的长度,而 C99 取消了这个限制,数组的长度也可以用变量表示(可变长度数组)。对于 C99 的这个新改动,GCC 和 Clang 是支持的,而 MSVC 却不支持。
NOTE
控制台
(黑底白字
)上玩玩,没有漂亮的用户界面以及人性化的交互。于是,开始学习数据结构、算法、数据库、操作系统,越陷越深,越来越迷茫,不知道学习 C 语言能做什么,认为学习编程很难,开始怀疑自己,直到放弃!!!借助
操作系统、第三方库以及以及一些硬件,如:单片机等,才能发挥它的威力!!!IMPORTANT
底层
的应用之外,最重要的一点就是生态
。IMPORTANT
现代化的高级编程语言的流行程度,除了和编程语言的设计是否优秀有关,最主要的原因就是生态
。
标准库
(语言本身提供的,开箱即用),如:Java、Go 等。包管理器
(用于管理第三方库)解决方案,如:Java 中的 Maven、Gradle、Go 中的 go modules ,JavaScript 的 npm 等。遗憾的是,C 语言的标准库
非常简单,只有输入输出
、文件操作
、日期时间
、字符串处理
、内存管理
,对于网络编程
、GUI
、数据库
、并发
等需要
大量的第三方库
或操作系统的功能
来扩展 C 语言的功能(Java 语言、Go 语言等其他的现代化高级编程语言,都是直接将这些常见的开发场景内置到标准库中,开箱即用,极大的降低了软件开发的难度)。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 语言
)。十八世纪英国文学家约翰逊博士说得好:"它的优秀之处并非原创,它的原创之处并不优秀。"”
项目构建工具
和包管理器
在软件开发中扮演着不同的角色,它们虽然有时会有重叠的功能,但主要关注的点是不同的。项目构建工具
是用于自动化编译、测试、打包、部署
等一系列任务的软件工具。它们帮助开发者简化和管理整个软件开发生命周期中的各个步骤,尤其是在构建过程中的复杂性管理上。.java
、.c
等)为可执行文件或中间文件(如:.class
文件)。Makefile
来定义构建规则和依赖关系。包管理器
是用于自动化安装、更新、配置
和管理软件包及其依赖关系
的工具。它主要关注于获取和管理项目所需的第三方库或工具包,并确保它们正确地集成到项目中。package.json
、requirements.txt
)自动下载和安装项目所需的依赖包。Java
项目中的 Maven
或 Gradle
而言,其不仅是项目构建工具
也是包管理工具
。NOTE
背景
:8051 是由 Intel 于 1980 年设计的一种 8 位微控制器架构。它具有指令集简单、结构紧凑的特点,广泛应用于低端嵌入式系统中。开发工具
:C51 是指针对 8051 系列微控制器的 C 语言编译器,如:Keil C51。这种编译器将 C 语言代码编译为适合 8051 架构的汇编代码。C 语言的作用
:C 语言在 8051 微控制器上的应用使得开发更加高效和可维护。尽管 8051 的硬件资源有限,但 C 语言仍然能够在不损失性能的前提下提供高级编程的便利。应用场景
: NOTE
总结:C51 微控制器适用于资源受限、需要低成本的简单控制系统,非常适合使用 C 语言来进行开发!!!
背景
:STM32 是意法半导体(STMicroelectronics)推出的一系列基于 ARM Cortex-M 内核的 32 位微控制器。它们广泛用于需要高性能和低功耗的嵌入式应用中,如:工业控制、消费电子和物联网设备。开发工具
:开发 STM32 微控制器通常使用 Keil、IAR Embedded Workbench 或 STM32CubeIDE 等开发环境。这些环境中使用的编程语言主要是 C(有时也包括 C++)。C 语言的作用
:C 语言在 STM32 上的应用非常广泛,开发者可以利用它直接控制硬件寄存器,同时也能方便地使用 STM32 提供的 HAL(硬件抽象层)库或 LL(低层)库进行开发。C 语言在这个平台上不仅能实现底层控制,还能编写复杂的应用逻辑。应用场景
: NOTE
总结:STM32 微控制器在物联网、消费电子、医疗设备和工业控制等领域表现出色,非常适合使用 C 语言来进行开发,因为 C 语言允许直接进行硬件控制并支持复杂的应用开发。
背景
: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 语言的高效性和低级别硬件访问能力是开发实时、低延迟系统的关键。应用场景
: NOTE
总结:ARM Cortex 系列适用于从实时系统到高级嵌入式操作系统的各类应用,支持从低功耗控制到高性能计算的多种需求,非常适合使用 C 语言来进行开发,因为 C 语言不仅用于控制硬件,还广泛应用于操作系统和应用程序的开发。
NOTE
C++ 是 C 语言的继承者和扩展,它保留了 C 语言的优势,并引入了更多现代编程语言的特性,使得它在更广泛的应用领域中得到应用。