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

基本介绍

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只能被 隐式地转换为指针类型,⽽不能被转换为整数类型。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

The First项目报告:创新型金融生态Lista DAO

一、Lista DAO是什么&#xff1f; LISTA是Lista DAO的原生加密协议代币&#xff0c;设计为一种可互操作的实用代币&#xff0c;旨在促进去中心化金融&#xff08;DeFi&#xff09;领域内的支付、治理与激励。LISTA的诞生源于Lista DAO项目&#xff0c;该项目是一个基于BNB链的…

修BUG:程序包javax.servlet.http不存在

貌似昨晚上并没有成功在tomcat上面运行&#xff0c;而是直接运行了网页。 不知道为啥又报错这个。。。 解决方案&#xff1a; https://developer.baidu.com/article/details/2768022 就整了这一步就行了 而且我本地就有这个tomcat就是加进去了。 所以说啊&#xff0c;是不是&a…

【Linux进阶】文件系统5——ext2文件系统(inode)

1.再谈inode (1) 理解inode&#xff0c;要从文件储存说起。 文件储存在硬盘上&#xff0c;硬盘的最小存储单位叫做"扇区"&#xff08;Sector&#xff09;。每个扇区储存512字节&#xff08;相当于0.5KB&#xff09;。操作系统读取硬盘的时候&#xff0c;不会一个个…

基于主成分分析PCA的一维时间序列信号降噪方法(Python)

主成分分析PCA是面向模式分类的特征提取最典型的工具&#xff0c;是满足上述映射准则的一种数据压缩的方法。作为经典的特征提取方法&#xff0c;是在不减少原始数据所包含的内在信息前提下&#xff0c;将原始数据集转化为由维数较少的“有效”特征成分来表示&#xff0c;使其在…

34 超级数据查看器 关联图片

超级数据查看器app&#xff08;excel工具&#xff0c;数据库软件&#xff0c;表格app&#xff09; 关联图片讲解 点击 打开该讲的视频 点击访问app下载页面 豌豆荚 下载地址 大家好&#xff0c;今天我们讲一下超级数据查看器的关联图片功能 这个功能能让表中的每一条信息&…

NodeJS餐厅点餐系统-计算机毕业设计源码71834

摘要 随着移动互联网技术的迅猛发展&#xff0c;微信小程序因其便捷性和即用即走的特性&#xff0c;成为了连接用户与服务的新桥梁。Node.js作为一种高效、轻量级的后端技术&#xff0c;为开发者提供了快速构建服务器端应用的能力。本文介绍了一个基于微信小程序和Node.js的餐厅…

【数组、特殊矩阵的压缩存储】

目录 一、数组1.1、一维数组1.1.1 、一维数组的定义方式1.1.2、一维数组的数组名 1.2、二维数组1.2.1、二维数组的定义方式1.2.2、二维数组的数组名 二、对称矩阵的压缩存储三、三角矩阵的压缩存储四、三对角矩阵的压缩存储五、稀疏矩阵的压缩存储 一、数组 概述&#xff1a;数…

在Android Jetpack Compose中实现夜间模式

在Android Jetpack Compose中实现夜间模式 随着用户对夜间模式需求的增加,Android开发者需要掌握如何在应用中实现这一功能。Jetpack Compose作为现代Android UI工具包,提供了简便且灵活的方式来实现夜间模式。本文将详细介绍如何在Jetpack Compose中实现夜间模式,包括配置…

智能指针的认识和应用

众所周知&#xff0c;大家在写代码时&#xff0c;常常会去malloc或者new指针&#xff0c;但是常常忘记了释放这些不再使用的资源&#xff0c;虽然这些资源很少&#xff0c;但是计算机中资源也是有限的。如此反复下去&#xff0c;计算机就会很卡&#xff0c;因为没有资源。 如何…

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

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

AI Earth——2020年中国建筑物高度CNBH数据产品(10m)

数据介绍: 复旦大学生命科学学院GC3S团队(吴万本博士、赵斌教授等)利用多源地球观测数据和机器学习技术,构建了中国第一个10米分辨率的建筑高度估计模型(CNBH-10m)。基于此模型建立了中国10米分辨率的建筑高度数据集。此数据集基于全天候地球观测(雷达、光学和夜光图像)…

前端面试代码题

本文总结面试过程中遇到的代码题。 1. 变量提升 2. 数组相关的方法 注意返回true值是保留不是过滤&#xff0c;别记反。没啥&#xff0c;就是gap半年在面不写会忘的。。。 arr.filter((item, index, current) > {return arr.indexOf(item) index});。可以去重 filter本质…

前端 js 单引号,双引号、斜杠, 表格 tr input、checkbox、、、、

直接上代码 var target (leftOrRight LEFT ? $("#left") : $("#right"));target.empty();// let tbody $("resultRight tbody");// tbody.empty();for (var i 0; i < items.length; i) {debugger// target.append("<option valu…

【数据结构】线性表----队列详解

1. 队列的基本概念 话不多说&#xff0c;直接开始&#xff01; 队列是一种线性数据结构&#xff0c;同栈类似但又不同&#xff0c;遵循先进先出&#xff08;FIFO, First In First Out&#xff09;的原则。换句话说&#xff0c;最先进入队列的元素会最先被移除。这样的特点使得…

【Spring Cloud精英指南】深度探索与实战:网关Gateway的高级应用与最佳实践

1. 前言 Spring Cloud Gateway提供了一个在Spring生态系统之上构建的API网关&#xff0c;包括&#xff1a;Spring 5&#xff0c;Spring Boot 2和Project Reactor。Spring Cloud Gateway旨在提供一种简单而有效的路由方式&#xff0c;并为它们提供一些网关基本功能&#xff0c;…

IntelliJ IDEA 2024.1.4最新教程!!直接2099!!爽到飞起!!

IntelliJ IDEA 2024.1.4最新破解教程&#xff01;&#xff01;直接2099&#xff01;&#xff01;爽到飞起&#xff01;&#xff01;【资源在末尾】安装馆长为各位看官准备了多个版本&#xff0c;看官可根据自己的需求进行下载和选择安装。https://mp.weixin.qq.com/s/Tic1iR_Xc…

C语言-顺序表

&#x1f3af;引言 欢迎来到HanLop博客的C语言数据结构初阶系列。在这个系列中&#xff0c;我们将深入探讨各种基本的数据结构和算法&#xff0c;帮助您打下坚实的编程基础。本次我将为你讲解。顺序表&#xff08;也称为数组&#xff09;是一种线性表&#xff0c;因其简单易用…

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

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

Ajax从零到实战

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…