软件开发新手入门五大核心技能之基础编程能力(三)

简介: 教程来源 http://yyvgt.cn/ 本章深入讲解函数与模块化编程:涵盖Python/Java/JS中函数定义、参数传递(默认/关键字/可变参数)、作用域与闭包、递归原理及优化技巧(汉诺塔、备忘录、尾递归),强调代码复用与健壮性设计。

第四章 函数与模块化 —— 代码复用的艺术

4.1 函数的定义与调用
函数的基本结构

# Python函数完整定义
def calculate_bmi(weight_kg, height_m):
    """
    计算身体质量指数(BMI)

    参数:
        weight_kg: 体重(千克)
        height_m: 身高(米)

    返回:
        BMI值(浮点数)
    """
    if height_m <= 0:
        raise ValueError("身高必须为正数")
    bmi = weight_kg / (height_m ** 2)
    return bmi

# 调用函数
bmi = calculate_bmi(70, 1.75)
print(f"BMI: {bmi:.2f}")

# 参数传递的深度理解
# Python中参数传递是"对象引用传递"
def modify_list(lst):
    lst.append(4)      # 修改传入的列表对象
    lst = [1, 2, 3]    # 重新绑定,不影响外部
    print(f"函数内部: {lst}")

my_list = [1, 2, 3]
modify_list(my_list)
print(f"函数外部: {my_list}")  # [1,2,3,4] - append生效
// Java方法定义
public class Calculator {

    // 基本方法
    public static int add(int a, int b) {
        return a + b;
    }

    // 重载(Overloading):相同方法名,不同参数
    public static int add(int a, int b, int c) {
        return a + b + c;
    }

    public static double add(double a, double b) {
        return a + b;
    }

    // 可变参数
    public static int sum(int... numbers) {
        int total = 0;
        for (int num : numbers) {
            total += num;
        }
        return total;
    }

    // 递归方法:阶乘
    public static long factorial(int n) {
        if (n <= 1) return 1;
        return n * factorial(n - 1);
    }

    // 方法调用示例
    public static void main(String[] args) {
        System.out.println(add(5, 3));           // 8
        System.out.println(add(5, 3, 2));        // 10
        System.out.println(add(5.5, 3.2));       // 8.7
        System.out.println(sum(1, 2, 3, 4, 5));  // 15

        // 递归陷阱:栈溢出
        // factorial(10000);  // 可能抛出 StackOverflowError
    }
}

4.2 参数的进阶特性
默认参数与关键字参数(Python)

# 默认参数
def greet(name, greeting="Hello", punctuation="!"):
    print(f"{greeting}, {name}{punctuation}")

greet("Alice")                    # Hello, Alice!
greet("Bob", "Hi")                # Hi, Bob!
greet("Charlie", punctuation="?") # Hello, Charlie?

# 默认参数的陷阱(可变对象)
def add_item(item, lst=[]):       # 危险!默认参数在定义时计算
    lst.append(item)
    return lst

print(add_item(1))  # [1]
print(add_item(2))  # [1, 2] !不是[2]
print(add_item(3))  # [1, 2, 3]

# 正确做法
def add_item_safe(item, lst=None):
    if lst is None:
        lst = []
    lst.append(item)
    return lst

# 关键字参数
def create_user(name, age, email):
    print(f"Name: {name}, Age: {age}, Email: {email}")

create_user(age=25, name="Alice", email="alice@example.com")  # 顺序任意

# 强制关键字参数(*号后的参数必须用关键字传递)
def config(host, port, *, timeout, retry):
    print(f"Host: {host}, Port: {port}, Timeout: {timeout}, Retry: {retry}")

config("localhost", 8080, timeout=30, retry=3)  # 正确
# config("localhost", 8080, 30, 3)  # 错误!

4.3 变量作用域与闭包

// JavaScript作用域与闭包示例
function outerFunction(x) {
    // 外部函数变量
    let outerVar = 10;

    // 内部函数(闭包)
    function innerFunction(y) {
        // 可以访问外部函数的变量
        console.log(x + outerVar + y);
    }

    return innerFunction;
}

const closure = outerFunction(5);
closure(3);  // 输出 18 (5+10+3)

// 经典闭包陷阱
function createCounters() {
    let counters = [];
    for (var i = 0; i < 3; i++) {  // 使用var
        counters.push(function() {
            console.log(i);
        });
    }
    return counters;
}

const counters = createCounters();
counters[0]();  // 输出 3,不是0!
counters[1]();  // 输出 3
counters[2]();  // 输出 3

// 解决方案:使用let或IIFE
function createCountersFixed() {
    let counters = [];
    for (let i = 0; i < 3; i++) {  // let有块级作用域
        counters.push(function() {
            console.log(i);
        });
    }
    return counters;
}

4.4 递归的深度解析

# 递归经典案例:汉诺塔
def hanoi(n, source, target, auxiliary):
    """
    汉诺塔递归解法
    n: 盘子数量
    source: 起始柱子
    target: 目标柱子
    auxiliary: 辅助柱子
    """
    if n == 1:
        print(f"移动盘子1从 {source} 到 {target}")
        return

    # 将n-1个盘子从source移动到auxiliary
    hanoi(n - 1, source, auxiliary, target)
    # 移动最大的盘子
    print(f"移动盘子{n}从 {source} 到 {target}")
    # 将n-1个盘子从auxiliary移动到target
    hanoi(n - 1, auxiliary, target, source)

# 测试
hanoi(3, 'A', 'C', 'B')

# 递归优化:斐波那契数列(带备忘录)
def fibonacci_memo(n, memo={}):
    if n in memo:
        return memo[n]
    if n <= 1:
        return n
    memo[n] = fibonacci_memo(n-1, memo) + fibonacci_memo(n-2, memo)
    return memo[n]

# 尾递归(Python不支持尾递归优化,仅供参考)
def factorial_tail(n, accumulator=1):
    if n == 0:
        return accumulator
    return factorial_tail(n-1, n * accumulator)

来源:
http://bncne.cn/

相关文章
|
8天前
|
人工智能 自然语言处理 文字识别
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
Qwen3.7-Max是阿里云百炼面向智能体时代推出的新一代旗舰模型,对标GPT-5.5、Claude Opus 4.7等闭源旗舰。该模型支持百万级token上下文窗口,具备顶级推理能力、多模态搜索与视觉理解增强、流式输出低延迟响应等核心优势,覆盖编程、办公、长周期自主执行等复杂场景。同时支持OpenAI接口兼容,便于系统快速迁移。用户可通过Token Plan团队或节省计划等订阅方式灵活调用,适合企业级高要求场景使用。
3613 15
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
|
16天前
|
人工智能 开发工具 iOS开发
Claude Code 新手完全上手指南:安装、国产模型配置与常用命令全解
Claude Code 是一款运行在终端环境中的 AI 编程助手,能够直接在命令行中完成代码生成、项目分析、文件修改、命令执行、Git 管理等开发全流程工作。它最大的特点是**任务驱动、终端原生、轻量高效、多模型兼容**,无需图形界面、不依赖 IDE 插件,能够深度融入开发者日常工作流。
3595 13
|
10天前
|
人工智能 自然语言处理 供应链
|
12天前
|
人工智能 Linux BI
国内用 Claude Code 终于不用翻墙了:一行命令搞定,自动接 DeepSeek
JeecgBoot AI专题研究 一键脚本:Claude Code + JeecgBoot Skills + DeepSeek 全平台接入 一行命令装好 Claude Code + JeecgBoot Skills + DeepSeek 接入,无需翻墙使用 Claude Code,支持 Wind
2975 7
国内用 Claude Code 终于不用翻墙了:一行命令搞定,自动接 DeepSeek
|
18天前
|
Shell API 开发工具
Claude Code 快速上手指南(新手友好版)
AI编程工具卷疯啦!Claude Code凭借任务驱动+终端原生的特性,成了开发者的效率搭子。本文从安装、登录、切换国产模型到常用命令,手把手带新手快速上手,全程避坑,30分钟独立用起来。
3717 25
|
10天前
|
人工智能 自然语言处理 安全
Claude Code 全攻略:命令大全+三种模式+记忆体系+实战工作流完整手册
Claude Code 是当前最流行的终端级 AI 编程助手,能够直接在命令行中完成代码生成、项目理解、文件修改、命令执行、错误修复等全流程开发工作。它不依赖图形界面、不占用额外资源,却能深度理解项目结构,自动生成规范代码,大幅提升研发效率。
1455 3
|
3天前
|
存储 定位技术 数据库
CodeGraph 如何让 Claude Code减少 7 成工具调用?
CodeGraph 为 Coding Agent 提供本地代码知识图谱,把函数、类、调用链和框架路由提前整理成“项目地图”,减少盲目搜索和文件读取。它不是新 Agent,而是上下文基础设施,让 Agent 更快找到正确代码路径,平均减少 7 成工具调用。
476 0
|
17天前
|
存储 Linux iOS开发
【2026最新】MarkText中文版Markdown编辑器使用图解(附安装包)
MarkText是一款免费开源、跨平台的Markdown编辑器,主打所见即所得实时预览,支持Windows/macOS/Linux。内置数学公式、流程图、代码高亮、多主题及PDF/HTML导出,是Typora的轻量免费替代首选。(239字)