C++函数

2023-12-20 23:43:17

缺省参数与哑元

函数缺省参数

在C++中,函数的形参列表中是可以有默认值的。有默认值的参数即位默认参数。

在函数调用时,有默认参数可以缺省

语法:返回值类型 函数名 (参数=默认值){函数体}

#include <iostream>
using namespace std;

int add (int x,int y,int z = 100);
int main() {
    int a;
    a = add(100,200);
    cout << a << endl;
    return 0;
}

int add(int x,int y,int z) {
    return x + y + z;
}

//运行结果为400,只能在定义函数的地方有默认值,实现函数不能有默认值

注意事项:靠右原则,即如果某个参数有默认值,那么从这个位置往后,从左向右,必须都要有默认值;例如:

#include <iostream>
using namespace std;

int add(int x, int y = 1, z = 2) {
    return x + y + z;
}

int main(){
    int a;
    a = add(1);
    cout << a << endl;
    return 0;
}

//运行结果为4;

函数声明和函数实现(即函数定义),只允许有一个默认值,即如果函数声明有默认值,则函数实现的时候就不能有缺省参数;

#include <iostream>

using namespace std;

int add(int x, int y = 1, int z =12);

int main(int argc, const char *argv[])
{
	int a;
	a = add(1);
	cout << a << endl;
	return 0;
}

int add(int x, int y, int z) {
	
	return x + y + z;
}

哑元

只有类型而没有变量名的参数称为“哑元”

int func(int a, int) {
    ...
}

使用哑元的场景:

  • 兼容旧代码,保证函数的向下兼容性
void func(int i, int j) { ... } == 升级 void func(int i) {...}//升级之后,前面调用的函数需要修改传参
void func(int i, int j) { ... } == 升级 void func(int i,int) {...}//升级之后,前面调用的函数不需要修改传参

引用型参数

  • 可以将引用用于函数的参数,这是形参就是实参的别名
  • 引用型函数参数作用
  • 可以在函数中修改实参的值
#include <iostream>

using namespace std;

int swap(const int &a, const int &b);
int main(int argc, const char *argv[])
{
	int c;

	c = swap(1,2);

	cout << c << endl; 
	
	return 0;
}

int swap(const int &a, const int &b) {
	
	return a + b;
}

避免实参到形参值复制的开销,提高传参效率

#include <iostream>
using namespace std;

struct teacher{
	char name[100];
	int age;
};

void print(const teacher &t) {
	cout << t.name << " " << t.age << endl;
}

int main(int argc, const char *argv[])
{
    const teacher t = {"zhangsan", 28};

	print(t);

	return 0;
}

引用型函数参数可能意外修改实参,如果不希望通过引用修改实参本身,可以将其声明为常引用,在提高传参效率的同事还可以接收常量型实参。

int add(const int &a, const int &b) {
    return a + b;

}

int main(void) {
    add(3,5);
    return 0;
}

引用返回

可以将函数的返回类型声明为引用型,这时函数的返回结果就是return后面数据的别名,避免了函数返回值的开销。

函数中返回引用,一定要保证在函数返回之后,该引用的目标依然有效。

  • 可以返回全局变量、静态变量和成员变量的引用
  • 可以返回调用对象自身的引用
  • 可以返回堆中动态创建对象的引用
  • 不能返回局部变量的引用//非常危险
#include <iostream>

using namespace std;

int & add(int &a, int &b) {
	static int temp = a + b;
	return temp;
}
int main(int argc, const char *argv[])
{
	int a = 10;
	int b = 20;
	int x = add(a,b);

	cout << x << endl;
	
	return 0;
}

//temp变量必须加static或者设置成全局变量,不然调用完函数之后,temp变量的地址已经被系统回收

函数重载

函数重载:同一作用域,函数名相同,但是参数表必须有所区分(类型、个数、顺序),将构成重载关系。例如:

#include <iostream>
using namespace std;

void swap(int *a, int *b) {
	int tmp;
	tmp = *a;
	*a = *b;
	*b = tmp;
}
void swap(char *a, char *b) {
	char tmp;
	tmp = *a;
	*a = *b;
	*b = tmp;
}

void swap(bool *a, bool *b) {
	bool tmp;
	tmp = *a;
	*a = *b;
	*b = tmp;
}

int main(int argc, const char *argv[])
{
	int x = 10, y = 20;
	char a = 'a', b = 'b';
	bool m = true, n = false;

	swap(&x, &y);
	swap(&a, &b);
	swap(&m, &n);

	cout << x << " " << y << endl;
	cout << a << " " << b << endl;
	cout << m << " " << n << endl;
	
	return 0;
}

注释:三个函数名相同,但是参数数据类型不同,叫做函数重载

注意:形参变量名不同,不构成重载的要素

? ? ? ? ? ?函数返回类型不同,不构成重载要素。

函数重载的实现:编译器将形参变量的类型作为最终函数名的一部分

函数匹配的优先级:

当前g++编译器匹配的一般规则:

  1. 完全匹配(最高)
  2. 常量转换(较好)
  3. 升级转换(一般)
  4. 降级转换(较差)
  5. 省略号匹配(最差)
#include <iostream>

using namespace std;

void swap(int a, int b) {
	int tmp;
	tmp = a;
	a = b;
	b = tmp;

	cout << a << " " << b << endl;
}

void con(const int a) {
	cout << "con(const int a)" <<endl;
}

void foo(char a) {
	cout << "foo(char)" << endl;
}

void foo(int a) {
	cout << "foo(int)" << endl;
}

void hun(short a) {
	cout << "hun(short)" << endl;
}

void hum(int x, int y) {
	cout << "hum(int,int)" << endl;
	
}

void hum(int x, ...) {
	cout << "hum(int, ...)" << endl;
}
int main(int argc, const char *argv[])
{
	int x = 10, y = 20;
	short a = 12.12;
	swap(x,y);//完全匹配

	con(x);//常量转换

	foo(a);//升级转换short转int

	hun(a);//降级转换int 转 short

	hum(x,a);//最低级的是省略转换
	return 0;
}

注意二义性问题:

  • 默认类型转换带来的二义性
int func(unsigned int a) {
    return a;
}

int func(double a) {
    return a;
}

int n = 12;
func(n);//erro
  • 缺省参数带来的二义性
void func(int x, int y, int z = 100) {
	cout << "func(int,int,int)" << endl;
}

void func(int x, int y) {
	cout << "func(int,int)" << endl;
}

int x = 10, y = 20;

func(x,y);//erro

文章来源:https://blog.csdn.net/2201_75441920/article/details/135071322
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。