编程基础与函数用法总结
起因
编程基础的知识过于细碎,没有章法。提炼总结本文,用于总结统筹。
一、编程基础
编程就是编写程序,所谓程序,就是告诉计算机要操作的数据和执行的指令序列,即对什么数据做什么操作。见于 编程-什么是编程。
变量与数据类型
变量
变量 = 变量名(标识符) + 变量值 + 数据类型
变量是计算机内存中一个具有名称的存储位置,用于临时存储程序在运行过程中需要使用和操作的数据。
设计价值:
- 抽象内存操作:用名称替代物理地址(类似于域名替代IP)
- 动态数据管理:存储中间结果、用户输入等运行时数据
- 提升代码复用性:逻辑与数据解耦,修改值无需改逻辑
- 类型安全屏障:编译期拦截非法操作(如文本做加法)
// 声明一个int型变量i
// 内存中分配4字节空间,i指向该地址
// i位置不变,值可变(这是"变"量的本质)
int i;
i = 5; // 将指向的内存空间值改为5变量 vs 常量
- 变量:值可以改变
- 常量:定义后不可改变(
final关键字修饰)
数据类型
什么是数据类型? 数据类型是编程语言中对不同种类数据进行分类的方式,定义了数据的性质、大小、取值范围以及可执行的操作。
为什么引入数据类型?
- 明确数据含义:让计算机知道二进制数据表示数字、文本还是其他
- 分配合适的内存空间:不同类型占据不同内存(
int4字节 vslong8字节) - 确保操作有效性:限制特定类型的操作(避免对文本进行数学加法)
- 提高可读性和可维护性:明确类型帮助理解数据用途和行为
基本数据类型
- 直接存储值本身
- 存储在栈内存中
- 特点:占用空间小,存取速度快,值传递时复制数据副本
- 赋值即复制值;== 比较内容;生命周期随作用域结束
引用数据类型(对象类型)
- 存储内存地址(引用),实际数据在堆内存中
- 包括:对象、数组、
String(Java中) - 特点:占用空间大,引用传递时共享同一内存地址
- == 比较地址,内容比较需用
equals();对象由GC管理生命周期int[] a = new int[]{1,2}; int[] b = a; // 复制引用,非复制数组 b[0] = 99; // a[0] 同步变为99(共享同一对象)
赋值
赋值操作的本质
- 基本类型:将值复制到变量指向的内存空间
- 引用类型:将内存地址赋值给变量,多个变量可指向同一对象
基本运算
流程控制
条件执行
- if-else链:适用于区间判断、复杂条件组合
- switch优化:
- JDK12+:支持
yield返回值 - JDK14+:表达式形式(无break穿透风险)
- 字符串/枚举支持(编译期优化为哈希跳转)
- JDK12+:支持
- 三元运算符:
条件 ? 真值 : 假值(简洁赋值场景)
循环语句
| 循环类型 | 适用场景 | 关键技巧 |
|---|---|---|
for | 已知迭代次数 | 嵌套循环注意变量作用域 |
while | 条件驱动循环 | 避免死循环(确保条件可变) |
do-while | 至少执行1次 | 先执行后判断 |
| 增强for | 遍历集合/数组 | 无法获取索引 |
控制流增强:
break label:跳出多层嵌套continue:跳过本次剩余代码
二、函数的用法
函数基础
函数是组织好的、可重复使用的代码块,用于实现单一或相关联的功能。它是从「线性执行」到「模块化编程」的关键跃迁。见于函数
- 本质:逻辑封装单元 + 接口契约(输入→处理→输出)
- 核心概念:
- 定义(Definition):声明函数签名(名称、参数、返回值)和函数体
- 声明(Declaration):提前告知编译器函数接口(头文件/接口概念)
- 调用(Invocation):通过函数名触发执行,程序计数器跳转到函数入口
- 四要素:
- 返回值:return 语句
- 名称:符合规范
- 参数列表:形参列表
- 函数体
- 设计原则:
- 单一职责:一个函数只做一件事
- 副作用最小化:避免隐式修改外部状态
- 明确返回:
void表示无返回值,非“返回空”
参数系统
参数是函数与外部交互的接口,是函数设计中最重要的部分。
参数类型匹配
- 形参(Parameter):函数定义中的占位符,局部变量
- 实参(Argument):调用时传入的实际值或引用
- 匹配规则:数量匹配、顺序匹配、类型兼容(隐式转换或显式重载解析)
- 隐式转换:小类型→大类型(
int→long) - 显式转换:大类型→小类型需强制转换(可能精度丢失)
- 自动装箱/拆箱:
int↔Integer(注意NPE风险)
- 隐式转换:小类型→大类型(
// 定义:形参 a, b 是占位符
int add(int a, int b) {
return a + b;
}
// 调用:实参 3, 5 是实际值
int result = add(3, 5);传递方式(以Java为例):值传递 vs 引用传递
值传递(Pass by Value)
- 机制:实参值的副本传递给形参
- 适用:基本数据类型(
int,double,boolean等) - 效果:函数内修改形参不影响实参
- 内存行为:栈中新建副本,函数结束副本销毁
void modify(int x) {
x = 100; // 只修改副本
}
int a = 10;
modify(a); // a 仍然是 10引用传递(Pass by Reference)
- 机制:实参的内存地址传递给形参
- 适用:引用数据类型(对象、数组)
- 效果:函数内通过引用修改对象会影响实参指向的对象,重赋引用(即内部形参修改引用)→不影响实参指向的对象
- 内存行为:栈中复制引用地址(指向同一堆内存),堆中数据共享
void demo(int x, List<String> list) {
x = 100; // 外部int不变
list.add("new"); // 外部List新增元素
list = new ArrayList<>(); // 外部引用不变(仅形参指向新对象)
}重要辨析:Java/Python 等语言是”值传递引用类型”(传递引用的副本),而非纯粹的引用传递。这解释了为什么交换对象引用本身不会生效。
可变参数
- 语法:
类型... name(必须是参数列表末尾) - 本质:编译为数组,可传0~N个参数
- 重载优先级:固定参数 > 可变参数(避免歧义)
函数特性
函数重载(Overload)
- 定义:同一类中同名函数,参数列表不同(数量、类型、顺序)+ 与返回值无关
- 解析机制:编译时静态绑定(Static Binding),根据实参类型选择最匹配版本
- 价值:提供友好API(如
print(int),print(String))
递归函数
- 定义:函数直接或间接调用自身
- 要素:基准条件(Base Case)+ 递归步骤(Recursive Step)
- 经典案例:阶乘、斐波那契、树形遍历、分治算法
- ⚠️ 警惕:
- 栈溢出(
StackOverflowError) - 重复计算(可用记忆化优化)
- 尾递归:部分语言优化(Java不支持,需手动转循环)
- 栈溢出(
底层原理
理解函数如何实现,才能写出高性能、线程安全的代码。
内存模型(函数视角)
程序内存分区
- 代码区:存储函数体指令(只读)
- 栈区(Stack):存储局部变量、函数参数、返回地址
- 函数调用期,每次调用生成新栈帧
- 自动分配/释放,LIFO(后进先出)
- 空间有限(通常1-8MB),递归过深导致溢出
- 堆区(Heap):存储对象实例、引用类型数据
- 手动/垃圾回收管理,空间大但访问慢于栈
- 函数间共享数据的媒介
- 方法区:存储字节码、静态变量
- JVM运行期,函数代码本身存储位置
变量生命周期
- 局部变量:函数调用时栈分配,返回时销毁
- 实例变量:对象在堆中创建时产生,垃圾回收时销
调用栈(Call Stack)
- 工作流程:
- 调用函数 → 创建栈帧(含局部变量表、操作数栈等)→ 压栈
- 执行中调用新函数 → 重复压栈
- 函数返回 → 弹出栈帧 → 恢复上一帧状态
- 调试价值:
- 异常堆栈跟踪 = 调用栈快照(定位错误源头)
- 递归深度可视化(IDE调试器可查看栈帧)
- 溢出根源:无限递归/超深递归 → 栈空间耗尽 →
StackOverflowError - 尾递归优化(Tail Call Optimization) 若递归调用是函数最后操作,编译器可复用当前栈帧而非新建,将递归转为循环(但并非所有语言支持,如 Java 不支持,Scala/C++ 部分支持)。
return func(a); // ✅ 是!直接返回递归结果
return func(a) + 1; // ❌ 否!递归后还有加法
int x = func(a); // ❌ 否!赋值后还有操作
return 1 + func(a); // ❌ 否!运算在递归后public static int sumTail(int n, int acc) {
if (n == 0) return acc;
return sumTail(n - 1, acc + n); // 递归是最后一行!无后续操作
}
// 调用 sumTail(10000, 0) → 依然 StackOverflowError!
// 实际优化(Java不优化)
int sumTail(int n, int acc) {
while (true) {
if (n == 0) return acc;
acc = acc + n;
n = n - 1;
}
}关联网络
演化日志
- v0.1 (2026-01-30):补充关联网络、演化日志,初始版本
复习回顾
📈 轮次: 1 🕒 lastReview: 2026-01-30 14:22:40 📅 nextReview: 2026-02-06 00:00:00