文章目录
- C语言
- 值传递
- 地址传递
- C++
- 引用传递
C语言
值传递
这种方式使用变量、数组元素作为函数参数,实际是将实参的值复制到形参相应的存储单元中,即形参和实参分别占用不同的存储单元,这种传递方式称为“参数的值传递”。在调用结束后,形参的存储单元被释放,而形参值的任何变化都不会影响到实参的值,实参的存储单元仍保留并维持数值不变。
例子:
#include <stdio.h>
void swap(int x, int y) {int tmp;tmp = x;x = y;y = tmp;printf("x = %d, y = %d\n", x, y);
}
int main() {int a = 10;int b = 20;swap(a, b);printf("a = %d, b = %d\n", a, b);return 0;
}
运行结果:
对上面的例子进行修改:
#include <stdio.h>void test(int x) {x = 1024;printf("test函数内部 x = %d\n", x);printf("x的地址为:%p\n", &x);
} int main() {int x = 1;printf("调用test前 x = %d\n", x); //1test(x); //1024printf("x的地址为:%p\n", &x);printf("调用test后 x = %d\n", x); //1return 0;
}
可以看出运行结果与我们之前描述的一致。
地址传递
这种方式使用数组名或者指针作为函数参数,传递的是该数组的首地址或指针的值,而形参接收到的是地址,即指向实参的存储单元,形参和实参占用相同的存储单元,这种传递方式称为“参数的地址传递”。
地址传递的特点是形参并不存在存储空间,编译系统不为形参数组分配内存
。数组名或指针就是一组连续空间的首地址。因此在数组名或指针作函数参数时所进行的传送只是地址传送,形参在取得该首地址之后,与实参共同拥有一段内存空间,形参的变化也就是实参的变化。
#include <stdio.h>// 修改1:参数改为指针类型
void test(int *px) { // px指向main中的x*px = 1024; // 通过指针修改原变量printf("test函数内部 *px = %d\n", *px); // 1024printf("px的值为:%p (指向main中的x)\n", px); printf("px自身地址为:%p\n", &px); // 指针自身的地址,也就是指向px的指针,又叫做二级指针// int **ppx = &px;
} int main() {int x = 1;printf("调用test前 x = %d\n", x); //1printf("x的地址为:%p\n", &x);// 修改2:传递x的地址test(&x); // 传递x的地址printf("调用test后 x = %d\n", x); //1024 被修改了return 0;
}
运行结果:
此外,如果想修改main函数中x的值,还有两种办法。
- 直接返回修改后的值
这种方法适用于单返回值的情况:
#include <stdio.h>int test(int x) {x = 1024; // 修改局部副本return x; // 返回新值
} int main() {int x = 1;printf("调用test前 x = %d\n", x); //1// 获取返回值并赋值给xx = test(x); printf("调用test后 x = %d\n", x); //1024return 0;
}
2. 使用全局变量
#include <stdio.h>int x; // 全局变量void test() {x = 1024; // 直接修改全局变量
} int main() {x = 1;printf("调用test前 x = %d\n", x); //1test(); // 不需要传递参数printf("调用test后 x = %d\n", x); //1024return 0;
}
但是,使用全局变量通常不是好的做法,因为它使得程序难以维护和理解。
C++
引用传递
<cstdio>
是 C++ 标准库中的一个头文件,它包含了 C 语言标准 I/O 库的 C++ 封装,主要用于文件的输入和输出操作。
C++引用声明的语法为:数据类型& 引用名 = 被引用变量;
,作为函数参数:返回值类型 函数名(数据类型& 参数名)
理解:引用不是新变量,而是已存在变量的别名,引用在编译后直接绑定到目标地址,不产生额外内存分配。
形式上,声明的形式具有相似性:
int* ptr; // 指针声明
int& ref; // 引用声明// 清晰区分参数类型
void func(int param); // 值传递
void func(int* param); // 指针传递
void func(int& param); // 引用传递
代码如下:
#include <iostream>using namespace std;int main() {int person = 10; // 实体:变量personint& idCard = person; // 引用idCard是person的别名person = 20; // 通过原名修改cout << idCard; // 输出20 - 通过别名访问idCard = 30; // 通过别名修改cout << person; // 输出30 - 原名也随之改变int original = 42;int& alias = original;cout << "变量地址: " << &original << endl; cout << "引用地址: " << &alias << endl;
}