C++学习笔记:函数的参数传递之非引用形参

本文深入解析C++中非引用形参的特性,包括普通形参、指针形参的不同行为及其对函数调用的影响。通过实例展示非引用形参在函数中的传值方式,对比引用形参,阐述其局限性和应用场合。

非信用形参包括:
1)普通形参
①非const形参
②const形参
2)指针形参
①非const指针形参
②const指针形参

一、下面的例子说明了非引用形参的传参实例!

#include<iostream>
#include<string>
#include<stdlib.h>
#include<vector>
using namespace std;

void AddOne(int x)//非指针参数:非引用形参---就是copy(拷贝)
{
	x = x + 1;//这里实际是吧copy加一!!
}


//这里也是传递的是copy,但是是指针的copy,因此也能间接实现引用传递的功能
void AddTwo(int *px)//非引用形参:指针形参
{
	*px = *px + 2;
}

void AddThree(int& x)//参数:引用形参
{
	x = x + 3;//真正对传进来的实参进行加法
}
int main()
{
	int a, b, c;
	a = 1;
	b = 2;
	c = 3;
	cout << "加之前:" <<a<< endl;
	//并没有把 真正的a传进去,传进去的a是copy
	AddOne(a);
	cout << "加之后:" <<a<< endl;

	system("pause");
}

大部分的盆友可能乍一看会觉得加之后的a是2,其实不然,我们来看下结果
在这里插入图片描述
惊不惊喜,a还是2,因为所有的非引用参数在传递的时候其实是把实参的copy传递进去了,并没有把真正的实参传进去,因此在函数体中确实完成了加一的操作,但是却是对实参的copy进行操作,真正的函数外面的实参并没有变化!

那么我们在来看引用形参的实际传递情况!!

int main()
{
	int a, b, c;
	a = 1;
	b = 2;
	c = 3;
	cout << "加之前:" <<a<< endl;
	//并没有把 真正的a传进去,传进去的a是copy
	AddOne(a);
	cout << "加之后:" <<a<< endl;


	cout << "加之前:" << c << endl;
	//传的是真正的c,不是c的copy
	AddThree(c);
	cout << "加之后:" << c<< endl;
	system("pause");
}

运行结果如下:
在这里插入图片描述
那么我们使用非引用形参的指针形参效果又如何呢?

来看一下代码:

int main()
{
	int a, b, c;
	a = 1;
	b = 2;
	c = 3;
	cout << "非引用形参:非指针形参*************************************" << endl;
	cout << "加之前:" <<a<< endl;
	//并没有把 真正的a传进去,传进去的a是copy
	AddOne(a);
	cout << "加之后:" <<a<< endl;
	cout << "非引用形参:指针形参*************************************" << endl;
	cout << "加之前:" << b << endl;
	//并没有把 真正的a传进去,传进去的a是copy
	//把b的地址copy一个传进去,也会间接修改真正的b
	AddTwo(&b);
	cout << "加之后:" << b << endl;
	cout << "引用形参*************************************" << endl;
	cout << "加之前:" << c << endl;
	//传的是真正的c,不是c的copy
	AddThree(c);
	cout << "加之后:" << c<< endl;
	system("pause");
}

结果如下:
在这里插入图片描述
我们可以发现,好像使用指针形参也能实现对实参b的真正修改,其中的原理就是:这里因为是非引用形参只能传递copy,因此它会把b的地址copy一个进来,但是地址的拷贝还是原来的地址,因此对地址的操作就是对真正的b进行操作!!

二、接下来再看一个例子

#include<iostream>
#include<string>
#include<stdlib.h>
#include<vector>
using namespace std;

int add(int x, int y)//形参是非const的
{
	return x + y;
}

int add_2(const int x, const int y)//形参是const的
{
	return x + y;
}

int main()
{
	int a, b, c;
	const int m = 8, n = 9;//这里需要注意的是const变量只能在定义的同时给其赋值!!
	a = 1;
	b = 2;
	c = 3;
	//用非const变量传递到非const形参的函数中**********************
	int k = add(a, b);
	cout << k << endl;

	//用非const变量传递到非const形参的函数中***********************
	k = add(m, n);
	cout << k << endl;
	system("pause");
}

在这里插入图片描述
可以看到结果,尽管是const变量传递到非const形参的函数中是可以允许的,反之也是允许的!

那么const 形参的目的和好处是什么呢?
让我们来看一个函数

void addOne(const int x)
{
	x = x + 1;//传进来的x不能修改,因为是const
}

如果形参是const,那么意味着传进来的实参的copy(因为这里是非引用形参)就不能修改了,因此只要不进行对形参的修改,非const的实参也是可以传递它的copy进来!!,就比如上面的add_2函数

当然尽管形参是一个const的指针,也是不能修改的,因为该指针指向的是一个const的常量值

void AddOne(int *ip)//这样允许修改
{
	*ip = *ip + 1;
}

void AddTwo(const int *ip)//这样不允许修改
{
	*ip = *ip + 2;
}

int Add(const int *px,const int *py)
{
	return *px+*py;//这样的运算是可以被允许的
}

上面我们说到,一个const的实参传递到非const形参的函数中是被允许的,但是一个const的指针实参传递到非const指针形参的函数中是不被允许的,实例如下:

#include<iostream>
#include<string>
#include<stdlib.h>
#include<vector>
using namespace std;

int add(int x, int y)//形参是非const的
{
	return x + y;
}

int add_2(const int x, const int y)//形参是const的
{
	return x + y;
}
void AddOne(int *ip)
{
	*ip = *ip + 1;
}

int Add(const int *px, const int *py)
{
	return *px + *py;//这样的运算是可以被允许的
}
int main()
{
	int a, b, c;
	const int a2 = 10, b2 = 20, c2 = 30;
	a = 1;
	b = 2;
	c = 3;
	AddOne(&a);//非const int *  可以传给   非const int *
	//AddOne(&a2);//const int *  不可以传给  非const int *
	Add(&a, &b);//非const int *  可以传给   const int *
	Add(&a2, &b2);//const int *  可以传给   const int *
	system("pause");
}

因此可以列一个表格表示

非指针形参指针形参
Non-const->const(允许)Non-const->const(允许)
const->const(允许)const->const(允许
Non-const->const(允许)Non-const->Non-const(允许)
const->Non-const(允许)const->Non-const(不允许)

还有一点需要注意的是:
在C++语言中,继承了C语言的规定,认为const的非指针形参和非const的非指针形参是一样的,因此在使用函数重载的时候需要格外注意:

void fcn(int i) {}
void fcn(const int i) {}

这样是无法实现重载的!!!

三、非引用形参的局限性

1、想要修改某个值就没法实现,除非是用指针形参!
2、如果需要传递的实参数据很庞大,那么在使用非引用形参函数的时候,需要完全拷贝,这样做的时间和空间浪费的代价是很大的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值