C++入门----缺省参数和函数重载

news2025/1/16 21:00:59

C++入门第一讲:

在这里插入图片描述

文章目录

  • C++入门第一讲:
    • 1.C++关键字(C++98)
    • 2.命名空间
      • 2.1命名空间的定义
    • 3.C++的输入和输出
    • 4.缺省参数
      • 4.1缺省参数的概念
      • 4.2缺省参数的分类
        • 4.2.1全缺省参数
        • 4.2.2半缺省参数
    • 5.函数重载
      • 5.1函数重载的概念
      • 5.2C++支持函数重载的原理 (名字修饰 -----name Mangling)
    • 6.总结

1.C++关键字(C++98)

C++总计63个关键字,C语言32个关键字

在这里插入图片描述

2.命名空间

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。

#include <stdio.h>
#include <stdlib.h>
int rand = 10;
// C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决
int main()
{
 printf("%d\n", rand);
return 0;
}
// 编译后后报错:error C2365: “rand”: 重定义;以前的定义是“函数”

2.1命名空间的定义

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。

#include<stdio.h>
#include <stdlib.h>

// 域
// 局部域/全局域:1、使用  2、生命周期
//int a = 2;

void f1()
{
	int a = 0;
	printf("%d\n", a);//局部优先原则,此处的局部变量a
	printf("%d\n",::a);  // ::域作用限定符,此处是全局变量a
}

void f2()
{
	int a = 1;
}

int main()
{
	printf("%d\n", a);
	f1();

	return 0;
}
#include "List.h"
#include "Queue.h"

//int main()
//{
//	struct AQueue::Node node1; //这里我们使用的是Queue.h文件中定义的命名空间AQueue里面的Node
//	struct BList::Node node2; //这里我们使用的是List.h文件中定义的命名空间BList里面的Node
//
//	AQueue::min++;
//	BList::min++;
//
//
//
//	return 0;
//}

namespace lyb
{
	namespace A				//命名空间的嵌套
	{

		struct Node
		{
			struct Node* next;
			int val;
		};

		struct Queue
		{
			struct Node* head;
			struct Node* tail;
		};

		int min = 0;
	}
}

int main()
{
	struct lyb::A::Node node1;
	struct lyb::B::Node node2;

	lyb::A::min++;
	lyb::B::min++;

	return 0;
}

命名空间是影响使用不影响生命周期,我们有三种访问命名空间的方式 :

1.指定命名空间访问

2.全局展开,但是一般情况下不建议全局展开

3.部分展开

下面我们用代码展示一下三种不同的访问方式:

#include <iostream>
#include "Queue.h"
using namespace std;

// 1、指定命名空间访问
// 2、全局展开. 一般情况,不建议全局展开的。
// 3、部分

int main()
{
	struct Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);

	std::cout << "1111";

	return 0;
}
#include <iostream>
using namespace std;
// 实际开发的项目工程
// 1、指定命名空间访问
// 3、常用部分展开

// 小的程序,日常练习,不太会出现冲突
// 2、全局展开.一般情况,不建议全局展开的。

// 常用展开
using std::cout;
using std::endl;

int main()
{
	cout << "1111" << endl;
	cout << "1111" << endl;
	cout << "1111" << endl;
	cout << "1111" << endl;

	int i = 0;
	std::cin >> i;

	return 0;
}

3.C++的输入和输出

#include<iostream>
// std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中
using namespace std;
int main()
{
cout<<"Hello world!!!"<<endl;
return 0;
}

说明:

1.使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含头文件以及按命名空间使用方法使用std;

  1. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< iostream >头文件中。

  2. <<流插入运算符,>>流提取运算符。

  3. C++输入输出可以自动识别变量类型。

    注意:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应头文件即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文件不带.h;旧编译器(vc 6.0)中还支持<iostream.h>格式,后续编译器已不支持,因此推荐使用+std的方式。

#include <iostream>
using namespace std;
int main()
{
   int a;
   double b;
   char c;
     
   // 可以自动识别变量的类型
   cin>>a;
   cin>>b>>c;
     
   cout<<a<<endl;
   cout<<b<<" "<<c<<endl;
   return 0;
}

关于cout和cin还有很多更复杂的用法,比如控制浮点数输出精度,控制整形输出进制格式等等。

std命名空间的使用惯例:

std是C++标准库的命名空间,如何展开std使用更合理呢?

  1. 在日常练习中,建议直接using namespace std即可,这样就很方便。
  2. using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模大,就很容易出现。所以建议在项目开发中使用,像std::cout这样使用时指定命名空间 + using std::cout展开常用的库对象/类型等方式。

4.缺省参数

4.1缺省参数的概念

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。

void Func(int a = 0)
{
 cout<<a<<endl;
}
int main()
{
 Func();     // 没有传参时,使用参数的默认值,即a=0;
 Func(10);   // 传参时,使用指定的实参
return 0;
}

4.2缺省参数的分类

4.2.1全缺省参数

// 全缺省
void Func(int a = 10, int b = 20, int c = 30)
{
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl;
	cout << endl;
}

4.2.2半缺省参数

void Func(int a, int b = 10, int c = 20)
 {
     cout<<"a = "<<a<<endl;
     cout<<"b = "<<b<<endl;
     cout<<"c = "<<c<<endl;
 }

特别注意:

  1. 半缺省参数必须从右往左依次来给出,不能间隔着给。

从右往左依次给出半缺省参数是指不能出现以下情况:

void Func(int a = 10, int b , int c = 20)  //这种情况就不符合从右往左依次给出,是错误的
 {
     cout<<"a = "<<a<<endl;
     cout<<"b = "<<b<<endl;
     cout<<"c = "<<c<<endl;
 }

2.缺省参数不能在函数声明和定义中同时出现

  //a.h 函数的声明
  void Func(int a = 10);
  
  // a.cpp  函数的定义
  void Func(int a = 20)
 {}
  
  // 注意:如果声明与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那个缺省值。
  1. 缺省值必须是常量或者全局变量

  2. C语言不支持(编译器不支持)

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    struct Stack
    {
    	int* a;
    	int top;
    	int capacity;
    };
    
    void StackInit(struct Stack* ps, int defaultCapacity = 4) //设置缺省值
    {
    	ps->a = (int*)malloc(sizeof(int) * defaultCapacity); //我们为栈开辟空间
    	if (ps->a == NULL)
    	{
    		perror("malloc fail");
    		exit(-1);
    	}
    	ps->top = 0;
    	ps->capacity = defaultCapacity;
    }
    
    int main()
    {
    	Stack st1; // 最多要存100个数
    	StackInit(&st1, 100);//我们指定大小为100,那么我们就开辟指定的100个空间
    
    	Stack st2; // 不知道多少数据
    	StackInit(&st2);//我们不知道开多大空间,那么就不指定,直接利用缺省参数,开辟4个int大小的空间
    
    	return 0;
    }
    

5.函数重载

5.1函数重载的概念

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数或者类型或者类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。

同名函数的形参列表不同:

1.参数类型不同

// 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;
}

相比较C语言来说,C++有函数重载,重载的情况如上,但是重载的原理是什么呢?

5.2C++支持函数重载的原理 (名字修饰 -----name Mangling)

  C语言不存在函数重载,C++才有函数重载,我们都知道函数的调用转到汇编代码就可以看到是一个个指令完成的,我们的C语言是根据函数名来查找的,即便满足上述函数重载的三个条件但是还是会报错,但是C++会对函数名字进行修饰,我们举个例子。因为在VS下C++函数名字修饰很复杂,所以我们在Linux操作系统下利用gcc和g++来分析:

如下是我们假设出来的函数:func1函数

在这里插入图片描述

我们来看一下在Linux操作系统下函数名是怎么样的

在这里插入图片描述

我们可以清楚的发现,C语言转成汇编代码函数名字还是func1,我们再来分析一下c++的情况:

在这里插入图片描述

同样的函数在两种情况下编译器编译完成后函数名竟然不一样了,C++的添加了一些符号,我们来分析一下这些符号都是什么意思?

最前面的_Z我们就当作默认的规则即可,后面的5表示我们的函数名有5个字符,函数名后面的id分别表示第一个形参是int型,第二个形参是double类型。所以我们就明白了C++有函数重载的原理,同时了解了Linux环境下C++名字修饰的含义。

但是还有一个易错点,如果我们函数的返回值类型不同会构成函数重载吗?

答案是错误的,这种情况不是函数重载,有人说因为C++名字修饰里面没有返回值,这个答案不完全对,本质是因为会造成函数调用的误解,我们进行函数调用的时候是不需要添加函数的返回值类型的,我们直接调用,如果两个函数的形参列表都相同唯独返回值不同,编译器也不知道该调用那个函数,就会报错,所以函数的返回值类型不同是不可以构成函数重载的。

6.总结

  我们对C++第一讲做一下总结:首先我们学习了C++的关键字,不要求全部背诵下来,但要对常用的要做到牢记于心,同时我们学习了C++的命名空间,这是一个全新的概念,在C语言中是没有这种概念的,我们深入了解了命名空间的使用和原理,之后我们学习了C++的输入和输出,即cin和cout,再接下来我们学习了缺省参数的相关知识,最后我们了解了一个全新的概念——函数重载,并且在Linux环境下分析了函数重载的原理,希望可以帮助到大家~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/155869.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在 SpringBoot 中 初步使用 MyBatis

这篇文章简单介绍如何初步使用MyBatis框架。MyBatis官网&#xff1a;mybatis – MyBatis 3 | 简介。本文中介绍MyBatis使用在SpringBoot中&#xff0c;Spring帮我们进行了管理&#xff0c;省去了获取sql的步骤。 什么是 MyBatis&#xff1f; MyBatis 是一款优秀的持久层框架&a…

XAML控件宽度为另一控件的一半、静态属性绑定、ObjectDataProvider

控件上当某些数据需要根据其他数据的变化而变化 很多时候&#xff0c;想让某个控件的宽度或者高度是另一个已有控件的一半&#xff0c;一开始打算使用ObjectDataProvider来实现&#xff0c;因为在控件上当某些数据需要根据其他数据的变化而变化时&#xff0c;可以使用ObjectDa…

Selenium实战【滑动验证码破解】【JAVA爬虫】

简介本文主要讲解&#xff0c;利用之前所学到的java selenium如何实战操作,浏览器控制鼠标&#xff0c;模拟人工操作滑动验证码。这里需要用javacv 的代码知识&#xff0c;用于计算图像中滑块需要移动的距离。实战目标网站&#xff1a;https://dun.163.com/trial/jigsaw操作流程…

【Java入门】Java注释和关键字

✅作者简介&#xff1a;CSDN内容合伙人、阿里云专家博主、51CTO专家博主、新星计划第三季python赛道Top1&#x1f3c6; &#x1f4c3;个人主页&#xff1a;hacker707的csdn博客 &#x1f525;系列专栏&#xff1a;Java入门 &#x1f4ac;个人格言&#xff1a;不断的翻越一座又一…

mycat个人详谈

项目背景 现在业务想实现不同的用户分别看到不同的数据库&#xff0c;领导说用mycat中间件试试。没有接触过这个东西&#xff0c;刚拿到手直接头皮发麻&#xff0c;现在搞定了&#xff0c;索性就记录一下 Mycat数据库分库分表中间件 简介 阿里大牛开发的开源免费产品&#x…

设计模式——抽象工厂模式

文章目录1. 抽象工厂模式的定义2. 抽象工厂模式的类图3. 抽象工厂模式的作用4. 抽象工厂模式的实现1. 抽象工厂模式的定义 提供一个接口&#xff0c;用于创建相关或依赖对象的家族&#xff0c;而不需要明确指定具体类。 抽象工厂允许客户使用抽象的接口来创建一组相关的产品&a…

OAuth 2.0简介

OAuth就是一种授权机制。数据的所有者告诉系统&#xff0c;同意授权第三方应用进入系统&#xff0c;获取这些数据。系统从而产生一个短期的、一定权限的令牌&#xff08;token&#xff09;&#xff0c;用来代替密码&#xff0c;供第三方应用使用。 流程 1.第三方客户端要求用…

【欧姆龙控制器NX1系列调研】

欧姆龙控制器NX1系列调研NX系列 NX1 CPU单元NX系列-EtherNet/IP耦合器单元NX系列-系统单元NX系列通信接口单元NX系列数字输入单元NX系列模拟量输入单元NX系列模拟量输出入单元NX系列 高速模拟量模块NX系列IO-Link 主站单元温度控制/温度输入单元位置接口单元NX系列 安全控制单元…

【algorithm】算法基础课---排序算法(附笔记 | 建议收藏)

&#x1f680;write in front&#x1f680; &#x1f4dd;个人主页&#xff1a;认真写博客的夏目浅石. &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;AcWing算法学习笔记 &#x1f4ac;总结&#xff1a;希望你看完…

CSS入门四、浮动

零、文章目录 文章地址 个人博客-CSDN地址&#xff1a;https://blog.csdn.net/liyou123456789个人博客-GiteePages&#xff1a;https://bluecusliyou.gitee.io/techlearn 代码仓库地址 Gitee&#xff1a;https://gitee.com/bluecusliyou/TechLearnGithub&#xff1a;https:…

mybatis参数配置和日志详解

生命周期和作用域是至关重要的&#xff0c;因为错误的使用会导致非常严重的并发问题 每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的&#xff0c;SqlSessionFactory的实例可以通过 SqlSessionFactoryBuilder 获得&#xff0c;而 SqlSessionFactoryBuild…

【stl容器--实践操作】

目录&#xff1a;前言一、string&#xff08;一&#xff09;初始化 、 赋值 、 拼接&#xff08;二&#xff09;单个字符的访问和修改[]、at()&#xff08;三&#xff09;插入和删除insert 、erase&#xff08;四&#xff09;查找和替换find、rfind、replace&#xff08;五&…

代码随想录-47-101. 对称二叉树

目录前言题目1.递归思路2. 本题思路分析&#xff1a;3. 算法实现4. pop函数的算法复杂度5. 算法坑点前言 在本科毕设结束后&#xff0c;我开始刷卡哥的“代码随想录”&#xff0c;每天一节。自己的总结笔记均会放在“算法刷题-代码随想录”该专栏下。 代码随想录此题链接 题目…

FileNotFoundError: [Errno 2] No such file or directory VSCode Python插件的工作路径

文章目录1 前言2 Python主进程工作路径3 解决参考1 前言 在VSCode中&#xff0c;你是否遇到这样的情况 Traceback (most recent call last):File "......*.py", line 1, in <module>with open(filepath, r) as f: FileNotFoundError: [Errno 2] No such file…

提面优秀成功上岸浙大MBA的一点经验——专业管理思维很重要

本人的学历背景比较一般&#xff0c;就是个普通一本&#xff0c;但大学时为了挣学分&#xff0c;参加了不少的活动&#xff0c;还考了教师资格证&#xff0c;并且还去山区支教过3个月&#xff0c;支教一开始也是为了学分&#xff0c;但是通过与孩子们的相处&#xff0c;其实自己…

http相关(更新中)

概念 HTTP&#xff08;hypertext transport protocol&#xff09;协议也叫超文本传输协议&#xff0c;这个协议详细规定了浏览器和万维网服务器之间互相通信的规则。HTTPS更安全&#xff1b;无状态&#xff0c;cookie解决了无状态的问题 请求过程 客户端发送给服务器的称为“…

深度聚类方法之跨实例引导的对比聚类(Cross-instance guided Contrastive Clustering,C3)

深度聚类方法之跨实例引导的对比聚类(Cross-instance guided Contrastive Clustering,C3) 1.参考文献 《C3: Cross-instance guided Contrastive Clustering》2.跨实例引导的对比聚类(Cross-instance guided Contrastive Clustering,C3) 该方法是在对比聚类(Contrastive Clus…

Linux系统编程——信号

1.信号 信号共性: 简单、不能携带大量信息、满足条件才发送。信号的特质: 信号是软件层面上的“中断”。一旦信号产生&#xff0c;无论程序执行到什么位置&#xff0c;必须立即停止运行&#xff0c;处理信号&#xff0c;处理结束&#xff0c;再继续执行后续指令。所有信号的产…

如何使用Element-UI?

文章目录Element-UI概述Element-UI快速入门Element 布局Layout 局部Container 布局容器Element-UI组件使用案例介绍准备基本页面完成表格展示拷贝修改完成搜索表单展示完成批量删除和新增按钮展示完成对话框展示完成分页条展示完整页面代码Element-UI概述 Element&#xff1a;…

day11|144.二叉树的前序遍历、145.二叉树的后序遍历、94.二叉树的中序遍历

144.二叉树的前序遍历 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,2,3] 示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[] 示例 3&#xff1a; 输入&#xf…