【C++】超详细入门——带你了解函数的参数传递

C++中函数共有3中参数传递的方式,每种传递方式的原理都有很大差别,每种方式的应用场景也不同,今天就带大家来详细解析一下。

在介绍函数传递之前,先了解一下形参与实参的概念,了解形参与实参是学习传参的基础。

形参(形式参数):在函数定义首部所声明的参数,或简称为参数,一定要注意:形式参数是额外分配的内存
实参(实际参数):实际调用函数所提供的参数。

看下图示例:

void func(int n);  //形参
void func2(){
    func(1);       //实参
}

传值参数

值传递用起来非常明了。当然缺点也有很多,就是慢、占用空间还有不能修改实参。因为所谓的值传参是把实参的值复制了一遍,所以会有上面的特点。

#include <iostream>
using namespace std;
void Swap(int x, int y )
{
    int t=x;
    x=y;
    y=t;
}

int main (){ 
    int a=3, b=4;
    int *pa = &a, *pb = &b;
    cout << "befort swap:" << endl;
    cout << "a=" << a << "; b=" << b << endl;
    cout << "&a=" << &a << "; &b=" << &b << endl;
    cout << "pa=" << pa << "; pb=" << pb << endl;
    Swap(a, b);
    cout << "after swap:" << endl;
    cout << "a=" << a << "; b=" << b << endl;
    cout << "&a=" << &a << "; &b=" << &b << endl;
    cout << "pa=" << pa << "; pb=" << pb << endl;
    return 0;
}
-------------------------------------
befort swap:
a=3; b=4
&a=0x61fef4; &b=0x61fef0
pa=0x61fef4; pb=0x61fef0
after swap:
a=3; b=4
&a=0x61fef4; &b=0x61fef0
pa=0x61fef4; pb=0x61fef0

从上面函数的输出结果可以看出,传给Swap函数的 a 和 b 并没有被 Swap 函数交换。从深层次来说该只是将main的帧栈中参数x,y的值进行了交换,并未在a,b的地址处完成a,b的交换。

传指针参数

在调用函数时系统并没有分配实际的地址给函数的形式参数,而是将实际参数的地址直接传递给对应的形式参数。

#include <iostream>
using namespace std;
void Swap(int *x, int *y )
{
    int t=*x;
    *x=*y;
    *y=t;
}

int main (){ 
    int a=3, b=4;
    int *pa = &a, *pb = &b;
    cout << "befort swap:" << endl;
    cout << "a=" << a << "; b=" << b << endl;
    cout << "&a=" << &a << "; &b=" << &b << endl;
    cout << "pa=" << pa << "; pb=" << pb << endl;
    Swap(pa, pb);
    cout << "after swap:" << endl;
    cout << "a=" << a << "; b=" << b << endl;
    cout << "&a=" << &a << "; &b=" << &b << endl;
    cout << "pa=" << pa << "; pb=" << pb << endl;
    return 0;
}
-------------------------------------------------
befort swap:
a=3; b=4
&a=0x61fef4; &b=0x61fef0
pa=0x61fef4; pb=0x61fef0
after swap:
a=4; b=3
&a=0x61fef4; &b=0x61fef0
pa=0x61fef4; pb=0x61fef0

从上面的结果中可以看出程序完成了参数互换的任务,调用Swap函数时,传递给Swap两个地址形参,分别是 &a 和 &b 的拷贝。Swap 函数利用指针所指地址,直接改变 a,b 的地址中的内容。

看另一个 Swap 的版本:

void Swap(int *x, int *y )
{
    int *t=x;
    x=y;
    y=t;
}
Swap(pa, pb);
-------------------------------------------
befort swap:
a=3; b=4
&a=0x61fef4; &b=0x61fef0
pa=0x61fef4; pb=0x61fef0
after swap:
a=3; b=4
&a=0x61fef4; &b=0x61fef0
pa=0x61fef4; pb=0x61fef0

这个 Swap 没有完成交换任务,这是因为函数仅两个地址形参进行了交换,并未真正交换 a 和 b 的地址。

还用上一个 Swap,如果这样调用 Swap 呢:

Swap(&a, &b);

程序输出的结果跟上一个一样,原因与上一个一样。这个程序的本意是交换 a 的地址和 b 的地址,但变量的地址是 const 的,不能改变。

看最后一个 Swap 版本:

#include <iostream>
using namespace std;
void Swap(int **x, int **y )
{
    int *t=*x;
    *x=*y;
    *y=t;
}

int main (){ 
    int a=3, b=4;
    int *pa = &a, *pb = &b;
    cout << "befort swap:" << endl;
    cout << "a=" << a << "; b=" << b << endl;
    cout << "&a=" << &a << "; &b=" << &b << endl;
    cout << "pa=" << pa << "; pb=" << pb << endl;
    Swap(&pa, &pb);
    cout << "after swap:" << endl;
    cout << "a=" << a << "; b=" << b << endl;
    cout << "&a=" << &a << "; &b=" << &b << endl;
    cout << "pa=" << pa << "; pb=" << pb << endl;
    cout << "*pa=" << *pa << "; *pb=" << *pb << endl;
    return 0;
}
------------------------------------------------
befort swap:
a=3; b=4
&a=0x61fefc; &b=0x61fef8
pa=0x61fefc; pb=0x61fef8
after swap:
a=3; b=4
&a=0x61fefc; &b=0x61fef8
pa=0x61fef8; pb=0x61fefc
*pa=4; *pb=3

这个 Swap 仍没有交换成功,但 Swap 函数完成了变量 pa 和 pb 的交换,Swap 中每个变量多加了个取地址符,表明交换的是地址。通过输出 pa 和 pb 的值可以验证。当然解引用 pa 和 pb 得出的结果也是交换后的了。

总结:C++是以分配指针变量的形式参数来存放实际参数所传入的变量地址,并通过变量的形参地址对实参的内存处进行操作。

传引用参数

类似于传址调用的一种,但是在传引用方式的函数中形式参数并不会另外分配内存来存放实际参数传入的地址,而是直接把形式参数作为实际参数的一个别名。这是传值与传指针的主要区别。

#include <iostream>
using namespace std;
void Swap(int &x, int &y)
{
    int t = x;
    x = y;
    y = t;
}

int main (){ 
    int a=3, b=4;
    int *pa = &a, *pb = &b;
    cout << "befort swap:" << endl;
    cout << "a=" << a << "; b=" << b << endl;
    cout << "&a=" << &a << "; &b=" << &b << endl;
    cout << "pa=" << pa << "; pb=" << pb << endl;
    Swap(a, b);
    cout << "after swap:" << endl;
    cout << "a=" << a << "; b=" << b << endl;
    cout << "&a=" << &a << "; &b=" << &b << endl;
    cout << "pa=" << pa << "; pb=" << pb << endl;
    return 0;
}
-----------------------------------------
befort swap:
a=3; b=4
&a=0x61fef4; &b=0x61fef0
pa=0x61fef4; pb=0x61fef0
after swap:
a=4; b=3
&a=0x61fef4; &b=0x61fef0
pa=0x61fef4; pb=0x61fef0

上面的形参 x 与 y 是引用类型的,分别作为 a 和 b 的别名,所有在 x 和 y 上的操作都会间接的作用于 a 和 b。因此函数内交换 x 和 y 的行为可以交换实参 a 和 b。所以这个 Swap 可以完成交换。

此外,这三种调用还可以混合使用,还有函数作为参数的调用,但只要将这三种传参方式分别搞懂,再复杂的参数传递再结合参数的性质也能搞明白。

🎉到此 C++ 的三种讲解就到此结束了,本文主要根据一个参数交换的例子来讲解的,三种传参方式的区别也展现的比较明显,整体内容来说还是比较详细的,如果有讲解不到位或有误的地方恳请大家批评与交流。

希望大家多多关注,三连支持。你们的支持是我源源不断创作的动力。

全部评论
【C++】超详细入门函数的知识
点赞 回复 分享
发布于 2022-08-28 12:21 河南

相关推荐

10-14 23:01
已编辑
中国地质大学(武汉) Java
CUG芝士圈:虽然是网上的项目,但最好还是包装一下,然后现在大部分公司都在忙校招,十月底、十一月初会好找一些。最后,boss才沟通100家,别焦虑,我去年暑假找第一段实习的时候沟通了500➕才有面试,校友加油
点赞 评论 收藏
分享
头像
10-09 19:35
门头沟学院 Java
洛必不可达:java的竞争激烈程度是其他任何岗位的10到20倍
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务