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

文章目录

  • 前言
    • 一、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++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.mzph.cn/news/651223.shtml

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

相关文章

二分算法模版

二分算法模版 实数二分算法模版实数二分模版题 整数二分算法模版向上取整二分模版向下取整二分模版二分模版的注意点二分模版中check函数的实现能够使用二分的条件 二分主要分两类&#xff0c; 一类是对实数进行二分&#xff0c;一类是对整数进行二分 对整数二分又分成2种&…

python-自动化篇-运维-监控-简单实例-道出如何使⽤Python进⾏系统监控?

如何使⽤Python进⾏系统监控&#xff1f; 使⽤Python进⾏系统监控涉及以下⼀般步骤&#xff1a; 选择监控指标&#xff1a; ⾸先&#xff0c;确定希望监控的系统指标&#xff0c;这可以包括 CPU 利⽤率、内存使⽤情况、磁盘空间、⽹络流量、服务可⽤性等。选择监控⼯具&#x…

Java实现加权平均分计算程序WeightedAverageCalculator

成绩加权平均分计算程序&#xff0c;带UI界面和输入保存功能。 因为本人对成绩的加权均分有所关注&#xff0c;但学校的教务系统查分时往往又不显示个人的加权均分&#xff0c;加之每次手动敲计算器计算很麻烦就花了点时间写了一个加权均分计算程序自用&#xff0c;顺便开源。…

STM32标准库——(5)EXTI外部中断

1.中断系统 中断&#xff1a;在主程序运行过程中&#xff0c;出现了特定的中断触发条件&#xff08;中断源&#xff09;&#xff0c;使得CPU暂停当前正在运行的程序&#xff0c;转而去处理中断程序&#xff0c;处理完成后又返回原来被暂停的位置继续运行 中断优先级&#xff…

《WebKit 技术内幕》学习之十五(6):Web前端的未来

6 Chromium OS和Chrome的Web应用 6.1 基本原理 HTML5技术已经不仅仅用来编写网页了&#xff0c;也可以用来实现Web应用。传统的操作系统支持本地应用&#xff0c;那么是否可以有专门的操作系统来支持Web应用呢&#xff1f;当然&#xff0c;现在已经有众多基于Web的操作系统&…

uniapp小程序:内存超过2mb解决方法(简单)message:Error: 上传失败:网络请求错误 代码包大小超过限制。

分析&#xff1a;这种情况是代码文件内存超过2mb无法进行预览上传 解决方法&#xff1a; 1、Hbuilder中点击运行-->运行到小程序模拟器--->运行时是否压缩代码 2、在微信小程序中点击详情--->本地设置&#xff1a; 3、点击预览即可运行了

两个近期的计算机领域国际学术会议(软件工程、计算机安全):欢迎投稿

近期&#xff0c;受邀担任两个国际学术会议的Special session共同主席及程序委员会成员&#xff08;TPC member&#xff09;&#xff0c;欢迎广大学界同行踊跃投稿&#xff0c;分享最新研究成果。期待这个夏天能够在夏威夷檀香山或者加利福尼亚圣荷西与各位学者深入交流。 SERA…

南方故乡吹来的风

故乡的风 - 张明敏 词&#xff1a;刘因国 曲&#xff1a;刘因国 南方故乡吹来的风 带着潮水的呼唤 吹着你的秀发 飘散着茉莉的香 茉莉的香哟 南方故乡吹来的风 带着渔船的归航 吹着你的欢畅 吹着渔帆点点醉哟 点点的醉哟 远方的姑娘 你是否听见 我的心在嘿哟 你…

上位机图像处理和嵌入式模块部署(c/c++ opencv)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 opencv可以运行在多个平台上面&#xff0c;当然windows平台也不意外。目前来说&#xff0c;opencv使用已经非常方便了&#xff0c;如果不想自己编译…

81 C++对象模型探索。数据语义学 - 静态成员变量的存取,非静态成员变量的存取

一&#xff0c;静态成员变量的存取 静态成员变量只有一个实体&#xff0c;保存在可执行文件的数据段中&#xff0c;如果没有初始化则保存在数据段的BBS中&#xff0c;由于存储在执行文件的数据段中&#xff0c;因此在编译阶段就会确定地址。当程序编译完成后&#xff0c;不管运…

20240127如何在线识别德语字幕?

20240127如何在线识别德语字幕&#xff1f; 2024/1/27 11:42 1945[科尔贝格]Kolberg 01:48:49 接近109分钟 德语视频的字幕OCR适配&#xff1a; 1、whisper&#xff0c;8:39-8:58&#xff0c;使用GTX1080需要接近20分钟。对整机性能要求比较重&#xff0c;特别吃显卡&#xff…

LabVIEW信号时间间隔测量

用LabVIEW软件平台开发一个用于测量两路信号时间间隔的系统。系统利用LabVIEW的数据采集和处理能力&#xff0c;能够准确测量并分析来自不同硬件板卡的信号时间间隔&#xff0c;这对于精确控制和数据分析至关重要。 系统主要由以下几部分组成&#xff1a;数据采集卡、信号处理…

力扣(LeetCode)227. 基本计算器 II

给你一个字符串表达式 s &#xff0c;请你实现一个基本计算器来计算并返回它的值。 整数除法仅保留整数部分。 你可以假设给定的表达式总是有效的。所有中间结果将在 [-231, 231 - 1] 的范围内。 注意&#xff1a;不允许使用任何将字符串作为数学表达式计算的内置函数&#…

三角函数、反三角函数

一、三角函数 二、反三角函数&#xff1a;已知三角函数值&#xff0c;反算角度大小 因为严格单调函数才有反函数一个y对应一个x&#xff0c;显然ysinx&#xff0c;ycosx&#xff0c;ytanx在其定义域并不是严格单调&#xff0c;所以需要人为划定范围。 1. 研究yarcsinx、yarcco…

CSS优先级内容

定义CSS样式时&#xff0c;经常出现两个或多个样式规则应用在同一元素的情况&#xff0c;这时就会出现优先级的情况&#xff0c;那么应用的元素应该显示哪一个样式呢&#xff1f; 一.下面举例对优先级进行具体讲解。 p{color:red;} .blue{color:orange;} #header{color:blu…

嵌入式学习-C++-Day3

嵌入式学习-CDay3 一、思维导图 二、作业 1.设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数和拷贝构造函数。 #inclu…

桌面型物联网智能机器人设计(预告)

相关资料 桌面级群控机器人CoCube探索-2022--CSDN博客 视频&#xff1a; 能&#xff01;有&#xff01;多&#xff01;酷&#xff01;CoCube桌面级群控机器人 让我看看谁在SJTU里划水… 简要介绍 设计一个桌面型物联网智能机器人&#xff0c;以ESP32芯片为核心&#xff0c;配…

pip 安装出现报错 SSLError(SSLError(“bad handshake

即使设置了清华源&#xff1a; pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simplepip 安装包不能配置清华源&#xff0c;出现报错: Retrying (Retry(total2, connectNone, readNone, redirectNone, statusNone)) after connection broken by ‘SSLE…

[Python] 如何在Windows下安装图形可视化工具graphviz

什么是graphviz? Graphviz是一款开源的图形可视化工具&#xff0c;用于生成各种结构化数据的图形表示。它支持多种图形排列算法&#xff0c;可以将复杂的数据关系用图形的方式直观地展示出来。Graphviz广泛应用于软件工程、数据可视化、计算机网络以及其他领域的可视化分析中…

springboot131企业oa管理系统

企业OA管理系统 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了企业OA管理系统的开发全过程。通过分析企业OA管理系统管理的不足&#xff0c;创建了一个计算机管理企业OA管理系统的方案。文章介绍了企业OA管…