C到C++——C++基础
C++是一种通用的、静态类型的、跨平台的编程语言。它是在1979年由Bjarne Stroustrup创建的,最初是作为C语言的扩展来支持面向对象编程。
C++在保留C语言的特性的同时,添加了许多其他的功能,包括类、对象、继承、多态、模板等。这使得C++成为了一种强大而灵活的编程语言,可以用于开发各种类型的应用程序,包括系统级软件、嵌入式系统、游戏开发、图形界面等。
C++也是一种高效的语言,其执行速度接近于C语言,因为它允许直接访问硬件和内存,并支持底层的操作。
C++还具有丰富的标准库,提供了许多常用的函数和数据结构,可以方便地进行文件操作、输入输出、字符串处理等。
总的来说,C++是一种功能强大、高效、灵活的编程语言,广泛应用于软件开发领域。
在系统的了解C++之前,我们要了解一些C++基础,以便我们后面更好的理解其他内容。大家也可以借助这一篇来了解C++对C有何变化:C++对C的扩充-CSDN博客
一.命名空间
1.1同名冲突
当我们在编写程序的时候,如果在一个作用域中出现了两个或多个同名的变量或者函数就会发生错误
int main()
{int a = 0;//……int a = 0;return 0;
}
我们在主函数这个作用域中定义了两个a变量,在编译的时候就会报错。这就是同名冲突。
同名冲突是在大型应用软件的设计过程中是非常容易发生的。比如程序员A在头文件codeA中定义了student类和fun函数,程序员B在头文件codeB中也定义了student类和fun函数。而当主程序员使用A、B写的功能时要包含其头文件,但是当包含之后,就会在编译时发生错误,因为头文件在编译时会展开,这就意味着在一个程序中同时出现了两个studen类和fun函数,此时就会导致编译失败,因为发生了同名冲突。
1.2命名空间
为了解决这个问题,ANSIC++增加了命名空间(namespace)。所谓命名空间,实际上就是一个由程序设计者命名的内存区域。程序设计者可以根据需要指定一些有名字的空间作用域,把一些全局实体分别放在各个命名空间中,从而与其他全局变量实体分割开来。
命名空间的定义格式为:
namespace 命名空间名
{//命名空间成员
}
如:定义一个名为xiasicheng的命名空间
namespace xiasicheng
{//命名空间成员const int a = 10;int a = 2;int func(){cout << "hello" << endl;}struct student{int age;char name[10];};}
命名空间的作用时建立一些互相分隔的作用域,把一些全局实体分隔开来,以免产生名字冲突。
在声明一个命名空间时花括号内不仅可以可以包含变量,还可以包含一下类型:
- 变量(可以初始化)
- 常量
- 函数(可以是定义也可以是声明)
- 结构体
- 类
- 模板
- 命名空间(命名空间的嵌套)
namespace xiasicheng
{//命名空间成员const int a = 10;namespace xiasicheng2{int b = 0;}
}
需要注意的是,命名空间不会改变变量的生命周期,本来是全局变量,定义在命名空间中还是全局变量。
1.3命名空间的使用
1.3.1指定命名空间访问
当我们需要使用命名空间中的成员时,要用命名空间名和作用于限定符对命名空间成员进行限定,以区别不同的命名空间中可能有同名的标识符:即
//命名空间名::命名空间中的成员名
cout << xiasicheng::a << endl;
但是当命名空间名字比较长,并且还要多次引用其成员时,就会非常不方便。
为此,C++提供了一些机制,能简化使用命名空间中成员的方法
1.3.2使用命名空间的别名
可以为命名空间起一个别名,用来代替较长的命名空间名。
如:
namespace Television
{int a = 0;
}namespace TV = Television;//用TV代替Televisionint main()
{cout << Television::a << endl;cout << TV::a << endl;return 0;
}
1.3.3使用using将命名空间中某个成员展开
using后面的成员名必须是由命名空间名限定的名字。例如:
using TV::a;
它表示在using语句所作用的作用域中可以用TV命名空间中的成员a,而且不必再逐个用命名空间名限定了。当我们要再使用变量a时,直接调用即可:
cout << a << endl;//相当于cout << TV::a << endl;
但是要注意,在同一作用域中用using声明的不同命名空间的成员不能有同名的成员。
1.3.4使用using namespace展开命名空间
C++提供了using namespace 语句来实现一次性展开命名空间,一般格式为:
using namespace 命名空间名;
当我们利用该语句展开某个命名空间之后,该命名空间中的所有成员都可以直接进行访问,不必再使用作用于限定符限定或者using语句声明某一个成员。
当是在使用using namespace 和using展开某一个成员时,都存在风险,所以在项目中时,建议使用命名空间名+作用于限定符的方式来访问变量。
二.C++的输入输出
C++有一套自己的输入输出方式,我们可以使用cout来实现输出,cin实现输入。它们是C++的标准输出流和输入流。
int a = 0;
cin >> a;
cout << a << endl;
因为C++是包含C的,所以在我们的C++程序中,也可以使用C语言的输入输出方式,但是C++的输入输出有一个很好的东西,那就是可以自定识别类型。我们不再像C语言那样要进行格式控制,我们C++直接写入变量名即可,不必控制变量的类型,cout和cin会自动识别的。
int main()
{int a = 0;cin >> a;scanf("%d", &a);cout << a << endl;printf("%d\n", a);return 0;
}
其实cout和cin也是包含在std这个命名空间中的,因为我们再文件开头就展开了std,所以我们不再需要进行限定,所以cout和cin的使用可以借助std和作用域限定符:
std::cin >> a;
std::cout << a << endl;
三.缺省参数
缺省参数也叫做有默认参数的函数,所以缺省参数是应用在函数模块中的。其含义就是在定义函数时,给形参一个默认值,当我们调用该函数时,如果没有传实参,该函数就会使用这个默认值,如果传了实参,该函数就会使用该实参而屏蔽掉缺省参数。
int MAX(int a = 0, int b = 0)
{return a > b ? a : b;
}
当一个函数有多个形参时,其可以分为全缺省,半缺省,不缺省:
全缺省就是其形参每一个都带有默认值,传参数时,可以只传一个,也可以传多个,传了就用实参,没传的就用缺省值。
半缺省就是只有一部分形参有缺省值,当一个函数是半缺省时,其带有缺省值的形参必须在形参表列的最右边。
int func(int a, int b, int c = 0, int d = 0)
{cout << a << " " << b << " " << c << " " << d << endl;
}
如果缺省值跳跃,在传参时就会产生歧义:
int func(int a = 1, int b, int c = 0, int d = 0)
{cout << a << " " << b << " " << c << " " << d << endl;
}int main()
{func(2);return 0;
}
此时,2是传给a呢?还是b呢?所以为了避免该情况的出现,带缺省值的形参应在形参表列的最右边。
四.变量的引用
引用(reference)是C++对C的一个重要扩充
4.1引用的概念
在C++中,变量的“引用”就是变量的别名,因此引用又叫别名(alias)。建立“引用”的作用是为一个变量再起另一个名字,以便在需要时可以方便、间接地引用该变量,这就是引用名称的由来。当我们给一个变量起了一个别名之后,他们两个占用同一块空间。
int a = 10;
int& b = a;//给a取了一个别名b,a和b占用同一块内存空间
注意:在声明一个别名时,必须同时给出初始化。
我们打印a和b的地址可以看到它们的地址相同。 当我们修改其中任意一方时,另一方也会发生改变。
4.2引用的特性
4.2.1引用在定义时必须初始化且引用的类型必须和被引用对象的类型相同
int main()
{int a = 0;int& b = a;//正确int& c;//没有初始化double& d = a;//引用类型与被引用类型不同return 0;
}
4.2.2一个变量可以有多个引用
int a = 0;
int& b = a;
int& c = a;
int& d = a;
当我们打印它们的地址时,它们都指向的是同一块空间:
4.2.3引用在初始化后不能再被重新声明为另一个变量的别名
int main()
{int a = 0;int& b = a;//b是a的别名int c = 10;&b = c;//企图让b成为c的别名,错误return 0;
}
4.2.4对于引用的初始化,可以用一个变量名,也可以用另一个引用
int main()
{int a = 10;int& b = a;int& c = a;//用变量初始化int& d = b;//用另一个引用初始化return 0;
}
4.3引用作为函数参数
用引用作为函数参数时,可以代替传地址的方式使实参改变,当函数形参为引用时,实参直接传变量也会改变。
void Swap(int& a, int& b)
{int tmp = a;a = b;b = tmp;
}
void Swap(int* a, int* b)
{int tmp = *a;*a = *b;*b = tmp;
}
我们可以对比引用传参和指针传参的区别,引用传参会更加方便,如果使用指针的话还要对变量进行解引用。
4.4const引用
const引用可以作为普通变量的别名,也可以作为const变量的别名。前者属于权限缩小,或者属于权限平移。
int a = 0;
const int& b = a;
此时b不可以改变,但是a可以改变。 此时属于权限缩小,原来a可写可读,b只能读不能写。
const int c = 100;
const int& d = c;
此时c和d都不能改变。此时属于权限平移,原来c只可读不可写,d也只能读不能写。
需要注意的是,权限只能平移或者缩小,但不能放大。
const int e = -1;
int& f = e;
e只可读,但f作为e的引用可读可写,此时权限放大,运行会出错。
4.5const引用中的常属性临时变量
double a = 1.2;
int& b = a;
a是浮点型,而想给其取一个int型的别名。此时会发生隐式转化,a会隐式转化为整型储存在临时变量中,而临时变量具有常属性,只可读,但是给其取别名时发生了权限放大,所以上面的写法是错误的。
正确的方法是用const引用接收:
double c = 2.2;
const int& d = c;
4.6引用和指针的关系
C++中引用是引用,指针是指针,两者相辅相成。
- 语法概念上引⽤是⼀个变量的取别名不开空间,指针是存储⼀个变量地址,要开空间。
- 引⽤在定义时必须初始化,指针建议初始化,但是语法上不是必须的。
- 引⽤在初始化时引⽤⼀个对象后,就不能再引⽤其他对象;⽽指针可以在不断地改变指向对象。
- 引⽤可以直接访问指向对象,指针需要解引⽤才是访问指向对象。
- sizeof中含义不同,引⽤结果为引⽤类型的⼤⼩,但指针始终是地址空间所占字节个数(32位平台下 占4个字节,64位下是8byte)。
- 指针很容易出现空指针和野指针的问题,引⽤很少出现,引⽤使⽤起来相对更安全⼀些。
五.重载函数
C++中的输入输出语句中用到的<<和>>叫做流插入操作符和流提取操作符。而在C语言中,它们作为位运算符,这叫做运算符重载,即一物多用。
而重载函数也叫函数重载,也就是一物多用的意思,同名函数有着不同的作用。
C++允许在同一作用域中用同一函数名定义多个函数,这些函数的参数个数和参数类型不相同,用来实现不同的功能。这就是函数重载,即一个函数名多用
int ADD(int x, int y)
{return x + y;
}double ADD(double x, double y)
{return x + y;
}
对上面两个函数而言,实现了整数相加和浮点数相加的功能,当我们调用ADD函数时,该函数会根据参数的不同,调用不同的函数。这就是函数重载的体现。
但是函数重载的前提是:函数的形参表列不同
- 形参个数不同
- 形参类型不同
- 形参个数和类型都不同
- 形参顺序不同
需要注意的是,函数重载跟返回值类型无关,返回值不同,形参相同的两个函数不能设计为重载函数。
六.inline
inlne是C++的一个关键字,它可以使一个函数成为内联函数。
调用函数时需要建立函数栈帧,这需要时间,当一个函数被频繁调用时,就会加大时间的消耗,导致程序效率降低。C++提供了一种提高效率的方法,即在编译时将所调用函数的代码嵌入到主调函数中。这种嵌入到主调函数中的函数称为内联函数,又称内置函数。
inline int ADD(int x, int y)
{return x + y;
}
当我们调用该函数时,其就会在调用出展开:
int main()
{ADD(1, 2);return 0;
}
//展开
int main()
{return 1 + 2;return 0;
}
其实,inline的出现是为了替代C语言中的宏。因为宏是一种文本替换不进行类型检查,不安全。所以C++就引入了inline这一关键字。
但是函数是否展开是跟编译器有关的。当你将一个函数定义为inline时,编译器会检查你设置的是否合理,如果合理,编译器就会在调用出展开;否则,就不展开。
将一个函数定为内联函数的前提是,该函数代码量少(10行之内),且会被频繁调用。
七.nullptr
nullptr是C++11引入的一个空指针常量。在C++中,空指针通常用NULL或0来表示,但这种表示方式可能存在一些模糊性和歧义。为了解决这个问题,C++11引入了nullptr作为一个明确的空指针常量。
nullptr可以被赋值给指针类型的变量,表示该指针不指向任何有效的内存地址。使用nullptr可以提高代码的可读性和安全性,因为它可以更清晰地表示一个空指针。另外,nullptr还可以与其他指针进行比较操作,以判断指针是否为空。
示例代码:
int* ptr = nullptr; // 定义一个指向整型的空指针if (ptr == nullptr) {// 检查指针是否为空// 执行相关操作
}
总的来说,nullptr是C++中用于表示空指针的常量,它在C++11中被引入,提高了代码的可读性和安全性。
完!
相关文章:

C到C++——C++基础
C是一种通用的、静态类型的、跨平台的编程语言。它是在1979年由Bjarne Stroustrup创建的,最初是作为C语言的扩展来支持面向对象编程。 C在保留C语言的特性的同时,添加了许多其他的功能,包括类、对象、继承、多态、模板等。这使得C成为了一种…...

trie算法
1、定义 高效的存储和查找字符串集合的数据结构 它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高 2、构建 我们可以使用数组来模拟实现Trie树。 我们设计一个二维数组 son[N] [26] 来…...
Kubernetes之pod的基本概念
目录 什么是pod 启动一个pod 说明 Pod 和控制器 Pod 模板 Pod 更新与替换 资源共享和通信 Pod 中的存储 Pod 联网 Pod 安全设置 什么是pod Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。 Pod(就像豌豆荚中)是一组&#…...

PostgreSQL的学习心得和知识总结(一百五十)|[performance]更好地处理冗余 IS [NOT] NULL 限定符
目录结构 注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下: 1、参考书籍:《PostgreSQL数据库内核分析》 2、参考书籍:《数据库事务处理的艺术:事务管理与并发控制》 3、PostgreSQL数据库仓库…...

sqllabs游戏
文章目录 总体思路:less-1:less-2:less-3:less-4:less-5:less-6:less-7:less-8:布尔盲注less-9:时间盲注less-21:less-24: 总体思路: 1、第一件事情 逃脱出单引号的控制 闭合单引号 2、单双引号需要成对出现 在python php Java中 3、2个办法 继续把多出…...
React Native Firebase:移动应用后端集成
React Native Firebase 是一个强大的库,它允许你在 React Native 应用中集成 Firebase 后端服务。Firebase 提供了一系列的服务,包括实时数据库、身份验证、云存储、云消息推送等,这些服务可以帮助你构建功能丰富、可扩展的移动应用。 安装和…...
趣味算法------开灯问题
题目描述 有 n 盏灯,编号为 1~n,第 1 个人把所有灯打开,第 2 个人按下所有编号为 2 的倍数的开关(这些灯将被关掉),第 3 个人按下所有编号为 3 的倍数的开关(其中关掉的灯将被打开,…...
如何长生?重要的是对内求索!
文章目录 1. 世界上没有仙丹2. 长生只能对内求索 1. 世界上没有仙丹 小说中的九转大还丹,修仙中的仙丹,蟠桃是不存在的。这是理所当然的废话。但是世界上总有很多广告词,用老山参、野生、纯天然,补肾、补肝等词来形容自己的产品&…...
SD-WAN解决方案
联通国际公司企业SD-WAN解决方案 产品介绍 随着数字化转型的加速推进,企业对网络连接的需求也在不断提高。联通国际公司推出的SD-WAN(Software-Defined Wide Area Network,软件定义广域网)解决方案,旨在为企业提供更…...
什么是C++的引用,请举例说明
C中的引用(Reference)是C语言的一个特性,它允许一个变量(称为引用变量)成为另一个变量(被引用的变量)的别名。这意味着,对引用变量的任何操作都会直接反映在被引用的变量上ÿ…...
大数据_SQL_5min访问达到100次的用户
某公司网站每日访问量达到10亿级别的访问量, 每次访问记录一条数据,数据包含如下字段:用户ID,访问时间(毫秒级),访问页面。 要求使用hive求出所有在5分钟内访问次数达到100次的用户(…...

Python PDF文本处理技巧 - 查找和高亮文字
目录 使用工具 Python在PDF中查找和高亮文字并统计出现次数和页码 Python在PDF的特定页面区域中查找和高亮文字 Python使用正则表达式在PDF中查找和高亮文字 Python在PDF中查找文字并获取它的坐标位置 其他查找条件设置 在日常工作和学习中,我们常常需要处理各…...

虚幻引擎 C++ 实现平面阴影
1、平面阴影介绍 平面阴影是一种相对简单的渲染阴影的方式,可以理解为对一个模型渲染两次,一次是渲染模型本身,另一次是渲染模型的投影。渲染投影可以看作是将模型的顶点变换到地面的投影空间再渲染,可以理解为渲染了一个“压扁”…...
leetcode 67. 二进制求和
二进制求和 已解答 简单 相关标签 相关企业 给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。 示例 1: 输入:a “11”, b “1” 输出:“100” 示例 2: 输入:a “1010”, b “1011” 输出&…...
【C++ 面试 - 基础题】每日 3 题(一)
✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/fYaBd 📚专栏简介:在这个专栏中,我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏&…...

【动态规划】1、不同路径II+2、三角形最小路径和
1、不同路径II(难度中等) 该题对应力扣网址 AC代码 只会写简单的if-else class Solution { public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {//1、定义子问题//2、子问题递推关系//3、确定dp数组的计算顺序…...

JavaEE-多线程编程单例模式
一、等待通知 系统内部,线程之间是抢占式执行的,随即调度,程序可以通过手动干预的方式,能够让线程一定程度的按咱们想要的顺序执行,无法主动让某个线程被调度,但可以主动让某个线程等待。等待通知可以安排…...

RHCA III之路---EX436-6
RHCA III之路---EX436-6 1. 题目2. 解题3. 确认 1. 题目 2. 解题 三台node分别运行 yum install -y device-mapper-multipath mpathconf --enable systemctl enable --now multipathd3. 确认 fdisk -l...

Vuex模块化 深入浅出超详细
Vuex 模块化 为什么需要模块化? 随着项目规模的增长,单一的 store 文件会变得庞大且难以管理; Vuex 的模块化是一种组织和管理应用状态的策略:,它允许将全局的状态管理分解成更小、更可管理的部分; 逻辑清…...
细说MCU检测按键输入的外部中断和修改HAL_GPIO_EXTI_IRQHandler() 的实现方法
目录 一、 硬件板及设计目的 二、建立工程 1.配置GPIO 2.配置时钟源和Debug 3.配置系统时钟 4.配置NVIC 三、代码编写 四、修改HAL_GPIO_EXTI_IRQHandler() 一、 硬件板及设计目的 本文使用的硬件板是ST的开发板NUCLEO-G474RE,板上MCU型号为ST…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...

《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...