1.形参和实参的区别
- 形参变量只有在被调用时才分配内存单元,调用结束时即刻释放。所以形参在函数内有效,函数调用结束后形参变量不能再使用。
- 实参可以是常量、变量、表达式、函数等类型。在函数调用时实参必须有确定的值,这样才能把这些值传送给形参。
- 实参和形参在数量、类型、顺序上必须严格一致,否则会发生“类型不匹配”的错误。
- 数据传送是单向的,只能把实参的值传送给形参,不能把形参的值传回给实参。即使形参的值发生改变,实参的值不会受影响。
- 当形参和实参不是指针类型时,形参和实参是不同的变量,位于不同的内存位置。函数运行时,形参将实参的内容复制一份,当函数结束时,形参被释放,实参的内容不会改变。
2.指针传递 到形参
- 传指针:传递指向变量地址的指针,需要解引用操作才能访问变量值。当一个函数的参数是通过指针传递时,该参数实际上是一个指向原始变量地址的指针。通过间接访问指针指向的地址,函数可以对原始变量进行修改。
#include <iostream>
void modifyValue(int* ptr) {
std::cout << "局部函数指针*ptr: " << *ptr << std::endl;
std::cout << "局部函数指针ptr: " << ptr << std::endl;
*ptr = *ptr + 1;
}
int main() {
int* p = new int(10);
std::cout << "指针*p: " << *p << std::endl;
std::cout << "指针p: " << p << std::endl;
modifyValue(p);
std::cout << "执行完函数后指针*p: " << *p << std::endl;
std::cout << "执行完函数后指针p: " << p << std::endl;
return 0;
}
输出示例
假设这个代码在一个典型的环境中运行,会得到以下输出:
指针*p: 10
指针p: 000001C1BEA21B70
局部函数指针*ptr: 10
局部函数指针ptr: 000001C1BEA21B70
执行完函数后指针*p: 11
执行完函数后指针p: 000001C1BEA21B70
在函数 modifyValue(int* ptr)中 给指针形参传递的是指针得地址
ptr
是接收到的指针参数,它指向和p
同样的内存地址。*ptr
是ptr
指向的内存中的值,即10
。ptr
是指针本身的值,即p
的值(地址)。
*ptr = *ptr + 1;
这行代码增加 ptr
指向的内存中的值 10
为 11
。
3.引用传递 到形参
- 传引用:直接传递变量本身的引用,不涉及指针的解引用操作。当一个函数的参数是通过引用传递时,该参数在函数内部实际上就是原始变量的别名。这意味着在函数内部对该参数的任何修改,都会直接反映到原始变量上
#include <iostream>
void modifyValue(int& ptr) {
std::cout << "局部函数&p:: " << &ptr<<std::endl;
std::cout << "局部函数ptr: " << ptr << std::endl;
ptr = ptr + 1;
}
int main() {
int x = 42;
std::cout << "x: " << &x << std::endl;
int &p = x;
std::cout << "&p: " << &p << std::endl;
std::cout << "p: " << p << std::endl;
modifyValue(p);
std::cout << "执行完函数后&p:: " << &p << std::endl;
std::cout << "执行完函数后p: " << p << std::endl;
return 0;
}
输出示例
假设这个代码在一个典型的环境中运行,会得到类似以下输出
x: 000000787150FDD0
&p: 000000787150FDD0
p: 42
局部函数&p:: 000000787150FDD0
局部函数ptr: 42
执行完函数后&p:: 000000787150FDD0
执行完函数后p: 43
在 modifyValue(int& ptr)函数中:给引用形参传递的是&p所引用x变量得内存地址
int& ptr
接收了参数p
的引用,实际上ptr
也是x
(或p
)的别名。- 打印
&ptr
将输出ptr
的地址,等同于x
的地址。 - 打印
ptr
将输出ptr
的值,即42
。 -
修改
ptr
的值,相当于修改x
的值,所以x
的值变为43
。
传引用和指针的使用场景:
- 传引用:更安全,避免了直接操作内存地址,通常在现代C++编程中更为常见。
- 传指针:允许传递空指针(null pointer),可以显式地表示无效的参数或可选参数,但相对容易引发空指针异常。