缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。
#include<iostream>
using namespace std;//使用using namespace 命名空间名称引入C++标准
void Func(int a = 0)
{
cout<<a<<endl;
}
int main()
{
Func(); // 没有传参时,使用参数的默认值
Func(10); // 传参时,使用指定的实参
return 0;
}
结果如下:
可以看到在定义
void Func(int a = 0)
时给int a 参数赋值为0; 所以当使用该函数时,如果不传参数:Func();
就默认传的参数为之前定义时赋值的0; 如果传参数:Func(10);
就正常传参即可;
注意:
//a.h
void Func(int a = 10);
// a.cpp
void Func(int a = 20)
{}
// 注意:如果声明与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那个缺省值。
void Func(int a = 10, int b = 20, int c = 30)
{
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl;
}
全缺省参数就是指定义函数时将所有的参数都赋值
void Func(int a, int b = 10, int c = 20)
{
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl;
}
半缺省参数就是指定义函数时将部分的参数赋值; 注意:半缺省参数必须从右往左依次连续来给出,中间不能有间隔;
例如:
#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{
cout << "int Add(int left, int right)" << endl;
return left + right;
}
double Add(double left, double right)
{
cout << "double Add(double left, double right)" << endl;
return left + right;
}
// 2、参数个数不同
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
// 3、参数类型顺序不同
void f(int a, char b)
{
cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
cout << "f(char b, int a)" << endl;
}
int main()
{
Add(10, 20);
Add(10.1, 20.2);
f();
f(10);
f(10, 'a');
f('a', 10);
return 0;
}
结果如下:
可以看到虽然函数名相同,但是对应不同的参数会调用不同的函数
int Add(int left, int right)
{
cout << "int Add(int left, int right)" << endl;
return left + right;
}
int Add(int right, int left)
{
cout << "int Add(int left, int right)" << endl;
return left + right;
}
结果如下:
在C++中,我们可以通过以下方式定义一个引用:
type &ref = variable;//类型& 引用变量名(对象名) = 被引用实体
例如:
void TestRef()
{
int a = 10;
int& ra = a;//<====定义引用类型
printf("%p\n", &a);
printf("%p\n", &ra);
}
注意:引用类型必须和引用实体是同种类型的
再举个例子:
可以看到它们都是同一个地址,指向同一个变量
#include <iostream>
int main() {
int num = 10;
int &ref = num; // 引用num变量
std::cout << "num: " << num << std::endl;
std::cout << "ref: " << ref << std::endl;
num = 20;
std::cout << "num: " << num << std::endl;
std::cout << "ref: " << ref << std::endl;
ref = 30;
std::cout << "num: " << num << std::endl;
std::cout << "ref: " << ref << std::endl;
return 0;
}
结果如下:
num: 10
ref: 10
num: 20
ref: 20
num: 30
ref: 30
可以看到,无论我们通过num还是ref来修改变量的值,都会影响到另一个变量的值,因为它们实际上是同一个变量的不同名称。
void TestRef()
{
int a = 10;
// int& ra; // 该条语句编译时会出错
int& ra = a;
int& rra = a;
printf("%p %p %p\n", &a, &ra, &rra);
}
结果如下:
C++中的常引用有两种情况:
int x = 10;
const int& ref = x;
在上面的例子中,ref是一个对x的常引用,意味着不能通过ref来修改x的值。
const int x = 10;
const int& ref = x;
在上面的例子中,ref是对常对象x的常引用。
常引用的作用是为了在不修改值的情况下使用对象,同时可以避免不必要的复制。常引用经常用于函数参数中,以便避免对实参进行复制。
指针和引用进行赋值和初始化时,权限可以缩小,但是不能放大
例如:
const int x = 10;
int& ref = x;//这是错误的,它放大了权限
在上面的例子中,原本的x被const修饰不能被改变数据,但是ref引用它时没有用const修饰说明可以被改动,放大了权限是不被接受的;这和指针是类似的:
const int* p1 = NULL; int* p2 = p1;//这也是错误的
void Swap(int& left, int& right)
{
int temp = left;
left = right;
right = temp;
}
结果如下:
可以看到我们没有使用传递变量的指针给函数就改变了实参的数据;
使用引用作为函数参数可以避免复制大量的数据,提高函数的效率。同时,通过引用传递参数可以实现对原始数据的修改,而不需要借助指针来实现。
引用作为函数的返回值前提是:返回的值在调用完函数后不会被释放销毁
例如:
int& Count()
{
static int n = 0;
n++;
return n;
}
n用static修饰为静态全局变量即使函数调用结束也不会被释放,所以可以用引用作为函数的返回值,这样就不需要再临时拷贝一份,减少了空间的消耗;
那么作为函数的返回值有什么作用呢? 举个例子:
#include<iostream>
#include<assert.h>
#define N 10
using namespace std;
//顺序表
typedef struct AY
{
int arr[N];
int size;
}AY;
int& PosAt(AY& ay, int x)
{
assert(x < N);
return ay.arr[x];
}
int main()
{
AY ay;
for (int i = 0; i < N; i++)
{
PosAt(ay, i) = i;//利用引用返回修改对应的值
}
for (int i = 0; i < N; i++)//打印
{
cout << PosAt(ay, i) << " ";
}
cout << endl;
return 0;
}
结果如下:
从上面的函数我们可以知道引用返回除了可以减少拷贝还可以修改返回的对象;
总结:如果函数返回时,出了函数作用域,如果返回对象还在(还没还给系统),则可以使用引用返回,如果已经还给系统了,则必须使用传值返回。
(1)在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间;而指针是保存着变量的地址的,是有独立的空间的;
例如:
int main()
{
int a = 10;
int& ra = a;
cout<<"&a = "<<&a<<endl;
cout<<"&ra = "<<&ra<<endl;
return 0;
}
结果如下:
通过上述例子我们发现引用和原来的变量的地址是一样的;
(2)在底层实现上实际是有空间的,因为引用是按照指针方式来实现的;
例如:
#include<iostream>
using namespace std;
int main()
{
int a = 10;
int& ra = a;
ra = 20;
int* pa = &a;
*pa = 20;
return 0;
}
结果如下:
通过上述例子,我们调试查看反汇编,发现引用和指针操作底层逻辑是一样的;
(3)引用和指针的不同:
以上就是C++中缺省参数、函数重载以及引用的所有内容啦 ~,缺省参数函数重载以及引用的出现是为了补充C语言语法的不足以及对C语言设计不合理的地方进行优化,引用的出现大大降低了我们学习C语言时相对于指针的难度,也便于我们更好的理解和使用,完结撒花 ~🥳🥳🎉🎉🎉