1. 传值与传地址的本质区别
在编程中,传值(Pass by Value)和传地址(Pass by Reference)是两种最基本的参数传递方式。传值是将变量的值复制一份传递给函数,而传地址则是将变量在内存中的地址传递给函数。
我见过太多开发者因为混淆这两者而导致的bug。比如下面这个C++例子:
cpp复制void increment(int x) {
x++;
}
int main() {
int num = 5;
increment(num);
cout << num; // 输出仍然是5
}
这里开发者期望num被修改,但实际上因为传值,函数内部操作的是副本。正确的做法应该是:
cpp复制void increment(int &x) {
x++;
}
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 常见传值/传地址错误模式
2.1 意外修改原始数据
在Python中,列表是可变对象,传参时实际上是传递了引用。我曾在一个项目中遇到过这样的问题:
python复制def clear_list(items):
items.clear()
data = [1, 2, 3]
clear_list(data)
print(data) # 输出[],原始数据被意外清空
解决方案是函数内部先创建副本:
python复制def clear_list(items):
items = items.copy()
items.clear()
2.2 性能陷阱
传值在大对象时会有性能问题。比如在Java中:
java复制void processLargeData(LargeData data) { // 这里传递的是引用的副本
// 操作data
}
虽然Java总是传值,但对于对象传递的是引用的值,所以通常不会复制整个对象。但如果误用clone(),就可能造成不必要的深拷贝。
3. 语言特性差异
3.1 JavaScript的特殊情况
JavaScript中基本类型是传值,对象是传"引用的值"。这导致一些迷惑行为:
javascript复制function changeObj(obj) {
ob
