计算机程序语言基础知识简单介绍
前言
程序语言基础横跨操作系统存储管理、编程语言分类、编译原理、文法自动机、程序执行机制多个板块,知识点比较散。本文按知识模块拆解,用通俗语言梳理核心考点,不堆砌晦涩术语。
一、内存存储管理(程序运行底层核心)
内存管理的核心目的:让多个程序安全、高效共用内存,实现内存合理分配与回收、地址隔离,屏蔽硬件差异,提升内存利用率,支撑程序并发运行。
计算机主流三种内存管理方式,核心区别在于划分依据、地址结构、碎片类型。
1. 页式存储(硬件划分)

- 划分规则:将内存和程序逻辑空间划分为固定大小的页面
- 地址结构:逻辑地址 = 页号 + 页内偏移
- 工作逻辑:页号查询页表,获取物理块号;页内偏移固定不变,直接复用
- 物理地址公式:物理地址 = 物理块号 × 页面大小 + 页内偏移
- 优缺点:无外部碎片,内存利用率高;会产生页内碎片(页面空间未占满浪费)
- 补充:页表本身存放在内存中,每个程序运行时有页表基址寄存器(PTBR)指向当前进程的页表;分页对程序员完全透明,由操作系统和MMU(内存管理单元)自动完成地址转换
2. 段式存储(用户逻辑划分)

- 划分规则:根据程序逻辑模块划分(代码段、数据段、栈段),段长不固定
- 地址结构:逻辑地址 = 段号 + 段内偏移
- 工作逻辑:段号查询段表,获取段起始基地址
- 物理地址公式:物理地址 = 段基址 + 段内偏移
- 优缺点:贴合编程逻辑,方便程序模块化管理;易产生外部碎片(内存零散空隙)
- 补充:分段对程序员可见,编写底层代码时能直接感知代码段、数据段的划分;段表存放每个段的基址和段长,地址转换时会先校验段内偏移是否超出段长
3. 段页式存储(结合两者优点)

- 核心逻辑:先分段、段内再分页
- 地址结构:段号 + 页号 + 页内偏移
- 工作逻辑:先根据段号找到对应段,再从该段的页表中根据页号找到物理块号,最后页内偏移直接拼入
- 特点:兼顾段的逻辑性和分页的高利用率;缺点是需要查询段表、页表两次,地址转换速度较慢
- 补充:现代操作系统多采用分页或段页式,纯段式存储已很少单独使用;硬件缓存TLB(快表)可加速地址转换,命中时无需多次查表
4. 虚拟内存与局部性原理(内存管理延伸)

虚拟内存是现代内存管理的重要延伸,核心思路是把硬盘空间当作内存的"备用仓库":
- 局部性原理:程序在任一时刻访问的地址趋于集中(时间局部性:刚访问的数据可能再次访问;空间局部性:刚访问地址附近的地址也可能被访问)
- 换入换出:当内存不足时,将暂时不用的数据块换出到硬盘交换区,需要时再换入
- 缺页中断:程序访问的页面不在内存时,CPU触发缺页中断,由操作系统从硬盘加载;频繁缺页会导致"抖动"(thrashing),系统性能急剧下降
通俗理解:虚拟内存就像厨房太小放不下所有餐具,把不常用的碗盘收进储物柜(硬盘),要用的时候再拿出来,不过拿取过程耗时较长。
高频考点专项记忆(存储管理)
易混坑点
- 页内偏移无需转换,是地址中唯一固定不变的部分
- 分页产生页内碎片,分段产生外部碎片
- 段页式地址转换需两次查表(先段表、后页表),比纯分页慢
- 快表(TLB)是硬件缓存,存放最近常用的页表项,命中后地址转换只需一次内存访问
记忆口诀
页固定,段可变;
页查块,段查基;
偏移不用去翻译,直接拿来用到底;
页内碎片页里剩,段外碎片到处生。
二、编程语言分类
1. 按层级划分:低级语言 & 高级语言

低级语言(贴近硬件)
包含机器语言、汇编语言。
- 机器语言:纯二进制指令,CPU可直接执行,速度最快,但是可读性极差、完全依赖硬件、无移植性
- 汇编语言:机器语言的符号化形式,需汇编器翻译为机器码
- 整体特点:执行效率高、开发难度大、可移植性极差
- 补充:汇编语言与机器语言基本一一对应(如
MOV AX, BX对应某个特定机器码),因此汇编被视为"助记符"而非真正的高级语言;不同CPU架构(x86、ARM等)的汇编指令集各不相同
高级语言(贴近人类)
代表语言:Java、Python、C++、Go等
- 特点:语法贴近自然语言,可读性强、开发效率高、屏蔽底层硬件差异、可移植性好
- 短板:无法直接运行,必须经过编译或解释翻译后才能被CPU识别执行
- 补充:C语言常被称为"中级语言"——既具备高级语言的结构化特性,又保留了指针、位运算等底层操作能力
2. 按类型检查划分:静态 & 动态类型语言

核心区分标准:数据类型检查的执行时机
静态类型语言
- 检查时机:编译阶段完成类型检查
- 规则:变量声明时必须指定固定数据类型
- 代表:C、C++、Java、Go
- 优缺点:提前排查类型错误,程序运行稳定、速度快;代码书写相对繁琐
- 补充:Java虽是静态类型,但具有类型推断(
var关键字,Java 10+),可在编译期自动推导类型,简化写法,但类型本身仍在编译期固定
动态类型语言
- 检查时机:程序运行阶段才校验数据类型
- 规则:变量无需预先声明类型,赋值即确定类型,且类型可在运行时改变
- 代表:Python、JavaScript、PHP
- 优缺点:编码灵活高效、调试方便;运行时易暴露类型错误,执行性能偏弱
- 补充:Python 3.6+ 支持类型注解(Type Hints),如
def add(a: int, b: int) -> int:,但这仅是提示性质,运行时不会强制校验,本质仍是动态类型
3. 强类型 & 弱类型(独立维度)
- 强类型:运算时不允许隐式类型转换(如Python:
"1" + 2直接报错) - 弱类型:运算时会自动进行隐式类型转换(如JavaScript:
"1" + 2得到字符串"12") - 核心理解:静态/动态区分"何时检查",强/弱区分"检查多严格",两者独立——Java是静态+强类型,Python是动态+强类型,C是静态+弱类型,JavaScript是动态+弱类型
三、程序执行方式:编译器 & 解释器
所有高级语言,只有编译、解释两种核心执行方式,现代语言多为混合模式。
1. 编译器
- 核心逻辑:全文一次性翻译,将完整源码编译为机器码/字节码,生成独立可执行文件
- 执行流程:源码 → 编译 → 生成产物 → 脱离源码直接运行
- 特点:一次编译、多次运行,运行速度快;代码修改后需重新编译
- 代表语言:C、C++
- 补充:编译型语言生成的可执行文件与操作系统及CPU架构强绑定,Windows上的
.exe无法直接在Linux上运行,这是可移植性差的直接体现
2. 解释器
- 核心逻辑:逐行翻译、边译边跑,不生成任何可执行文件
- 特点:启动速度快、调试便捷;重复执行代码效率低(每次循环都要重新翻译)
- 代表语言:Python、JavaScript
- 补充:解释器省去了编译等待时间,尤其适合快速原型开发;但运行时多了一层翻译开销,CPU密集任务中性能明显弱于编译型语言
3. 混合模式
主流语言优化方案,例如Java:源码编译为字节码(.class文件),再由JVM虚拟机解释执行,兼顾编译的高效和解释的灵活性。
- 补充:Java的JIT(即时编译器)会在运行时把热点字节码直接编译为本地机器码缓存起来,后续调用无需再解释,大幅提升长期运行性能;C#的CLR(公共语言运行时)也采用类似机制。Python的PyPy版本同样实现了JIT优化,执行速度远超标准CPython
四、完整编译六大流程(必考顺序)

源码从编写到生成机器指令,必须经过固定六个阶段,顺序不可颠倒:
- 词法分析:拆解源码字符串,识别关键字、变量、运算符等基础单词(Token)
- 语法分析:校验代码语句结构合法性,生成抽象语法树(AST)
- 语义分析:核心做类型检查、作用域校验,排查逻辑语义错误
- 中间代码生成:生成与硬件无关的中间代码(三地址码),适配多平台
- 代码优化:等价改写中间代码,删减冗余运算,提升执行效率
- 目标代码生成:将优化后的中间代码,翻译为对应设备的机器指令/汇编指令
编译流程补充要点
- 符号表:贯穿整个编译过程,记录所有标识符的类型、作用域、内存位置等信息,各阶段都需查询或更新
- 出错处理:也贯穿全过程,遇到错误时需报告具体位置和类型(警告/错误),尽量继续编译以发现更多问题
- 前端 vs 后端:词法分析→语法分析→语义分析→中间代码生成统称"前端"(与硬件无关),代码优化→目标代码生成统称"后端"(与硬件相关),前后端分离使同一编译器可支持多语言多平台(如GCC支持C/C++/Fortran,可输出x86/ARM等多种架构机器码)
高频考点专项记忆(编译原理)
易混坑点
- 语法分析只查结构,类型错误、语义错误由语义分析负责
- 代码优化针对中间代码,不修改原始源码
- 编译器的前端与硬件无关,后端与硬件相关;跨平台编译本质是替换后端
- 符号表贯穿全程,并非某一阶段独有
记忆口诀
编译一次出文件,解释逐行马上干;
词拆单,语造树,语义检查类型数;
中间生成再优化,最后产出机器码。
五、编译原理基础概念
1. 正规集、正规式、有限自动机
- 正规集:符合规则的字符串集合,用于定义编程语言合法单词
- 正规式(正则表达式):用来简洁表示正规集的公式,如标识符规则:
[a-zA-Z][a-zA-Z0-9]* - 有限自动机:识别正规集的数学模型,分为DFA(确定)、NFA(非确定),是词法分析器的底层实现
通俗理解:正则定规则,自动机做识别。

- DFA(确定有限自动机) :每个状态在某个输入下最多只有一个转移目标,识别效率高,实现简单
- NFA(非确定有限自动机) :某个状态下同一输入可能有多个转移目标,更易构造,但需转换为DFA才能高效实现
- 词法分析器生成工具(如Lex、Flex)本质就是读取正规式定义,自动构造对应的有限自动机代码
2. 后缀表达式(逆波兰表达式)

- 中缀表达式:日常书写格式(
a+b*c),存在优先级、括号,计算机难以直接运算 - 后缀表达式:运算符后置(
a b c * +),无括号、无优先级问题 - 运算逻辑:依托栈结构,数字入栈、运算符弹出两个操作数计算,结果压栈,极简高效
- 应用场景:编译器表达式运算的标准中间格式
后缀表达式手动转换方法:按运算顺序加括号,将运算符移到对应右括号后面,再逐层去括号。
示例:a * (b + c) / d
-
第一步:
(a * (b + c)) / d -
第二步:
(a (b c +) *) d /→a b c + * d / -
表达式树:中缀对应二叉树的中序遍历,后缀对应后序遍历,前缀表达式(波兰表达式)对应先序遍历,三者本质是同一棵树的不同遍历方式
六、程序三大基础控制结构
所有复杂程序,均由三种基础结构组合而成,是结构化编程的核心:
- 顺序结构:代码从上至下逐行依次执行
- 分支结构:if-else、switch,根据条件选择性执行代码
- 循环结构:for、while、do-while,重复执行指定代码块
结构化编程定理
- 1966年Böhm-Jacopini定理证明:任何程序都可以只用顺序、分支、循环三种结构实现,无需goto语句
- 单入口单出口:每个结构只有一个入口和一个出口,保证程序逻辑清晰、可验证
- 滥用goto会导致"面条代码"(spaghetti code),逻辑混乱难以维护,现代编程语言已基本淘汰或限制goto使用
七、函数参数传递机制
编程语言两大参数传递方式,核心区别:是否操作原始数据内存
1. 传值调用
- 逻辑:复制实参的值,生成独立副本传给形参
- 特性:函数内部修改形参,不会影响外部原始实参
- 通俗理解:修改复印件,原件无变化
2. 传址(引用)调用
- 逻辑:将实参的内存地址传递给形参,形参直接指向原始数据
- 特性:函数内部修改数据,外部实参同步改变
- 通俗理解:直接修改原件
传值和传址调用示例

参数传递机制补充(高频面试点)
- Java:基本类型(int、char等)采用传值;对象类型传递的是引用的副本(即地址值的拷贝),形参和实参指向同一对象,修改对象属性会影响外部,但更换形参指向新对象不会影响外部引用
- Python:统一采用"传对象引用"方式(类似Java的对象传递),重新赋值形参不会改变外部绑定
本质理解:一切传递本质上都是"值"——要么是数据本身的值(传值),要么是内存地址的值(传址)。“引用传递"传递的也是地址这个"值”,只是这个值被用来定位原始数据。
高频考点专项记忆(参数传递)
易混坑点
- C语言无原生引用传递,仅支持传值;需通过指针传递地址,模拟传址效果
- Java"引用传递"说法不严谨:正确说法是"传值,但值是对象引用的副本"
- 传址调用中,形参和实参指向同一块内存地址,改形参=改实参
记忆口诀
传值复制一份本,内部改动外部稳;
传址给到原地址,一改全都跟着移;
C无引用只有值,指针拿来做代替。
八、整体核心知识总结
- 内存存储:页固定、段可变,分页管内存、分段管逻辑,碎片类型各不同
- 代码执行:编译生成文件高速运行,解释逐行实时执行,六大编译步骤顺序固定
- 参数传递:传值不改原值,传址全局生效,C语言指针模拟引用
- 语言本质:高级语言需翻译、静态语言早校验、动态语言更灵活
所有枯燥的计算机语言基础,本质就是一套完整链路:内存承载程序运行 → 语言规范定义代码格式 → 编译/解释完成翻译 → 控制结构流转逻辑 → 参数传递实现数据交互。
把这套链路拆开细看:
程序员用高级语言写代码 → 编译器做词法/语法/语义分析确保代码正确 → 生成中间代码再做优化 → 最终输出机器指令 → CPU执行时需要内存管理(分页/分段)将指令和数据装入内存 → 函数调用时通过传值/传址完成数据传递 → 顺序/分支/循环控制代码执行流向 → 程序跑完释放内存空间。
整个链路环环相扣,任意环节出问题程序都无法正常运行。考试中无论考到哪个节点,都要能快速定位它在全链路中的位置和作用,这是理解而非死记硬背的核心优势。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)