子程序(函数)

学习目标

通过本集的学习,你将能够:

  • 理解子程序的概念
  • 掌握参数传递机制
  • 区分值传递和引用传递
  • 理解副作用

1. 子程序概述

1.1 什么是子程序?

子程序是一段可重用的代码,接受输入并返回输出。

子程序的其他名称:
- 函数(function)
- 过程(procedure)
- 方法(method)

1.2 子程序的组成

def function_name(parameters):
    """文档字符串"""
    # 函数体
    statements
    return result

组成部分:
- 函数名
- 参数列表
- 函数体
- 返回值(可选)

2. 参数传递机制

2.1 值传递(Pass by Value)

值传递:传递参数的副本。

值传递示例(C++):
void f(int x) {
    x = 42;  // 修改的是副本
}

int main() {
    int a = 10;
    f(a);
    // a 仍然是 10
}

2.2 引用传递(Pass by Reference)

引用传递:传递参数的引用。

引用传递示例(C++):
void f(int &x) {
    x = 42;  // 修改的是原始值
}

int main() {
    int a = 10;
    f(a);
    // a 变成 42
}

2.3 传递对象引用

很多语言传递对象引用。

Python(传递对象引用):
def f(lst):
    lst.append(42)  // 修改列表

my_list = [1, 2, 3]
f(my_list)
// my_list 变成 [1, 2, 3, 42]

def g(x):
    x = 42  // 重新绑定,不影响外部

a = 10
g(a)
// a 仍然是 10

3. 参数类型

3.1 形参与实参

形参(形式参数):
def f(x, y):  // x, y 是形参
    return x + y

实参(实际参数):
f(1, 2)  // 1, 2 是实参

3.2 默认参数

默认参数:
def f(x, y=10):
    return x + y

f(5)     // 15
f(5, 3)  // 8

3.3 可变参数

可变参数(Python):
def sum_all(*args):
    total = 0
    for x in args:
        total += x
    return total

sum_all(1, 2, 3, 4)  // 10

3.4 关键字参数

关键字参数:
def f(x, y, z):
    return x + y + z

f(x=1, z=3, y=2)  // 6,顺序不重要

4. 副作用

4.1 什么是副作用?

副作用是函数除了返回值之外对外部状态的修改。

有副作用的函数:
count = 0

def increment():
    global count
    count += 1  // 副作用
    return count

4.2 纯函数

纯函数没有副作用,只依赖输入。

纯函数:
def add(x, y):
    return x + y

特点:
- 相同输入总是返回相同输出
- 没有副作用
- 不依赖外部状态

4.3 副作用的影响

副作用的问题:
- 难以测试
- 难以调试
- 难以并行化
- 难以理解

副作用的好处:
- I/O(打印、文件操作)
- 修改状态
- 性能优化

5. 实用案例

5.1 案例1:值传递 vs 引用传递

C++ 示例:
#include <iostream>
using namespace std;

void by_value(int x) {
    x = 42;
}

void by_reference(int &x) {
    x = 42;
}

int main() {
    int a = 10, b = 10;
    by_value(a);
    by_reference(b);
    cout << a << endl;  // 10
    cout << b << endl;  // 42
}

5.2 案例2:纯函数 vs 有副作用

纯函数:
def square(x):
    return x * x

有副作用:
log = []

def square_with_log(x):
    result = x * x
    log.append((x, result))  // 副作用
    return result

6. 自测问题

  1. 什么是子程序?
  2. 值传递和引用传递的区别是什么?
  3. 什么是形参和实参?
  4. 什么是纯函数?
  5. 副作用有什么优缺点?

7. 下集预告

下一集我们将学习数据类型详解!

参考资料

  • 《程序设计语言:概念与构造》
  • 《编程语言原理》
« 上一篇 控制结构 下一篇 » 数据类型详解