C++ (第二天上午---函数重载和缺省参数和占位参数)

devtools/2024/9/23 13:20:00/

一、函数重载

1、问题的引入
在实际开发中,有时候我们需要实现几个功能类似的函数,只是有些细节不同。例如希望交换两个变量的值,这两个变量有多种类型,可以是 int、float、char、bool 等,我们需要通过参数把变量的地址传入函数内部。在C语言中,程序员往往需要分别设计出三个不同名的函数,其函数原型与下面类似:

void swap1(int *a, int *b);      //交换 int 变量的值
void swap2(float *a, float *b);  //交换 float 变量的值
void swap3(char *a, char *b);    //交换 char 变量的值
void swap4(bool *a, bool *b);    //交换 bool 变量的值

那么在C++中,有没有一种方法,允许多个函数拥有相同的名字,只要它们的参数列表不同就可以呢。
答案:使用函数重载。
2、概念
用相同的函数名定义多个不同的功能称为函数重载。重载的函数根据参数的个数和类型进行区分,但不能单独根据返回类型进行区分。
3、例子

void swap(int *a,int *b)
{*a = *a + *b;*b = *a - *b;*a = *a - *b;
}
void swap(float *a,float *b)
{*a = *a + *b;*b = *a - *b;*a = *a - *b;
}
void swap(char *a,char *b)
{*a = *a + *b;*b = *a - *b;*a = *a - *b;
}
void swap(bool *a,bool *b)
{*a = *a + *b;*b = *a - *b;*a = *a - *b;
}

在函数调用的时候会根据不同的参数列表选择调用对应的函数
4、函数重载的规则

  • 函数名称必须相同
  • 参数列表必须不同(个数不同、类型不同、参数排列顺序不同等)
  • 函数的返回类型可以相同也可以不相同。
  • 仅仅返回类型不同不足以成为函数的重载
    5、函数重载的作用
  • 解决函数名字资源问题
  • 函数调用的时候很方便,自动根据不同的参数调用不同函数(静态多态-编译时候多态)
    6、注意
    在c++中编译器会检查函数名称和参数列表, 在c语言中编译器只检查函数名称
    7、函数重载原理
    在这里插入图片描述
    总结:返回值不一样不能实现函数重载
    const参数能实现函数重载

二、函数默认参数(缺省实参)和占位参数

1、概念
在声明函数的时候可以赋予函数参数默认值。所谓默认值就是在调用时,可以不写某些参数的值,编译器会自动把默认值传递给调用语句中。
2、特点

  • 如果函数的声明和定义是分开的,必须在声明的时候设置默认值,不可以在定义的时候设置默认值;
  • 不能将实际值传递给引用类型的参数。可以将变量作引用类型参数的默认值,这时变量必须是已经声明且是全局变量
#include<iostream>using namespace std;int g_val = 10;//默认值是在函数声明的时候进行设置
int func(int a=10);
//不能将实际值传递给引用类型的参数。可以将变量作引用类型参数的默认值,这时变量必须是已经声明且是全局变量 
//int rfunc(int &a=10); --除非 const int &a=10
int rfunc(int &a=g_val);int main()
{func();return 0;
}
//如果函数的定义和声明是分开的,那么函数定义的时候不能设置默认值,而是在声明的时候进行设置
int func(int a)
{cout<<"a:"<<a<<endl;
}
int rfunc(int &a)
{cout<<"a:"<<a<<endl;
}
  • 若给某一参数设置了默认值,那么在参数表中其后所有的参数都必须也设置默认值
如果多参数默认,必须满足从右往左连续默认
void fun(int a, int b=9, int c=1); 允许
void fun(int a=1, int b, int c=2); 不允许

3、占位参数
占位参数:跟默认参数不同,在函数定义时,形参只写类型,不写形参变量名
语法:

返回值类型  函数名(type ) //type --- int char
{}
占位参数的使用场景比较少,只在运算符重载中可以应用
void test(int) //占位参数
{}
void test1(char) //占位参数
{}
int main()
{int b = 10;test(b); //带占位参数的函数调用时,要传入对应类型的参数值return
}

练习5:使用链表设计一个录入学生信息的函数(参数为学生信息)(输入信息有个学号,姓名,年龄,班级 参数顺序自定),结合函数重载和默认参数的特点,设计的时候使后期使用更方便

#include <iostream>
#include <cstring>/* 练习2:设计一个录入学生信息的函数(参数就是学生信息)
(输入的时候有姓名、年龄、班级...),结合函数重载和默认参数的特点
设计出来的程序使用的时候 更加方便 */using namespace std;enum MODE
{ADD, //增加SHOW,    //显示EXIT    //退出
};struct student{char name[256];int age;char classes[256];//班级
};//单向非循环链表
typedef struct node{struct student info;//数据域struct node *next;//指针域
}Node_t;//链表的头结点
typedef struct list{Node_t *head;//数据的首结点Node_t *tail;//数据的尾结点int nodeNumber;//链表中结点的个数
}List_t;List_t *create_list()
{//1、申请一个头结点的内存空间List_t *list = new List_t;list->head = list->tail = NULL;list->nodeNumber = 0;return list;
}void insert_nodeToList_tail(List_t *list,const char *name,const int age=21,const char *classes="gz2166")
{if(list==NULL)return ;//1、新建数据结点Node_t *newNode = new Node_t;//2、初始化strcpy(newNode->info.name,name);newNode->info.age = age;strcpy(newNode->info.classes,classes);newNode->next = NULL;//3、将新建的结点插入到链表中if(list->head == NULL) //从无到有{list->head = newNode;list->tail = newNode;}else{ //从少到多  ---尾插法//当前尾结点的next指向新结点list->tail->next = newNode;//更新尾结点list->tail = newNode;}list->nodeNumber++;}void print_allToList(List_t *list)
{Node_t *p = list->head;cout<<"姓名\t\t"<<"年龄\t"<<"班级\t"<<endl;while(p){cout<<p->info.name<<"\t\t"<<p->info.age<<"\t"<<p->info.classes<<"\t\t"<<endl;p = p->next;}
}int main()
{List_t *list = create_list();insert_nodeToList_tail(list,"zhang3",22);insert_nodeToList_tail(list,"li4");insert_nodeToList_tail(list,"laowang",23,"gz2169");print_allToList(list);return 0;
}

四、函数重载与函数默认参数
思考:假如一个程序中有如下两个函数

void test()
{
}
void test(int x=10)
{
}
调用:
test(11);//调用 的是:void test(int x=10)
test();//调用的是???歧义

答案:有歧义,解决方法:可以定义命名空间


http://www.ppmy.cn/devtools/56822.html

相关文章

6.The hardest part about learing hard things(学一件难的事,难在哪里)

I’ve been recording a lot of podcast interviews for my upcoming book, Ultralearning.One of the reurring themes I’ve noticed in our conversations is that how people feel about learning is the overwhelming cause of the results they experience. 我为我的新书…

[leetcode]文件组合

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:vector<vector<int>> fileCombination(int target) {vector<vector<int>> vec;vector<int> res;int sum 0, limit (target - 1) / 2; // (target - 1) / 2 等效于 target /…

哈希表(C++实现)

文章目录 写在前面1. 哈希概念2. 哈希冲突3. 哈希函数4.哈希冲突解决4.1 闭散列4.1.1 线性探测4.1.2 采用线性探测的方式解决哈希冲突实现哈希表4.1.3 二次探测 4.2 开散列4.2.2 采用链地址法的方式解决哈希冲突实现哈希表 写在前面 在我们之前实现的所有数据结构中(比如&…

【高性能服务器】多进程并发模型

&#x1f525;博客主页&#xff1a; 我要成为C领域大神&#x1f3a5;系列专栏&#xff1a;【C核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 对于常见的C/S模型…

【flutter】点击底部不同的item实现切换Scaffold

要实现底部导航栏的不同项目切换不同的 Scaffold&#xff0c;您可以使用 IndexedStack 和 BottomNavigationBar 的组合。IndexedStack 可以根据当前所选的底部导航栏项目来切换不同的 Scaffold。以下是一个示例代码&#xff1a; import package:flutter/material.dart;void ma…

大二暑假 + 大三上

希望&#xff0c;暑假能早睡早起&#xff0c;胸围达到 95&#xff0c;腰围保持 72&#xff0c;大臂 36&#xff0c;小臂 32&#xff0c;小腿 38&#x1f36d;&#x1f36d; 目录 &#x1f348;暑假计划 &#x1f339;每周进度 &#x1f923;寒假每日进度&#x1f602; &…

Windows页面错误(Page Fault)写几种c++会导致,此问题的例子

在C中&#xff0c;直接导致Windows页面错误&#xff08;Page Fault&#xff09;的情景较少直接由编程错误引发&#xff0c;页面错误更多是由操作系统在内存管理和虚拟内存机制中处理的。不过&#xff0c;某些编程错误可能导致访问违规&#xff0c;进而间接引起操作系统报告页面…

学生党蓝牙耳机推荐有哪些?四款学生党必入的性价比蓝牙耳机推荐

在数字化和移动设备普及的今天&#xff0c;蓝牙耳机已经成为了我们日常生活中不可或缺的一部分&#xff0c;尤其是对于学生群体来说&#xff0c;一款性价比高的蓝牙耳机都能极大地提升他们的生活质量&#xff0c;那么学生党蓝牙耳机推荐有哪些&#xff1f;市面上的蓝牙耳机品牌…