294 lines
9.1 KiB
Markdown
294 lines
9.1 KiB
Markdown
---
|
||
title: "编程哲学导论"
|
||
subtitle: "Programming Philosophy - Introduction"
|
||
version: "1.0"
|
||
category: "哲学篇 · 导论"
|
||
order: 0.1
|
||
tags: [编程, 哲学, 导论, 基础概念]
|
||
---
|
||
|
||
# 0.1 编程哲学导论
|
||
|
||
> **本节导读**:从最本质的角度理解"编程"的含义,建立对代码、编译器、程序的核心认知,并初步了解程序设计的基本哲学思想。
|
||
|
||
---
|
||
|
||
## 一、什么是编程?
|
||
|
||
### 1.1 词源解析
|
||
|
||
| 汉字 | 含义 | 词性 | 说明 |
|
||
|:----:|------|:----:|------|
|
||
| **编** | 编写 | 动词 (verb) | 编写代码的动作 |
|
||
| **程** | 程序 / 程式 | 名词 (noun) | 具有格式和顺序的结构 |
|
||
|
||
### 1.2 核心定义
|
||
|
||
> **编程 (Programming)**:按照一定的 **格式** 与 **顺序** 编写代码的过程。
|
||
|
||
我们编程的核心目标,是对各种各样的 **文件** 进行操作。
|
||
|
||
#### 直观类比
|
||
|
||
可以将编程与 **烹饪** 做类比:
|
||
|
||
| 烹饪 | 编程 |
|
||
|------|------|
|
||
| 菜谱 (格式 + 顺序) | 代码 / 算法 |
|
||
| 食材 (原料) | 数据 / 文件 |
|
||
| 菜肴 (最终产出) | 可执行程序 |
|
||
| 厨师 (执行者) | CPU / 计算机 |
|
||
|
||
---
|
||
|
||
## 二、核心概念
|
||
|
||
### 2.1 什么是代码?
|
||
|
||
**代码 (Code)** 本质上是 **文本文件**,即由 ASCII 字符组成的纯文本。
|
||
|
||
#### 常见代码文件扩展名
|
||
|
||
| 语言 | 扩展名 | 说明 |
|
||
|------|--------|------|
|
||
| C 语言 | `.c` | C 源文件 |
|
||
| C 语言 | `.h` | C 头文件 |
|
||
| C++ | `.cpp` | C++ 源文件 |
|
||
| C++ | `.hpp` | C++ 头文件 |
|
||
| C++ | `.cc` / `.cxx` | C++ 源文件(替代写法) |
|
||
|
||
> **NOTE**:`.c` / `.h` 通常用于 C 语言代码;`.cpp` / `.h` / `.cc` / `.cxx` / `.hpp` 通常用于 C++ 代码。
|
||
|
||
> **NOTE**:只要是合法的 C 或 C++ 的 ASCII 文本(无论使用何种扩展名),都可以被称为 **代码**。
|
||
|
||
#### 代码示例
|
||
|
||
**示例 — C 语言 "Hello, World"**:
|
||
|
||
```c
|
||
#include <stdio.h>
|
||
|
||
int main()
|
||
{
|
||
printf("Hello, World!\n");
|
||
|
||
return 0;
|
||
}
|
||
```
|
||
|
||
> **NOTE**:以上代码就是一个纯 ASCII 文本文件,保存为 `main.c` 后,它就是一段 **代码**。无论你将扩展名改为 `.txt`、`.abc` 甚至不加扩展名,只要内容合法,它依然是代码——只是编译器可能无法自动识别而已。
|
||
|
||
---
|
||
|
||
### 2.2 什么是编译器?
|
||
|
||
**编译器 (Compiler)** 是将 **代码** 转换为 **可执行文件** 的工具。
|
||
|
||
#### 直观类比
|
||
|
||
可以将编译器类比为 **翻译官**:
|
||
|
||
| 翻译官 | 编译器 |
|
||
|--------|--------|
|
||
| 输入:外文原文 | 输入:源代码 (C/C++) |
|
||
| 处理:语法分析、语义理解 | 处理:词法/语法/语义分析 |
|
||
| 输出:本国语言译文 | 输出:机器码 (可执行文件) |
|
||
|
||
如果原文有语法错误,翻译官会报错并指出问题位置 —— 编译器也是如此。
|
||
|
||
#### 输入与输出
|
||
|
||
```
|
||
┌─────────────────────┐ ┌─────────────────────┐
|
||
│ Input │ →→→→ │ Output │
|
||
│ │ │ │
|
||
│ File, Code │ Compiler │ Executable File, │
|
||
│ (ASCII Text) │ │ Linker Output │
|
||
└─────────────────────┘ └─────────────────────┘
|
||
```
|
||
|
||
#### 编译流程全景图
|
||
|
||
以 Windows 上的编译流程为例:
|
||
```
|
||
Source File(s)
|
||
│
|
||
▼
|
||
┌──────────────┐
|
||
│ Preprocessor │
|
||
└──────┬───────┘
|
||
│
|
||
▼
|
||
┌──────────────┐
|
||
│ Compiler │
|
||
└──────┬───────┘
|
||
│
|
||
▼
|
||
┌──────────────┐
|
||
│ Assembler │
|
||
└──────┬───────┘
|
||
│
|
||
▼
|
||
┌──────────────┐
|
||
│ Linker │
|
||
└──────┬───────┘
|
||
│
|
||
▼
|
||
Executable File (.exe)
|
||
```
|
||
|
||
> **REFERENCE**:关于编译流程各阶段的详细说明,请参阅 [→ 0.2 编程基础](./0.2%20Philosophy%20-%20Basic.md#三编译流程详解)
|
||
|
||
---
|
||
|
||
### 2.3 什么是程序?
|
||
|
||
**程序 (Program)** 是经过编译后生成的可执行文件,是计算机能够直接理解和执行的指令集合。
|
||
|
||
#### 直观类比
|
||
|
||
| 概念 | 类比 |
|
||
|------|------|
|
||
| **源代码** | 乐谱 (人可读,但不能直接发声) |
|
||
| **编译器** | 钢琴家 (将乐谱"翻译"为按键动作) |
|
||
| **程序/可执行文件** | 录好的音频文件 (可直接播放) |
|
||
| **运行程序** | 播放录音 (计算机执行指令) |
|
||
|
||
#### 示例
|
||
|
||
```
|
||
main.c (Source Code) --[Compile]--> main.exe (Program) --[Run]--> Output
|
||
Human Readable Machine Executable User Sees
|
||
```
|
||
|
||
---
|
||
|
||
## 三、基本设计哲学
|
||
|
||
> 以下是我对程序基本设计哲学的理解与总结:
|
||
|
||
### 3.1 抽象 (Abstraction)
|
||
|
||
用代码的方式 **描述问题**,而不纠结于实现细节。
|
||
|
||
- 将复杂现实简化为可计算的模型
|
||
- 关注 **"做什么"** 而非 **"怎么做"**
|
||
- 通过接口隐藏底层复杂性
|
||
|
||
#### 示例
|
||
|
||
**场景:发送一封电子邮件**
|
||
|
||
| 层级 | 抽象程度 | 你需要关心的事 |
|
||
|:----:|----------|----------------|
|
||
| **用户层** | 最高 | 收件人地址、邮件标题、正文内容 |
|
||
| **应用层** | 高 | 调用 `smtp.send(to, subject, body)` |
|
||
| **协议层** | 中 | SMTP 握手、HELO/EHLO、DATA 命令 |
|
||
| **传输层** | 低 | TCP 三次握手、数据包分片与重组 |
|
||
| **物理层** | 最低 | 电信号 / 光信号 / 无线电波 |
|
||
|
||
**抽象的意义**:当你写 `print("Hello")` 时,你不需要知道显卡如何渲染像素、操作系统如何调度显示驱动——这就是抽象的力量。
|
||
|
||
### 3.2 模块化 (Modularization)
|
||
|
||
将复杂问题 **分解** 为多个相对独立的子问题,每个子问题构成一个 **模块**。
|
||
|
||
```
|
||
Complex Problem
|
||
|
|
||
+---> Module A ---> Sub-problem A
|
||
+---> Module B ---> Sub-problem B
|
||
+---> Module C ---> Sub-problem C
|
||
```
|
||
|
||
**示例 — 开发一个计算器程序**:
|
||
|
||
```
|
||
Calculator App
|
||
|
|
||
+--- [input_module] -- User input parsing
|
||
+--- [calc_module] -- Arithmetic logic
|
||
+--- [display_module] -- Result formatting & display
|
||
+--- [history_module] -- History record management
|
||
```
|
||
|
||
**优势**:
|
||
- 降低复杂度:每个模块只关注一件事
|
||
- 提高代码复用性:`calc_module` 可被其他项目引用
|
||
- 便于团队协作开发:不同成员负责不同模块
|
||
- 方便测试与调试:可单独对 `calc_module` 进行单元测试
|
||
|
||
### 3.3 封装 (Encapsulation)
|
||
|
||
将模块的 **实现细节隐藏** 起来,仅 **暴露必要的接口** 给外部使用。
|
||
|
||
```
|
||
┌──────────────────────────────┐
|
||
│ [ Module ] │
|
||
│ │
|
||
│ ┌───────────────────┐ │ <- Public API
|
||
│ │ Interface │ │
|
||
│ └────────┬──────────┘ │
|
||
│ │ │
|
||
│ ┌────────▼──────────┐ │
|
||
│ │ Private │ │ <- Hidden Details
|
||
│ └───────────────────┘ │
|
||
└──────────────────────────────┘
|
||
```
|
||
|
||
**示例 — 汽车驾驶**:
|
||
|
||
| 封装层 | 对外暴露(接口) | 隐藏细节 |
|
||
|--------|------------------|----------|
|
||
| 方向盘、油门、刹车 | 驾驶员可操作 | 引擎燃烧原理、变速箱齿轮比 |
|
||
| 函数 `sqrt(x)` | 输入 x,输出根号 x | 牛顿迭代法的具体计算过程 |
|
||
|
||
```c
|
||
// math_utils.c -- 实现细节
|
||
static double newton_sqrt(double n) // static: 仅内部可见性
|
||
{
|
||
// 牛顿迭代法的具体实现... 外部不能直接调用此函数
|
||
double guess = n / 2.0;
|
||
|
||
for (int i = 0; i < 100; i++) {
|
||
guess = (guess + n / guess) / 2.0;
|
||
}
|
||
|
||
return guess;
|
||
}
|
||
|
||
// math_utils.c -- 对外暴露的接口
|
||
// 仅暴露必要的接口,隐藏实现细节
|
||
// 例如:sqrt(9) = 3.0, sqrt(16) = 4.0
|
||
double sqrt(double n)
|
||
{
|
||
if (n < 0) return 0.0; // 内部校验逻辑,负数返回0
|
||
|
||
return newton_sqrt(n);
|
||
}
|
||
```
|
||
|
||
**原则**:
|
||
- 信息隐藏 (Information Hiding)
|
||
- 最小知识原则 (Principle of Least Knowledge)
|
||
- 高内聚、低耦合
|
||
|
||
---
|
||
|
||
## 本节小结
|
||
|
||
| 概念 | 核心要点 |
|
||
|------|----------|
|
||
| **编程** | 按照格式顺序编写代码,本质是对文件的操作 |
|
||
| **代码** | ASCII 文本文件,具有约定扩展名规范 |
|
||
| **编译器** | 将代码转换为可执行文件的工具,经历预处理→编译→汇编→链接 |
|
||
| **程序** | 编译后的可执行指令集 |
|
||
| **抽象** | 关注"做什么",忽略实现细节 |
|
||
| **模块化** | 分而治之,降低复杂度 |
|
||
| **封装** | 隐藏实现,暴露接口 |
|
||
|
||
---
|
||
|
||
> **上一节**:无(起始章节)
|
||
> **下一节**:[→ 0.2 编程基础](./0.2%20Philosophy%20-%20Basic.md)
|