非信用形参包括:
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、如果需要传递的实参数据很庞大,那么在使用非引用形参函数的时候,需要完全拷贝,这样做的时间和空间浪费的代价是很大的!

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

被折叠的 条评论
为什么被折叠?



