⌨️

程序设计基础

程序设计是用计算机语言把解题步骤告诉计算机的过程。本章讲解算法、三种基本控制结构、 数据类型与变量、运算符、函数与模块化、面向对象思想、程序的翻译执行以及主流语言与调试方法。

📚 9 个小节🔁 三种控制结构🧱 函数与模块🎛️ 面向对象

1程序与程序设计

程序:为解决某一问题而设计的指令(语句)的有序集合,是算法用某种程序设计语言的具体实现。 程序必须装入内存后由 CPU 逐条执行。
程序设计(编程):分析问题、设计算法、选用语言编写代码、调试测试直至正确解决问题的完整过程。

1.1 程序设计的一般步骤

  1. 分析问题、确定需求:明确输入是什么、要输出什么、有哪些约束。
  2. 设计算法:规划解题的方法和步骤(先想清楚再写代码!)。
  3. 编写代码(编码):用程序设计语言把算法表达出来。
  4. 调试程序:发现并修正语法错误和逻辑错误,让程序跑通。
  5. 测试与维护:用多组数据验证正确性与边界情况,后续按需修改完善。

1.2 著名的程序公式

瑞士计算机科学家沃斯(Niklaus Wirth)提出:

程序 = 数据结构 + 算法

数据结构描述数据如何组织,算法描述对数据如何操作,二者构成程序的核心。这也解释了为什么本课程后续要专门学习数据结构。

📝

代码风格同样重要:见名知义的命名、适当的注释、缩进整齐、函数短小,程序不仅是写给机器执行的,更是写给人阅读和维护的。

2算法基础

算法(Algorithm):为解决一个特定问题而采取的确定的、有限的操作步骤。 算法独立于具体语言,可以用自然语言、流程图、伪代码等多种方式描述。

2.1 算法的五个基本特性

  • 有穷性:必须在执行有限步骤之后结束,且每步都在有限时间内完成。
  • 确定性:每条指令含义明确,不能有二义性;相同输入必有相同结果。
  • 可行性(有效性):每一个操作都可以由已经实现的基本运算执行有限次实现。
  • 输入:有零个或多个输入(零输入时算法内部自带初始数据)。
  • 输出:有一个或多个输出——没有输出的算法毫无意义。

2.2 算法的描述方法

自然语言与伪代码

用中文或类语言描述步骤,通俗易懂;伪代码介于自然语言与真实代码之间,结构紧凑、无语法负担,是设计算法时最常用的草稿形式。

流程图

用标准图形符号表示控制流:起止框(圆角矩形)、处理框(矩形)、判断框(菱形)、输入输出框(平行四边形)、流程线(箭头)。

以"求两个数的最大值"为例的伪代码:

算法 Max(a, b)
输入: 两个数 a, b
输出: 较大者
    if a > b then
        return a
    else
        return b

2.3 算法的评价

  • 正确性:对合法输入能得到正确结果(最基本要求)。
  • 可读性:易于理解,便于交流和维护。
  • 健壮性(鲁棒性):输入非法数据时能妥善处理而不崩溃。
  • 高效率与低存储:运行时间短、占用内存少,用时间复杂度与空间复杂度量化。

时间复杂度表示算法运行时间随问题规模 n 的增长趋势,用大 O 记号表示,常见量级(从优到劣): O(1) < O(log n) < O(n) < O(n log n) < O(n²) < O(2ⁿ) < O(n!)。 例如单层循环是 O(n),两层嵌套循环通常是 O(n²)。

3程序的三种基本控制结构

1966 年 Bohm 和 Jacopini 证明:任何复杂的程序都可以由顺序、选择、循环三种基本结构组合嵌套而成。 它们都只有一个入口和一个出口,是结构化程序设计的基石。

3.1 顺序结构

最基本的结构:语句按书写顺序自上而下依次执行,每条语句只执行一次。

// 计算矩形面积
length = 5;          // 第 1 步:输入长
width  = 3;          // 第 2 步:输入宽
area = length * width; // 第 3 步:计算
print(area);         // 第 4 步:输出 15

3.2 选择结构(分支结构)

根据条件判断的真假选择执行不同语句。分为单分支、双分支和多分支:

if (score >= 60) {
    print("及格");
} else if (score >= 0) {
    print("不及格");
} else {
    print("成绩无效");
}

多分支还可用 switch / case 语句处理一个表达式取多个离散值的情况。注意条件判断中的相等比较是 ==(C/Java)或 =(Python),不要与赋值号混淆。

3.3 循环结构(重复结构)

在条件满足时反复执行某段语句(循环体),常见两种形式:

  • 当型循环 while:先判断条件,真则执行循环体(可能一次也不执行)。
  • 直到型循环 do-while:先执行循环体再判断(至少执行一次)。
  • for 循环:适合循环次数已知的场景,把初始化、条件、增量写在一起。
// 求 1+2+...+100,结果应为 5050
sum = 0;
for (i = 1; i <= 100; i++) {
    sum = sum + i;
}
print(sum);
⚠️

编写循环务必保证条件最终能变为假,否则会造成死循环(如忘了更新循环变量);循环体内可使用 break 提前跳出、continue 跳过本次剩余语句进入下一次判断。

4数据类型、常量与变量

4.1 数据的表示

计算机内部所有数据都以二进制存储。数值型数据有原码、反码、补码等表示(计算机中有符号整数普遍采用补码,可化减法为加法); 字符则通过编码标准映射为数字:

  • ASCII 码:美国标准信息交换码,用 7 位表示 128 个英文字符;数字 '0' 是 48,大写 'A' 是 65,小写 'a' 是 97。
  • 汉字编码:GB2312、GBK、GB18030;Unicode 致力于收录全球所有文字,UTF-8 是其最常用的变长编码实现。

4.2 基本数据类型

大类常见类型示例
整型int、short、long0、-7、2026
实型(浮点型)float 单精度、double 双精度3.14、-0.5(浮点数有精度误差,金额计算需谨慎)
字符型char'A'、'9'、'\n'('\n' 换行等转义字符)
布尔型booltrue、false

此外还有构造类型:数组、字符串、结构体/记录、枚举,以及指针、列表、字典等语言扩展类型。

4.3 常量与变量

  • 常量:程序运行期间值不能改变,如圆周率 π、整数 100;用 const 修饰或全大写命名。
  • 变量:内存中一块命名的存储单元,其值可以改变;变量具有名字、类型和值三要素,使用前通常要"先定义后使用"。
const PI = 3.14159;      // 常量
int age = 18;           // 整型变量
age = age + 1;            // 变量的值可以修改 → 19
📝

强类型语言(C、Java)变量必须声明类型,编译期检查;弱类型/动态类型语言(Python、JavaScript)变量类型可随值改变,书写灵活但大型项目更依赖测试与规范。

5运算符与表达式

运算符规定对数据进行的操作,操作数通过运算符连接成表达式,表达式按优先级和结合性计算。

类别常见运算符示例 / 说明
算术运算符+ - * / %(取余)7 % 3 = 1;整数相除可能取整(C 中 7/2=3)
关系运算符> < >= <= == !=结果为布尔值,如 5 > 3 → true
逻辑运算符&&(与) ||(或) !(非)组合条件:age>=18 && hasID
赋值运算符= += -= *= /=x += 5 等价于 x = x + 5
自增自减++ --i++ 使 i 增 1
条件运算符? :max = a>b ? a : b;(三目运算)
位运算符& | ^ ~ << >>直接对二进制位操作,常用于底层与性能优化

优先级大致顺序:括号最优先 → 算术(先乘除后加减)→ 关系 → 逻辑(与高于或)→ 赋值。 实际编程中建议用括号显式表达意图,避免死记优先级。

if ( (x > 0) && (x < 100) ) {
    print("x 是 1~99 之间的数");
}

6函数与模块化程序设计

函数(Function):完成特定功能、有名字的一段程序,可接收输入(参数)并返回结果(返回值)。 其他语言中也称"过程""方法"或"子程序"。
// 定义:求两数之和
function add(a, b) {
    return a + b;
}
// 调用
result = add(3, 5);   // → 8

6.1 为什么需要函数

  • 消除重复:同一段逻辑写一次、调用多次(DRY 原则:Don't Repeat Yourself)。
  • 分解复杂问题:大程序拆成一个个高内聚、低耦合的小函数,便于分工与理解。
  • 复用与共享:函数可放入库中供多个程序使用(如数学函数 sqrt()、print())。
  • 信息隐藏:调用者只需知道"传什么、返回什么",不必关心内部实现。

6.2 参数传递与作用域

  • 形参与实参:定义时括号中的是形式参数,调用时实际传入的是实际参数。
  • 局部变量:函数内部定义,只在函数内有效;全局变量:函数外定义,整个文件可用。应尽量少用全局变量以减少相互影响。
  • 递归:函数在定义中直接或间接调用自身。递归必须有明确的终止条件(出口)并不断向出口逼近,如阶乘 n! = n × (n-1)!。

6.3 结构化程序设计思想

20 世纪 60 年代为解决"软件危机",Dijkstra 等人提出结构化程序设计:自顶向下、逐步求精、模块化, 只用三种基本结构、限制滥用 goto 语句,使程序层次清晰、易读易验证。

7面向对象程序设计

随着软件规模增大,面向对象程序设计(OOP)成为主流范式。它把现实世界中的事物抽象为对象, 用"对象 + 消息"来组织程序,比面向过程更贴近人的思维方式。代表语言有 C++、Java、C#、Python 等。

7.1 类与对象

  • 类(Class):对一类事物共同特征的抽象模板,包含属性(数据,描述状态)和方法(函数,描述行为)。
  • 对象(Object):类的具体实例。类与对象的关系如同"图纸与房子""学生类与张三同学"。
class Dog {
    String name;                 // 属性
    void bark() {             // 方法
        print(name + ": 汪汪!");
    }
}
Dog d = new Dog();       // 由类创建对象(实例化)
d.name = "旺财";
d.bark();

7.2 面向对象的三大特性

特性含义意义
封装把数据和操作数据的方法捆绑在对象中,对外隐藏内部细节,只留必要接口(用 private/public 等访问控制)降低耦合、保护数据、提高安全性
继承子类自动获得父类的属性和方法,并可扩展或重写(如"狗"继承"动物")代码复用、建立类的层次体系
多态同一消息发给不同对象可产生不同行为(方法重写、重载、接口实现)程序更灵活、可扩展

面向过程

以"函数/过程"为中心,关注"第一步做什么、第二步做什么",把数据与处理数据的函数分开。适合小规模、流程固定的问题。代表:C。

面向对象

以"对象"为中心,关注"有哪些事物、各自有什么状态和行为、如何协作"。适合大型复杂系统。代表:Java、C++、Python。

8程序的翻译、执行与开发环境

8.1 从源代码到运行

高级语言源程序不能被 CPU 直接执行,必须经过翻译:

  • 编译方式(C/C++):源代码 → 编译 → 目标文件 → 链接库 → 可执行文件(.exe),运行快、与平台相关。
  • 解释方式(Python/JS):解释器读取源代码边翻译边执行,开发调试方便、跨平台,速度较慢。
  • 虚拟机方式(Java/C#):先编译成字节码,再由虚拟机 JVM/CLR 在目标平台上执行。

8.2 集成开发环境(IDE)

IDE 把编辑器、编译器/解释器、调试器、项目管理等集成在一起,大幅提高开发效率。常见有: Visual Studio、IntelliJ IDEA(Java)、PyCharm(Python)、Dev-C++/CLion(C/C++)、VS Code(轻量通用、靠插件扩展)。

8.3 程序错误的类型

错误类型表现解决
语法错误违反语言规则(漏分号、括号不配对),编译/解释无法通过根据报错的行号提示修改
运行时错误语法正确但运行中出错:除以 0、数组越界、空指针、内存不足查看异常信息定位
逻辑错误程序能运行,但结果不对(算法或条件写反),最隐蔽调试器单步跟踪、设置断点、观察变量、用测试用例验证

8.4 调试方法

常用手段:设置断点 → 单步执行 → 监视变量/表达式 → 查看调用栈;也可在关键位置打印中间结果。 调试的本质是"观察程序实际执行路径与预期的偏差",先复现、再缩小范围、最后定位根因。

9主流编程语言与选择

语言诞生/特点主要应用领域
C1972 年,贴近硬件、高效灵活操作系统、嵌入式、驱动、底层库
C++C 的超集,增加面向对象与泛型游戏引擎、高性能计算、浏览器、数据库内核
Java1995 年,"一次编写到处运行",生态庞大、安全稳定企业级后端、Android 开发、金融系统
Python1991 年,语法简洁接近自然语言、库极其丰富人工智能、数据分析、自动化脚本、Web 后端
C#微软主导,与 .NET 平台结合紧密Windows 应用、Unity 游戏、企业开发
JavaScript网页交互的唯一原生脚本语言,借助 Node.js 也可做后端前端、全栈 Web、浏览器插件
Go / Rust / Kotlin / Swift较新语言:Go 并发简洁;Rust 内存安全;Kotlin(安卓)、Swift(苹果)为移动开发首选云服务、系统编程、移动开发
💡

初学者语言选择建议:Python 语法最简单、成就感来得最快,适合培养编程思维;学校教学常以 C 语言打基础,帮助理解内存与底层原理。语言是相通的,扎实掌握一门后再学其他语言会非常快——重要的是计算思维,而非语法本身。

🔑

本章小结:程序 = 数据结构 + 算法;算法须满足有穷、确定、可行、有输入输出;任何程序都由顺序、选择、循环三种结构构成;数据按类型组织、以变量承载、用运算符组成表达式;函数实现模块化分解,面向对象用封装、继承、多态管理复杂性;源代码经编译或解释执行,配合 IDE 与调试技术保证正确。下一章学习数据如何被更精巧地组织——数据结构。