初识C++ | 基本介绍、命名空间、输入输出、缺省函数、函数重载、引用、内联函数、nullptr

news2024/9/9 4:58:56

基本介绍

C++的起源

1979年,当时的 Bjarne Stroustrup 正在⻉尔实验室从事计算机科学和软件⼯程的研究⼯作。⾯对项⽬中复杂的软件开 发任务,特别是模拟和操作系统的开发⼯作,他感受到了现有语⾔(如C语⾔)在表达能⼒、可维护性 和可扩展性⽅⾯的不⾜。
于是,牛逼的祖师爷决定自己创造语言!
1983年,Bjarne Stroustrup 在C语⾔的基础上 添加了 ⾯向对象编程 的特性,设计出了C++语⾔的雏形, 此时的C++已经有了类、封装、继承等核⼼概念,为后来的⾯向对象编程奠定了基础。这⼀年该语⾔被正式命名为C++。

重点:C++祖师爷——Bjarne Stroustrup

           C++——在C语⾔的基础上产生的

                         可以进行C语言的过程化程序设计

                        可以进行以抽象数据类型为特点的基于对象的程序设计

                        可以进行面向对象的程序设计

C++的发展

时间:1998年

阶段:C++98

内容:第一个版本发布,绝大多数编译器都支持,得到了国际标准化组织(ISO)和美国标准化协会认可,以模板方式重写 C++ 标准库,引入了 STL (标准模板库)。

时间:2011年

阶段:C++11

内容:增加了许多特性,使得 C++ 更像一种新语言,比如:正则表达式、基于范围for循环、auto关键字、新容器、列表初始化、标准线程库等

时间:2020年

阶段:C++11

内容: 引入了许多新的特性,比如:模块(Modules)、协程(Coroutines)、范围(Ranges)、概念(Constraints)等重大特性,还有对已有特性的更新:比如Lambda支持模板、范围for支持初始化等

目前主要实用标准为 C++98 和 C++11

命名空间

产生背景:在C/C++中,变量、函数和后⾯要学到的类都是⼤量存在的,这些变量、函数和类的名称将都存在于全局作⽤域中,可能会导致很多冲突。
目的:对标识符的名称进⾏本地化,以避免命名冲突。

#include <iostream>
using namespace std;
namespace ONE {
	int n = 3;
}


namespace TWO {
	int n = 4;
}

int main() {
	cout << ONE::n << endl;
	cout << TWO::n << endl;
	return 0;
}

命名空间的定义

定义命名空间,需要使⽤到namespace关键字,后⾯跟命名空间的名字,然后接⼀对{}即可,{}中
即为命名空间的成员。命名空间中可以定义变量/函数/类型等。
namespace 关键字{
    //内容——可以定义变量/函数/类型等
}

namespace本质是定义出⼀个域,这个域跟全局域各⾃独⽴,不同的域可以定义同名变量。
C++中域有函数局部域全局域命名空间域类域
域影响的是编译时语法查找⼀个变量/函数/ 类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。
局部域和全局域除了会影响编译查找逻辑,还会影响变量的声明周期
命名空间域类域不影响变量声明周期
namespace只能定义在全局,当然他还可以嵌套定义
#include <iostream>
using namespace std;
namespace ONE{
	int n = 3;
	namespace TWO {
		int n = 4;
	}
}

int main() {
	cout << ONE::n << endl;
	cout << ONE::TWO::n << endl;
	return 0;
}

项⽬⼯程中多⽂件中定义的同名namespace会认为是⼀个namespace,不会冲突。
C++标准库都放在⼀个叫std(standard)的命名空间中。

命名空间的使用

一共有三种方法:

方法一:指定命名空间访问(推荐)

 // 指定命名空间访问
#include <iostream>
using namespace std;
namespace ONE{
	int n = 3;
}

int main() {
	cout << ONE::n << endl;
	return 0;
}
方法二:using将命名空间中某个成员展开(项⽬中经常访问的不存在冲突的成员推荐)
//using将命名空间中某个成员展开
#include <iostream>
using namespace std;
namespace ONE{
	int n = 3;
}
using ONE::n;
int main() {
	cout << n << endl;
	return 0;
}
方法三:展开命名空间中全部成员(冲突风险大,项目中不推荐)
//展开命名空间中全部成员
#include <iostream>
using namespace std;
namespace ONE{
	int n = 3;
}
using namespace ONE;
int main() {
	cout << n << endl;
	return 0;
}

输入输出

<iostream> 是 Input Output Stream 的缩写,是标准的输⼊、输出流库,定义了标准的输⼊、输
出对象。
cout/cin/endl等都属于C++标准库,C++标准库都放在⼀个叫std(standard)的命名空间中,所以要 通过命名空间的使⽤⽅式去⽤他们。
std::cin 是 istream 类的对象,它主要⾯向窄字符的标准输⼊流。
std::cout 是 ostream 类的对象,它主要⾯向窄字符的标准输出流。
std::endl 是⼀个函数,流插⼊输出时,相当于插⼊⼀个换⾏字符加刷新缓冲区。
<<流插⼊运算符>>流提取运算符
#include <iostream>
using namespace std;

	int n = 3;

int main() {
	cout << n << endl;//此处endl写成'/n'也是同样的效果
	return 0;
}
使用C++输入输出的优势
更⽅便,可以⾃动识别变量类型,不需要像printf/scanf输⼊输出时那样,需要⼿动指定格式。
C++的流能更好的⽀持⾃定义类型对象的输⼊输出。

缺省函数

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

全缺省就是全部形参给缺省值

半缺省就是部分形参给缺省值。(不是一半哦)

C++规定半缺省参数必须从右往左依次连续缺省不能间隔跳跃给缺省值。

带缺省参数的函数调⽤,C++规定必须从左到右依次给实参,不能跳跃给实参。

#include <iostream>
using namespace std;
//全缺省
void Print1(int a = 1, int b = 2) {
	cout<<"全缺省"<< endl;
	cout <<a<<endl;
	cout <<b<< endl;

}
//半缺省
void Print2(int a , int b ,int c=3) {
	cout << "半缺省" << endl;
	cout <<a<< endl;
	cout <<b<< endl;
	cout <<c<< endl;
}


int main() {
	//全缺省——不给参数
	Print1();
	//全缺省——给参数
	Print1(4, 5);
	//半缺省——给必要参数
	Print2(1,2);
	//半缺省——给所有参数
	Print2(1, 2, 4);
	return 0;
}
函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省
值。

函数重载

C++⽀持在同⼀作⽤域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或者类型不同
注意:返回值不同不能作为重载条件,因为调⽤时也⽆法区分。
#include <iostream>
using namespace std;

void func(int a) {
	cout << a << endl;
}

void func(int a,int b) {
	cout << a<<b << endl;
}

void func(double a) {
	cout << a  << endl;
}


int main() {
	func(1);
	func(1, 2);
	func(1.1111);

	return 0;
}

引用

引用的概念

引⽤不是新定义⼀个变量,⽽是给已存在变量取了⼀个别名,编译器不会为引⽤变量开辟内存空间,它和它引⽤的变量共⽤同⼀块内存空间。
引用的底层仍然是指针!
类型& 引⽤别名 = 引⽤对象;
#include<iostream>
using namespace std;

int main()
{
int a = 0;
// 引⽤:b和c是a的别名
int& b = a;
int& c = a;
// 也可以给别名b取别名,d相当于还是a的别名
int& d = b;
++d;
// 这⾥取地址我们看到是⼀样的
cout << &a << endl;
 cout << &b << endl;
cout << &c << endl;
cout << &d << endl;
return 0;
	 }

引用的特性

引⽤在定义时必须 初始化  
⼀个变量可以有多个引⽤(土豆有很多个别名:洋芋、马铃薯)
引⽤⼀旦引⽤⼀个实体,再不能引⽤其他实体(洋芋只能是土豆的别名,不能再成为其它蔬菜的别名)
这一点注意与指针区分开!

引用的使用

引⽤在实践中主要是于引⽤传参引⽤做返回值中减少拷⻉提⾼效率和改变引⽤对象时同时改变被 引⽤对象。
1. 引⽤传参
引⽤传参指针传参功能是类似的,引⽤传参相对更⽅便⼀些。
#include<iostream>
using namespace std;
//引用传参
void Swap(int& rx, int& ry)
 {
 int tmp = rx;
 rx = ry;
 ry = tmp;
 }

 int main()
 {
 int x = 0, y = 1;
 cout << x << " " << y << endl;

 Swap(x, y);
 cout << x << " " << y << endl;
 return 0;
 }
2.做返回值
int arr[5] = { 0 };//全局变量

int& func(int n) {
	
	return arr[n];
}


int main() {
	
	cout << arr[4] << endl;
	func(4)=1;//改变了arr[4]的值为1
	cout << arr[4] << endl;
	return 0;
}

const引用

可以引⽤⼀个const对象,但是必须⽤const引⽤const引⽤也可以引⽤普通对象
原因:因为对象的访问权限引⽤过程中 可以缩⼩ ,但是 不能放⼤
注意 :类似 int& rb = a*3; double d = 12.34; int& rd = d; 这样⼀些场景下a*3的和结果保存在⼀个临时对象中, int& rd = d 也是类似,在类型转换中会产⽣临时对象存储中间值,也就是时,rb和rd引⽤的都是临时对象,⽽C++规定临时对象具有常性,所以这⾥ 就触发了权限放⼤,必须要⽤const引⽤才可以。
 (临时对象:编译器需要⼀个空间暂存表达式的求值结果时临时创建的⼀个未命名的对象)

指针和引用的关系

C++中指针和引⽤就像两个性格迥异的亲兄弟,指针是哥哥,引⽤是弟弟,在实践中他们相辅相成,功 能有重叠性,但是各有⾃⼰的特点,互相不可替代。
引用指针
开不开空间?不开
初始化?必须初始化建议初始化,但不必须
改变对象?引⽤⼀个对象后,不能再引⽤其他对象可以改变指向对象
访问对象?可以直接访问需要解引⽤
sizeof中含义引⽤类型的⼤⼩
地址空间所占字节个数(32位平台下 占4个字节,64位下是8byte)
安全性更安全空指针和野指针的问题

内联函数

⽤inline修饰的函数叫做内联函数
nline int Add(int x, int y)
{
	return x + y;
}
inline对于编译器⽽⾔只是⼀个建议。
也就是说,你加了inline编译器也可以选择在调⽤的地⽅不展开,不同编译器关于inline什么情况展开各不相同,因为C++标准没有规定这个。inline适⽤于频繁调用的短小函数,对于递归函数,代码相对多⼀些的函数,加上inline也会被编译器忽略。
想象一下,假如一个内联函数内有100条语句:
没有展开:
call:相当于跳转,跳转到函数的地址
展开:
C++设计了inline⽬的就是替代C的宏函数
C语⾔实现宏函数也会在预处理时替换展开,但是宏函数实现很复杂很容易出错的,且不⽅便调试
#define ADD(x, y) ((x) + (y))	//通过宏函数实现ADD,复杂易错

inline不建议声明和定义分离到两个⽂件,分离会导致链接错误。因为inline被展开,就没有函数地址,链接时会出现报错。

内联函数特点:

  • 在 Debug 模式下,函数不会进行替换,可以进行调试
  • 在 Realse 模式下,函数会像宏函数一样展开,提高程序运行速度
  • 内联函数弥补了宏函数的不足,同时吸收了宏函数速度快的优点

补充:

vs编译器 debug版本下⾯默认是不展开inline的,这样⽅便调试,debug版本想展开需要设置⼀下
以下两个地⽅。

nullptr

NULL实际是⼀个宏,在传统的C头⽂件(stddef.h)中,可以看到如下代码:
#ifndef NULL
     #ifdef __cplusplus
         #define NULL 0
     #else
         #define NULL ((void *)0)
     #endif
 #endif
由此可见,C++中NULL被定义为字⾯常量0,而非void*。
为了修复这一漏洞,   C++11中引⼊nullptr。
nullptr是⼀个特殊的关键字,nullptr是⼀种特殊类型的字⾯量,它可以转换 成任意其他类型的指针类型。使⽤nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被 隐式地转换为指针类型,⽽不能被转换为整数类型。

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

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

相关文章

获取网页logo图标

怎么获取网页logo图标的URL链接 第一种方法&#xff1a; 最常用的方法&#xff08;适用于90%的站点&#xff09;是&#xff0c;直接在访问网址首页链接后加上上/favicon.ico&#xff0c;例如&#xff1a; https://www.baidu.com/favicon.ico 第二种方法&#xff1a; 按F12&…

Photoshop套索工具使用指南:解锁自由选区的艺术

在Adobe Photoshop的强大工具箱中&#xff0c;套索工具组是每位图像处理爱好者与专业人士的得力助手。这组工具&#xff0c;包括套索工具、多边形套索工具和磁性套索工具&#xff0c;为用户提供了高度灵活的选择区域方式&#xff0c;无论是处理复杂的图像边缘还是进行精细的抠图…

Flexcel学习笔记

1.引用的单元 FlexCel.Core 始终需要使用的一个单元。 多系统运行时。{$IFDEF LINUX}SKIA.FlexCel.Core{$ELSE}{$IFDEF FIREMONKEY}FMX.FlexCel.Core{ $ELSE}VCL.FlexCel.Core{$ENDIF}{$ENDIF} FlexCel.XlsAdapter这是FlexCel的xls/x引擎。如果您正在处理xls或xlsx文件&#x…

Centos7 新增yum源

背景&#xff1a;原来的yum源&#xff0c;无法下载yum包了。新增一个阿里云的&#xff08;网易163的源失效了&#xff0c;无法使用&#xff09; Could not retrieve mirrorlist http://mirrorlist.centos.org/?release7&archx86_64&repoos&infrastock error was …

PyCharm 2023.3.2 关闭时一直显示正在关闭项目

文章目录 一、问题描述二、问题原因三、解决方法 一、问题描述 PyCharm 2023.3.2 关闭时一直显示正在关闭项目 二、问题原因 因为PyCharm还没有加载完索引导致的 三、解决方法 方法一&#xff1a; 先使用任务管理器强制关闭&#xff0c;下次关闭时注意要等待PyCharm加载完索…

AI软件测试工程师需要学习什么,怎么学习

对于已经从事软件测试工作的人来说真是需要补充的是以下部分的内容 1.AI概念和原理:了解人工智能的基本概念、发展历史、应用领域等 对应内容 https://cloud.baidu.com/article/31805742.机器学习基础知识:学习机器学习的基本概念、算法和框架&#xff0c;如线性回归、迈辑回归…

第一次参加数学建模竞赛新手小白备赛经验贴

2024年暑假已经来临&#xff0c;下半年的数学建模竞赛非常多&#xff0c;许多同学可能是第一次参赛&#xff0c;对于如何准备感到迷茫和无从下手。在这种情况下&#xff0c;我们将分享一些备赛的小技巧&#xff0c;帮助大家在这个暑假更好的入门&#xff0c;即便是零基础的小白…

计算机视觉之ShuffleNet图像分类

前言 ShuffleNetV1是一种计算高效的CNN模型&#xff0c;旨在在移动端利用有限的计算资源达到最佳的模型精度。其设计核心是引入了Pointwise Group Convolution和Channel Shuffle两种操作&#xff0c;以降低模型的计算量并保持精度。与MobileNet类似&#xff0c;ShuffleNetV1通…

【Docker系列】Docker 镜像源:优化你的容器化开发流程

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

第18章 概率潜在语义分析:课后习题

本章概要&#xff1a; 1.概率潜在语义分析是利用概率生成模型对文本集合进行话题分析的方法。概率潜在语义分析受潜在语义分析的启发提出两者可以通过矩阵分解关联起来。 给定一个文本集合&#xff0c;通过概率潜在语义分析&#xff0c;可以得到各个文本生成话题的条件概率分布…

WebDriver与浏览器通信的深度剖析与探索

在自动化测试的世界里&#xff0c;WebDriver无疑是连接测试脚本与浏览器之间的桥梁&#xff0c;它让复杂的自动化测试成为可能。本文将深入探讨WebDriver与浏览器之间的通信机制&#xff0c;揭示它们之间如何协同工作&#xff0c;以及这一过程中涉及的关键技术和挑战。 一、We…

2493-04A-6 同轴连接器

型号简介 2493-04A-6是Southwest Microwave的连接器。该连接器是一种端子连接器&#xff0c;采用 1.0 毫米插头&#xff08;公头&#xff09;进行连接。它由多个部件组成&#xff0c;包括过渡块、接地板、螺纹夹紧板、发射针、冷板、底座、电路板和外壳等。 型号特点 外壳&…

stm32——AD采集以及DMA

今天继续我们的STM32的内容学习&#xff0c;我使用的单片机是STM32F103VCT6,通过Keil Array Visualization软件来观测AD采样出来的波形。先来看看本次实验用到的硬件知识。 首先是ADC&#xff08;Analog-to-Digital Converter&#xff09;是模拟信号转数字信号的关键组件&#…

[Linux]五种IO模型(图文讲解+故事讲解)

目录 一、对IO的理解&#xff1a;等拷贝 等 拷贝 二、五种IO模型&#xff08;解释其概念&#xff09; 1.阻塞IO 2.非阻塞IO 3.信号驱动IO 4.IO多路复用 5.异步IO IO速度比较 三、一个故事让你了解五种IO模型 四、同步VS异步 阻塞VS非阻塞 同步VS异步 阻塞VS非阻…

常用录屏软件,分享这四款宝藏软件!

在数字化时代&#xff0c;录屏软件已经成为我们日常工作、学习和娱乐中不可或缺的工具。无论你是需要录制教学视频、游戏过程&#xff0c;还是进行产品演示&#xff0c;一款高效、易用的录屏软件都能让你的工作事半功倍。今天&#xff0c;就为大家揭秘四款宝藏级录屏软件&#…

深度|不同数据系统中的“一致性”(Consistency)含义的区别

“你们的系统能实现强一致性吗&#xff1f;”作为过去几年一直在开发流处理系统的从业者&#xff0c;我经常被问到这个问题。我时常想自信地推销我们的产品&#xff0c;但现实情况是&#xff0c;回答这个问题并不简单。其中的挑战并不在于问题本身&#xff0c;而在于 “一致性”…

【芯片方案】珠宝手机秤方案

珠宝手机秤作为一种便携式电子称重设备&#xff0c;因其小巧、便携、精度高等特点&#xff0c;广泛应用于各种需要精确称重的场景。可能这个目前在国内使用的人比较少&#xff0c;但在西方国家珠宝手机秤却是可以用来送礼的物品。因为珠宝手机秤的外观跟手机外观大多相似&#…

【数据结构】排序——快速排序

前言 本篇博客我们继续介绍一种排序——快速排序&#xff0c;让我们看看快速排序是怎么实现的 &#x1f493; 个人主页&#xff1a;小张同学zkf ⏩ 文章专栏&#xff1a;数据结构 若有问题 评论区见&#x1f4dd; &#x1f389;欢迎大家点赞&#x1f44d;收藏⭐文章 ​ 目录 …

Python高级(三)_正则表达式

Python高级-正则表达式 第三章 正则表达式 在开发中会有大量的字符串处理工作,其中经常会涉及到字符串格式的校验。 1、正则表达式概述 正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为regex、…

springboot企业培训管理系统-计算机毕业设计源码50804

摘要 本研究旨在开发一套高效、安全、易用的springboot企业培训管理系统。该系统致力于提升企业的培训管理效率&#xff0c;确保培训质量与效果的持续优化。通过整合先进的AI技术&#xff0c;在企业培训管理中发挥着不可或缺的作用。 通过采用Java作为主要开发语言&#xff0c;…