C++的关键字,命名空间,缺省参数,函数重载以及原理

news2025/4/20 8:18:43

文章目录

  • 前言
    • 一、C++关键字(C++98)
    • 二、命名空间
      • 命名空间介绍
      • 命名空间的使用
    • 三、C++输入【cin】& 输出【cout】
    • 四、缺省参数
      • 缺省参数概念
      • 缺省参数分类
      • 缺省参数的使用
      • 小结一下
    • 五、函数重载
      • 函数重载介绍
      • 函数重载类型
    • 六、C++支持函数重载的原理--名字修饰(name Mangling)【重点】

前言

从今天开始就序列更新C++的文章了,希望大家可以耐心的坚持下去学习,有一个很好的成长~~

首先来看一下C++的介绍,百度百科C++ – >点我跳转

C++是在C的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式
等。熟悉C语言之后,对C++学习有一定的帮助,本章节主要目标:

  1. 补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的,比如:作用
    域方面、IO方面、函数方面、指针方面、宏方面等。
  2. 为后续类和对象学习打基础。
  • 我们这里不讲和C语言重合的语法,直接上干货,新内容,没有学过C语言的可以关注一下C语言的专栏
  • 下面直接开始C++之旅~~

C语言有关键字,那么C++也有关键字,首先我们来认识一下这些关键字

一、C++关键字(C++98)

  • C++总计63个关键字,C语言32个关键字
  • 这些关键字我们已经在C语言阶段已经有些见到过了,那些没有见过的关键字我们在后续的练习中会反复用到,所以也不用刻意记住慢慢的就都知道了~~
asmdoifreturntrycontinue
autodoubleinlineshorttypedeffor
booldynamic_castintsignedtypeidpublic
breakelselongsizeoftypenamethrow
caseenummutablestaticunionwchar_t
catchexplicitnamespacestatic_castunsigneddefault
charexportnewstructusingfriend
classexternoperatorswitchvirtualregister
constfalseprivatetemplatevoidtrue
const_castfloatprotectedthisvolatilewhile
deletegotoreinterpret_cast

第二个我们来认识一个新的概念叫命名空间

二、命名空间

命名空间介绍

  • C++ 的命名空间(Namespace)是一种用于组织和管理代码标识符(变量、函数、类等)的方法。它可以避免命名冲突,使得在不同的命名空间中可以使用相同的标识符而不会产生命名冲突。

  • 使用命名空间可以将一组相关的标识符封装在一起,提供了更好的代码组织和模块化能力。在 C++ 中,可以通过关键字 namespace 定义一个命名空间,并在其中声明相关的标识符。


  • 我们来看下面代码,定义了一个全局变量rand,而我还引入了头文件stdlib,而这个rand是stdlib中的一个库函数,–>rand,这样我想打印这个rand的值就会与库函数里的rand产生冲突,产生重定义,这个就是C语言中的不足之处了
#include <stdio.h>
#include <stdlib.h>
int rand = 10;

int main()
{
	printf("%d\n", rand);
	return 0;
}

在这里插入图片描述

  • 在C++中就可以很好的解决这种问题:

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

  • 首先第一个正常的命名空间定义,也就是namespace后面跟上一个名字【随便起~】,也就相当于是一个域,就好像C语言中的局部域,全局域。
namespace lsl 
{
	// 命名空间中可以定义变量/函数/类型
	int rand = 10;
	
	int Add(int left, int right)
	{
		return left + right;
	}

	struct Node
	{
		struct Node* next;
		int val;
	};
}
  • 第二个就是命名空间可以嵌套
  • 这个也可以很好的理解,就和函数嵌套一样,一个域是一个域的,互不干扰
namespace N1
{
	int a;
	int b;
	int Add(int left, int right)
	{
		return left + right;
	}
	namespace N2
	{
		int c;
		int d;
		int Sub(int left, int right)
		{
			return left - right;
		}
	}
}
  • 第三个就是同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。

在这里插入图片描述

注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中

  • 那么我这个命名空间域如何使用呢?

  • 来看下面这段代码

namespace lsl
{
	// 命名空间中可以定义变量/函数/类型
	int a = 0;
	int b = 1;
	int Add(int left, int right)
	{
		return left + right;
	}
	struct Node
	{
		struct Node* next;
		int val;
	};
}
int main()
{
	printf("%d\n", a);
	return 0;
}

在这里插入图片描述

  • 上面图片清晰的展示到,是不能这样用的,已经是在一个域里面了,所以就要使用特定的方法来使用这个域里面变量,函数和类型

命名空间的使用

命名空间的使用有三种方式:

  • 第一种方式加命名空间名称及作用域限定符【::】也就是两个冒号,也就是域作用限定符
int main()
{
	printf("%d\n", lsl::a);
	return 0;
}

在这里插入图片描述

  • 第二种方式使用using将命名空间中某个成员引入

在这里插入图片描述

  • 第三种方式就是使用using namespace 命名空间名称引入,也就是展开,让指定的命名空间里的内容在外面都可以访问

在这里插入图片描述

这里的最后一种方式相信大家学c++或多或少也都见到过,平常在使用c++的时候都要有这么一句using namespace std;,std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中,这里的展开和头文件的展开是不一样的,不要混淆了~~

到这里我们也知道了,首先是先从局部域来搜索,然后从全局域再搜索,搜索不到就报错了,然而我们这里新增加了一个域作用限定符【::】,有了这个就是指定域搜索


  • 编译器搜索原则:

不指定域:当前局部域,全局域
指定域:如果指定了,直接去指定域搜索


三、C++输入【cin】& 输出【cout】

  • 在学习一门语言的时候,大部分人都会第一次写下这么一段代码,打印hello world,C++怎么来打印呢?
#include<iostream>
using namespace std;
int main()
{
	cout << "hello world" << endl;
	return 0;
}

在这里插入图片描述

说明:

  1. 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含 < iostream >头文件以及按命名空间使用方法使用std
  2. coutcin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含头文件中。后面在实际应用中会回用到很多,慢慢都会介绍~~
  3. <<流插入运算符>>流提取运算符
  4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。C++的输入输出可以自动识别变量类型
  • 注意:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应头文件即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文件不带.h;旧编译器(vc 6.0)中还支持<iostream.h>格式,后续编译器已不支持,因此推荐使用+std的方式。

  • 这里的cout【输出】,cin【输入】可以自动识别类型

在这里插入图片描述

std命名空间的使用惯例:

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

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

四、缺省参数

缺省参数概念

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

接下来看一个案例就能明白了:

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

在这里插入图片描述

缺省参数分类

  • 全缺省参数【也就是从左到右形参都有默认值】
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;
}

缺省参数的使用

  • 我们可以这样使用:
  • 第一个参数就是匹配的一个形参,依次匹配,不可跳跃的传参

在这里插入图片描述

  • 实际上我们是还可以这样用的,比如说我是定义了一个栈,栈在初始化的的时候不知道一开始初始化多少个,这个时候我们就可以使用缺省参数,指定传参。
  • 比如我知道要插入100个数据,我就直接指定100的大小就可以,减少扩容消耗
  • 如果不知道多少个就默认4个就可以啦~~

在这里插入图片描述

还有一个重要的点,就是下面这里

  • 我们这里可以分文件写这个栈

在这里插入图片描述

  • 我们这里的声明定义可以同时写吗?

我们有人写代码的时候就有可能写成这样的操作,声明的参数和定义的参数不一样,那么是依谁的为准呢?

在这里插入图片描述

  • 我们这里直接给出结论,是必须在声明给,为什么呢?
  • 这就需要了解代码的编译原理了,到时候会发表一篇C语言的编译程序环境和预处理,程序编译+链接全过程,尽情期待~~
  • 在同一文件下,缺省值在函数的声明与定义中同时定义,在编译阶段的语法检查时,直接报错了~

小结一下

1. 半缺省参数必须从右往左依次来给出,不能间隔着给
2. 缺省参数不能在函数声明和定义中同时出现
3. 缺省值必须是常量或者全局变量
4. C语言不支持(编译器不支持)


五、函数重载

函数重载介绍

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

函数重载类型

函数重载有3个类型,我们分别来看一下:

  • 第一个就是参数类型不同

在这里插入图片描述

第二个是参数个数不同

在这里插入图片描述

  • 第三个就是参数类型顺序不同

在这里插入图片描述

  • 最后这里要注意:构成函数重载的条件是函数名相同,参数不同,构成函数重载【非常重要】

下面我们来看一道题【自己先做一下】来巩固一下:

以下不是double compare(int,int)的重载函数的是( )

A. int compare(double,double)
B. double compare(double,double)
C. double compare(double,int)
D. int compare(int,int)

解析:

A.重载必须是参数列表有所不同(包括个数和类型),所以参数类型不同,构成重载
B.参数类型不同,构成重载
C.参数类型不同,构成重载
D.函数重载不能依靠返回值的不同来构成重载,因为调用时无法根据参数列表确定调用哪个重载函 数,故错误


六、C++支持函数重载的原理–名字修饰(name Mangling)【重点】

那么为什么C++支持函数重载呢?而C语言不支持呢?

  • 靠的就是名字修饰

在这里插入图片描述

  1. 实际项目通常是由多个头文件和多个源文件构成,而通过C语言阶段学习的编译链接,我们可以知道,【当前a.cpp中调用了b.cpp中定义的Add函数时】,编译后链接前,a.o的目标文件中没有Add的函数地址,因为Add是在b.cpp中定义的,所以Add的地址在b.o中。那么怎么办呢?
  2. 所以链接阶段就是专门处理这种问题,链接器看到a.o调用Add,但是没有Add的地址,就会到b.o的符号表中找Add的地址,然后链接到一起。
  3. 那么链接时,面对Add函数,链接接器会使用哪个名字去找呢?这里每个编译器都有自己的函数名修饰规则。
  4. 由于Windows下vs的修饰规则过于复杂,而Linux下g++的修饰规则简单易懂,下面我们使用了g++演示了这个修饰后的名字。
  5. 通过下面我们可以看出gcc的函数修饰后名字不变。而g++的函数修饰后变成【_Z+函数长度+函数名+类型首字母】。

在这里插入图片描述

  • gcc编译后的结果:

在这里插入图片描述

结论:在linux下,采用gcc编译完成后,函数名字的修饰没有发生改变,之所以就函数名不能相同

  • 采用C++编译器编译后结果:

在这里插入图片描述

结论:在linux下,采用g++编译完成后,函数名字的修饰发生改变,编译器将函数参
数类型信息添加到修改后的名字中,所以就支持函数重载


  • Windows下名字修饰规则

在这里插入图片描述

  • 对比Linux会发现,windows下vs编译器对函数名字修饰规则相对复杂难懂,但道理都是类似的,我们就不做细致的研究了。

  • 扩展学习:C/C++函数调用约定和名字修饰规则–有兴趣好奇的同学可以自行搜索看一看,里面有对vs下函数名修饰规则讲解

  • 通过这里就理解了C语言没办法支持重载,因为同名函数没办法区分。而C++是通过函数修饰规则来区分只要参数不同修饰出来的名字就不一样,就支持了重载。

  • 如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为调用时编译器没办
    法区分。

最后,本章简单的介绍了C++的关键字,介绍了命名空间的作用和使用,知道了C++的输出和出入,会用缺省参数,以及函数重载~~

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

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

相关文章

【开源】基于JAVA语言的智慧社区业务综合平台

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 业务类型模块2.2 基础业务模块2.3 预约业务模块2.4 反馈管理模块2.5 社区新闻模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 业务类型表3.2.2 基础业务表3.2.3 预约业务表3.2.4 反馈表3.2.5 社区新闻表 四、系统展…

[BUUCTF]-PWN:hitcon2014_stkof解析

又是一道堆题&#xff0c;先看保护 关键信息&#xff0c;64位&#xff0c;没开pie。再看ida 大致就是alloc创建堆块&#xff0c;free释放堆块&#xff0c;fill填充堆块内容&#xff0c;以及一个看起来没啥用的函数&#xff0c;当然我也没利用这个函数去解题 这里有两种解法 解…

Python tkinter (6) Listbox

Python的标准Tk GUI工具包的接口 tkinter系列文章 python tkinter窗口简单实现 Python tkinter (1) —— Label标签 Python tkinter (2) —— Button标签 Python tkinter (3) —— Entry标签 Python tkinter (4) —— Text控件 GUI 目录 Listbox 创建listbox 添加元素…

Java版大厂算法题1——数字颠倒

问题描述 输入一个整数&#xff0c;将这个整数以字符串的形式逆序输出&#xff0c;程序不考虑负数的情况&#xff0c;若数字含有0&#xff0c;则逆序形式也含有0。如果输入为100&#xff0c;则输出为001。 数据范围&#xff1a;0<n<(2^30)-1 * 输入描述&#xff1a;输入…

2023启示录|虚拟人这一年

图片&#xff5c;《银翼杀手 2049》剧照 作者丨程心 编辑丨罗辑 2023 年&#xff0c;大模型 “救活” 了很多行业&#xff0c;其中最为反转的&#xff0c;就是把虚拟数字人&#xff08;以下简称虚拟人&#xff09;从活死人墓里拉了出来。 还没开年&#xff0c;在 2022 年火…

保姆级教学:Java项目从0到1部署到云服务器

目录 1、明确内容 2、apt 2.1、apt 语法 2.2、常用命令 2.3、更新apt 3、安装JDK17 4、安装MySQL 4.1、安装 4.2、检查版本及安装位置 4.3、初始化MySQL配置⭐ 4.4、检查状态 4.5、配置远程访问⭐ 4.6、登录MySQL 4.7、测试数据库 4.8、设置权限与密码⭐ 5、安…

基于Python flask MySQL 猫眼电影可视化系统设计与实现

1 绪论 1.1 设计背景及目的 猫眼电影作为国内知名的电影信息网站&#xff0c;拥有海量的电影信息、票房数据和用户评价数据。这些数据对于电影市场的研究和分析具有重要意义。然而&#xff0c;由于数据的复杂性和数据来源的多样性&#xff0c;如何有效地采集、存储和展示这些数…

0127-2-Vue深入学习5—Vue-Router路由模式

1、Vue-Router三种路由模式&#xff1a; hash&#xff1a;#️⃣使用URL hash 值来做路由&#xff0c;支持所有路由器&#xff1b;history:&#x1f4d6;依赖HTML5 History API和服务器配置&#xff1b;abstract:⛓支持所有JS运行环境&#xff0c;Node.js服务端&#xff1b; 1.1…

基于springboot+vue+mysql+mybatis的博客系统源码+数据库

pb-cms 介绍 博客系统&#xff0c;架构&#xff1a;springbootvuemysqlmybatis 软件架构 软件架构说明 系统截图 技术选型 技术版本说明Spring Boot2.1.6MVC核心框架Spring Security oauth22.1.5认证和授权框架MyBatis3.5.0ORM框架MyBatisPlus3.1.0基于mybatis&#xff0…

HCIA-HarmonyOS设备开发认证-3.内核基础

目录 前言目标一、进程与线程待续。。。 前言 对于任何一个操作系统而言&#xff0c;内核的运行机制与原理是最为关键的部分。本章内容从多角度了解HarmonyOS的内核运行机制&#xff0c;涵盖进程与线程的概念&#xff0c;内存管理机制&#xff0c;网络特性&#xff0c;文件系统…

高级CPU(提高CPU运行速度)

晶体管 早期是加快晶体管切换速度,来提升CPU速度 增加电路 给CPU专门的除法电路其他电路来做复杂操作 缓存&#xff08;cache&#xff09; 给CPU加缓存&#xff08;cache&#xff09;,提高数据存取速度,更快送给CPU&#xff0c;因为处理器里空间不大所以缓存一般只有KB或M…

BGP:03 BGP路由

这是实验拓扑&#xff0c;IBGP 利用环回口建立邻居&#xff0c;IGP 协议为 OSPF&#xff0c; EBGP 通过物理接口建立邻居 基本配置&#xff1a; R1: sys sysname R1 int loop 0 ip add 1.1.1.1 24 int g0/0/0 ip add 192.168.12.1 24 qR2: sys sysname R2 int loop 0 ip ad…

基于SSM的网络办公系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的网络办公系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring Spri…

c语言基础6

1.逗号表达式 逗号表达式&#xff0c;就是用逗号隔开的多个表达式。 逗号表达式&#xff0c;从左向右依次执行。整个表达式的结果是最后⼀个表达式的结果。 我们来看下面的一个代码&#xff1a; int main() {int a 1;int b 2;int ret (a > b, a b 2, b, b a 1);p…

shell脚本基础之函数与数组详解

目录 一、shell函数 1、shell函数的概念 2、shell函数的用法 2.1 定义函数 2.2 调用函数 2.3 函数作用范围 2.3.1 调用函数的范围 2.3.2 全局作用域和局部作用域 3、 函数返回值 3.1 系统默认的返回值 3.2 return语句 4、函数传参 5、查看函数列表 6、删除函数 …

RC4Drop加密:提升数据保护的新选择

摘要&#xff1a;RC4Drop是一种基于RC4算法的加密技术&#xff0c;通过将明文数据分成多个部分并进行加密&#xff0c;实现了对数据的高效保护。本文将对RC4Drop加密技术的优缺点进行详细分析&#xff0c;并给出一个Java完整demo示例。 RC4Drop加密解密 | 一个覆盖广泛主题工具…

kafka-顺序消息实现

kafka-顺序消息实现 场景 在购物付款的时候&#xff0c;订单会有不同的订单状态&#xff0c;对应不同的状态事件&#xff0c;比如&#xff1a;待支付&#xff0c;支付成功&#xff0c;支付失败等等&#xff0c;我们会将这些消息推送给消息队列 &#xff0c;后续的服务会根据订…

Redis数据类型-string

Redis-string类型 Redis中的数据类型全局命令get&setredis中变量设置的过期时间是如何检测的 keysexistsdelexpirettlpexpirepttltype string数据类型的底层的数据结构操作string类型的常用命令get&setmset&mgetsetnxsetexpsetexincr&decrincrby&decrbyinc…

前端实现弹小球功能

这篇文章将会做弹小球游戏&#xff0c;弹小球游戏大家小时候都玩过&#xff0c;玩家需要在小球到达游戏区域底部时候控制砖块去承接小球&#xff0c;并不断的将小球弹出去。 首先看一下实现的效果。 效果演示 玩家需要通过控制鼠标来实现砖块的移动&#xff0c;保证在小球下落…

借款还款记录账本,助你轻松地应对借还款带来的种种问题

借还款明细管理看似琐碎&#xff0c;实则关乎我们的切身利益。现在有【晨曦记账本】为你的财务健康保驾护航&#xff0c;让你可以更加轻松地应对借款和还款带来的种种问题&#xff0c;让生活更加简单、有序。 所需工具&#xff1a; 一个【晨曦记账本】软件 操作步骤&#xf…