c++ 传参传值地址_C/C++ | 三种不同函数参数传递方式

46f8944dccb0706bb7830e32e5995eba.png

一、前言

本文介绍C/C++语言中三种函数参数传递方式:值传递、引用传递、指针传递,全文分为三个部分:“初识三种函数参数传递方式”“代码演示”“引用传递和指针传递的区别”。

初识三种函数参数传递方式:该部分用表格对比三种函数参数传递方式;

代码演示:该部分分为三个小节,分别用代码实现值传递、引用传递、指针传递;

引用传递和指针传递的区别:着重介绍引用传递和指针传递区别。

一起来看看吧!

二、初识三种函数参数传递方式

C/C++中存在三种函数参数传递方式,值传递、引用传递、指针传递。

bfea4b8da3878dc2f99eb93fc9399e06.png

注意:C语言中支持两种参数传递方式——值传递和指针传递,C++中支持三种传递方式——值传递、引用传递和指针传递,对于引用传递,C语言不支持,但是C++支持。本节演示的程序是C++程序,因为C语言中引用传递无法演示出来。

三、代码演示

3.1 值传递(传值)

代码1:

#include<iostream>
using namespace std;
 
//值传递   交换前a=1,b=2;交换后a=1,b=2;
void swapByValue(int a,int b)
{
    cout<<"swapByValue函数  交换前"<<endl;
    cout<<"a="<<a;
    cout<<"  b="<<b;
    cout<<"  &a="<<&a;
    cout<<"  &b="<<&b<<endl;
 
    int temp=a;
    a=b;
    b=temp;
    cout<<"swapByValue函数  交换后"<<endl;
    cout<<"a="<<a;
    cout<<"  b="<<b;
    cout<<"  &a="<<&a;
    cout<<"  &b="<<&b<<endl;
}
 
//主函数
int main()
{
    int a=1;
    int b=2;
    cout<<"main函数  交换前"<<endl;
    cout<<"a="<<a;
    cout<<"  b="<<b;
    cout<<"  &a="<<&a;
    cout<<"  &b="<<&b<<endl;
    swapByValue(a,b);//值传递
    cout<<"main函数  交换后"<<endl;
    cout<<"a="<<a;
    cout<<"  b="<<b;
    cout<<"  &a="<<&a;
    cout<<"  &b="<<&b<<endl;
    return 0;
}

输出1:

52c7fb9f2c28448529f9e37edace4eef.png

小结1:可以看出main函数中a、b变量的内存地址和swap函数中a、b变量的内存地址没有任何关系。

因为它们本来就是两套独立的存储位置,相互之间没有任何关系,从main函数中调用swapByValue函数,是指将a、b参数的值传递过去,所以内存地址为0xfafed0、0x6afed4的a、b变量的值的变化不会影响到内存地址0xfafeec、0x6afee8的a、b变量的值。

如果一定要影响main中a、b变量的值,只能使用return返回,不过,可惜的是,return只能返回一个变量值(返回结构体或自定义类另说)。

3.2 引用传递(传引用)

代码2:

#include<iostream>
using namespace std;
 
//引用传递  交换前a=1,b=2;交换后a=2,b=1;
void swapByReference(int &a,int &b)
{
    cout<<"swapByReference函数  交换前"<<endl;
    cout<<"a="<<a;
    cout<<"  b="<<b;
    cout<<"  &a="<<&a;
    cout<<"  &b="<<&b<<endl;
    int temp=a;
    a=b;
    b=temp;
    cout<<"swapByReference函数  交换后"<<endl;
    cout<<"a="<<a;
    cout<<"  b="<<b;
    cout<<"  &a="<<&a;
    cout<<"  &b="<<&b<<endl;
}
//主函数
int main()
{
    int a=1;
    int b=2;
    cout<<"main函数  交换前"<<endl;
    cout<<"a="<<a;
    cout<<"  b="<<b;
    cout<<"  &a="<<&a;
    cout<<"  &b="<<&b<<endl;
    swapByReference(a,b);//引用传递
    cout<<"main函数  交换后"<<endl;
    cout<<"a="<<a;
    cout<<"  b="<<b;
    cout<<"  &a="<<&a;
    cout<<"  &b="<<&b<<endl;
    return 0;
}

输出2:

bdf28d916dda8fa498379ed096d607f5.png

小结2:main函数将a、b变量的引用(别名)传递给swapByReference函数,则swapByReference函数中a、b变量仅仅是main函数中a、b变量的引用(别名),不是一个新的真是存在的变量,所以swapByReference函数中的a变量的地址也是0x6afeec,和main函数中a变量的地址一样,swapByReference函数中的b变量的地址也是0x6afee8,和main函数中b变量的地址一样。

swapByReference函数中,交换了两个内存地址上的内容,因为swapByReference函数中的a、b变量作用域今夏与swapByReference函数,所以随着swapByReference执行完毕,其中的a、b变量也没什么用了。

再次回到main函数,main函数的a、b变量存放于0x6afeec地址和0x6afee8地址中,然后将它们输出交换结果即可。

3.3 指针传递、地址传递(传地址(传址))

因为指针变量的内容就是十六进制的内存地址,所以指针传递就是地址传递,又称为传地址。

代码3:

#include<iostream>
using namespace std;
 
//指针传递  交换前a=1,b=2;交换后a=2,b=1;
void swapByAddress(int *a,int *b)
{
    cout<<"swapByAddress函数  交换前"<<endl;
    cout<<"a="<<a;
    cout<<"  b="<<b;
    cout<<"  *a="<<*a;
    cout<<"  *b="<<*b<<endl;
    int temp=*a;    //注意:a是地址  *a是内容   b是地址  *b是内容  这里是内容交换,所以是*a和*b交换   这种写法正确
    *a=*b;
    *b=temp;
    cout<<"swapByAddress函数  交换后"<<endl;
    cout<<"a="<<a;
    cout<<"  b="<<b;
    cout<<"  *a="<<*a;
    cout<<"  *b="<<*b<<endl;
 
    // int temp=a;    //注意:a是地址  *a是内容   b是地址  *b是内容  这里是内容交换,所以是*a和*b交换
    // a=b;               //这种写法正确   这样交换的是地址
    // b=temp;
}
 
//主函数
int main()
{
    int a=1;
    int b=2;
    cout<<"main函数  交换前"<<endl;
    cout<<"a="<<a;
    cout<<"  b="<<b;
    cout<<"  &a="<<&a;
    cout<<"  &b="<<&b<<endl;
    swapByAddress(&a,&b);//指针传递
    cout<<"main函数  交换后"<<endl;
    cout<<"a="<<a;
    cout<<"  b="<<b;
    cout<<"  &a="<<&a;
    cout<<"  &b="<<&b<<endl;
    return 0;
}

输出3:

bfc2bfc5557aa400ae427fd9f4a85131.png

小结3:和上面引用传递不同,在swapByAddress函数中,参数a、b为int *类型(整型指针类型),所以swapByAddress函数中,a、b表示的是地址,*a *b表示的是内容。

从结果中可以看到,实参为&a,&b将变量地址传递给swapByAddress函数,函数接收到地址,使用*a *b获取地址上的内容,交换地址上的内容,最后在main函数中输出。

指针传递中,记住一种错误示范:

代码:

#include<iostream>
using namespace std;
 
void errorFun(int *a,int *b)   //错误示范
{
    cout<<"swapByAddress函数  交换前"<<endl;
    cout<<"a="<<a;
    cout<<"  b="<<b;
    cout<<"  *a="<<*a;
    cout<<"  *b="<<*b<<endl;
    int *temp=a;    //注意:a是地址  *a是内容   b是地址  *b是内容  这里是内容交换,所以是*a和*b交换   这种写法正确
    a=b;
    b=temp;
    cout<<"swapByAddress函数  交换后"<<endl;
    cout<<"a="<<a;
    cout<<"  b="<<b;
    cout<<"  *a="<<*a;
    cout<<"  *b="<<*b<<endl;
 
    // int temp=a;    //注意:a是地址  *a是内容   b是地址  *b是内容  这里是内容交换,所以是*a和*b交换
    // a=b;               //这种写法正确   这样交换的是地址
    // b=temp;
}
 
//主函数
int main()
{
    int a=1;
    int b=2;
    cout<<"main函数  交换前"<<endl;
    cout<<"a="<<a;
    cout<<"  b="<<b;
    cout<<"  &a="<<&a;
    cout<<"  &b="<<&b<<endl;
    errorFun(&a,&b);//指针传递
    cout<<"main函数  交换后"<<endl;
    cout<<"a="<<a;
    cout<<"  b="<<b;
    cout<<"  &a="<<&a;
    cout<<"  &b="<<&b<<endl;
    return 0;
}

输出:

4dfe0651f81215d676302cd6ccf828da.png

注意:*这是一种错误的示范,swapByAddress函数中交换的是int a,int * b的十六进制的地址,而不是内存地址中的内容,这种地址交换效果类似于值交换,地址交换的结果是不会影响到调用方main函数的,所以main函数中还是a=1,b=2。

四、引用传递和指针传递的区别

C语言中支持两种参数传递方式——值传递和指针传递,C++中支持三种传递方式——值传递、引用传递和指针传递,对于引用传递,C语言不支持,但是C++支持,所以上面的程序可以编译通过。

值传递和指针传递的区别是明显的,值传递是普通变量传递数值,指针传递是指针变量传递引用。

这里谈论引用传递和指针传递的区别,根本区别:引用传递中形参和实参是同一对象,指针传递中形参和实参指向同一对象。

06920e8bdaf292aaf50ea2be48e54df5.png

五、尾声

本节介绍C/C++函数参数传递的三种方式——传值、传引用、传地址,是属于C/C++入门级博客,希望对初学者有用。

天天打码,天天进步!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值