[C++初阶] :从C到C++

目录

  • C++发展史,C++语言的特性
  • C++新增关键字
    • namespace关键字
      • C语言的命名缺陷(重定义现象)
      • 域与指定访问操作符 “::”
      • 命名空间域详解
      • namespace std
  • C++的输入与输出
  • 函数重载
    • 什么是重载,重载的几种常见形态
    • 重载的作用
    • 注意不构成重载的情况
  • 缺省参数
    • 1.全缺省
    • 2.半缺省
    • 注意事项
  • auto关键字
    • auto关键字的注意事项
  • 引用
    • 什么是引用
    • 引用应用场景和作用
      • 函数传值调用的本质(重要)
      • 返回引用虽好,切忌不可滥用
    • 引用和“权限const”的关系
    • 引用和指针的区别(重要)
      • 引用 VS 指针(初始化与绑定)
      • 引用 VS 指针(多级间接访问)
      • 引用 VS 指针(传参)
      • 引用 VS 指针(安全性)
  • C++语法糖:基于范围的for循环
  • C++的空指针nullptr
    • C语言null指针的局限

C++发展史,C++语言的特性

C++由丹麦计算机科学家Bjarne Stroustrup在贝尔实验室工作时开发。
Stroustrup最初的目标是为系统级编程和嵌入式系统创建一种改进的C语言版本,以支持更高效的代码组织方式。他最初称之为“带类的C”(“C with Classes”),它引入了面向对象编程的概念,如类、继承、封装。

1985年:发布了第一个商业版本,迅速获得了认可,并开始被广泛应用于各种领域
1990年:发布了带有标准模板库(STL)的版本,进一步增强了其功能性和灵活性,STL是C++的核心之一,不会STL库是不敢说自己会C++的
后续会详细介绍STL库
1998年:ISO/IEC 14882:1998标准发布,标志着C++成为了一种国际标准语言。这被称为C++98(C++98是C++非常重要的版本)
2011年:C++11发布,带来了许多重要的新特性,如自动类型推导(auto)、lambda表达式智能指针等,极大提升了语言的现代性和易用性(C++11对C++语言的发展来说极其重要,它标志着C++的一次重大进化,后续会详细介绍C++11引入的新特性)

语言特性 1 :对硬件的精密操控 :
C++允许对硬件进行精细控制,包括内存管理和直接访问硬件资源,使得它非常适合需要高效率的应用场景,如操作系统、游戏引擎、嵌入式系统

语言特性 2:多范式编程
C++支持多种编程范式,包括过程化编程、面向对象编程(OOP)、泛型编程和函数式编程。这种灵活性使开发者可以根据具体需求选择最合适的编程方式。

语音特性3 :兼容C语言
C++被设计为与C语言高度兼容,允许C++代码调用C库,并且可以直接包含C头文件。这使得从C迁移到C++变得相对容易。

C++还支持并发,零抽象开销等特性…,现在就让我们正式进入C++吧

在这里插入图片描述

C++新增关键字

在这里插入图片描述

class 定义类支持面向对象编程
new 动态分配内存并调用构造函数
delete 释放动态分配的内存并调用析构函数
public 定义类的公有成员
private 定义类的私有成员
protected 定义类的受保护成员
this 指向当前对象的指针
virtual 声明虚函数,支持多态
override 显式声明重写基类的虚函数(C++11 引入)
final 禁止派生类重写虚函数或禁止类被继承(C++11 引入)
friend 声明友元函数或类,允许访问私有成员
template 定义模板,支持泛型编程
typename 在模板中声明类型参数或指示依赖类型
namespace 定义命名空间,避免命名冲突
using 引入命名空间成员或定义类型别名
bool 布尔类型(true 或 false)
true 布尔值真
false 布尔值假
nullptr 表示空指针(C++11 引入)
constexpr 声明常量表达式(C++11 引入)
auto 自动类型推导(C++11 引入)
(这些关键字非常重要,后续文章这些关键字都会介绍)

namespace关键字

C语言的命名缺陷(重定义现象)

#include<stdio.h>int rand = 0;
int main()
{printf("%d\n", rand);return 0;
}

当我们包含stdlib头文件的时候上述代码片就会有重定义的错误

在这里插入图片描述

在几百万行甚至几千万行的工程中,我们一定会遇到大量的重定义行为
由此工程师们引入了关键字namespase支持“重定义”行为

域与指定访问操作符 “::”

一般的我们把域分为三类,命名空间,全局,局部
使用 : : 操作符就可以访问全局域的x
在这里插入图片描述

命名空间域详解

命名空间域在全局作用域中有自己的独立的区域
使用namespace定义命名空间
下图可见text和text2互不干扰,相互独立
在这里插入图片描述

那么我们该怎么访问命名空间域里面的成员呢
当然就是通过上述的域指定访问操作符 ::

在这里插入图片描述

还有一种方式是直接展开整个命名空间
在这里插入图片描述
注意了,滥用using展开整个命名空间会导致重定义,目标不明确的现象
滥用using导致x不明确
在这里插入图片描述

namespace std

std命名空间是C++标准库使用的命名空间。它包含了所有标准库的组件,这些标准库的
组件分部在各种头文件中
如容器(vector, list, map等)、算法(sort, find等)、流(iostream, fstream等)
使用std命名空间同样有两种方法:

  1. using namespace std;
  2. 使用 :: ,如 std::cout << “hello world” << std::endl; 指定访问std命名空间
    在平常做小型实验或小型demo中,我们为图方便可以使用using展开std
    在中大型工程中,为了避免与std的成员命名冲突,绝对不能直接using展开std

C++的输入与输出

C++的输入流cout
通常用于将数据输出到控制台,它与插入运算符 << 结合使用,可以输出各种类型的数据,如字符串、数字等。
有了 cout 输出的知识,我们可以写出第一个C++程序 “hello world”了
在这里插入图片描述

C++的输出流 cin
通常用于从控制台读取数据。它与提取运算符 >> 结合使用,可以从用户那里获取输入,并将其存储到变量中。
他们都被定义在 std 命名空间中

在这里插入图片描述

函数重载

什么是重载,重载的几种常见形态

生活中的函数重载:
微波炉通常有多种加热模式,可以根据你放进去的食物类型和数量,自动调整加热时间和功率,而不是A微波炉只能加热5min,B微薄炉只能加入10min… 这就是一种“函数重载”的体现。

函数重载: 是函数的一种特殊情况,
C++ 允许在 同一作用域中 声明几个功能类似 的同名函数 ,这些同名函数的 形参列表 ( 参数个数 或 类型 或 类型顺序 ) 不同 ,常用来处理实现功能类似数据类型不同的问题。
注意:对返回值没有任何要求。
如果函数名、参数个数、类型、类型顺序均相同,但返回值不同,并不构成重载,而是直接报错

//参数类型不同的函数重载
//整数相加
int add(int a, int b) {std::cout << "add two integer: ";return a + b;
}// 处理两个浮点数相加
double add(double a, double b) {std::cout << "add two double: ";return a + b;
}
//参数顺序不同的函数重载
// 处理浮点数和整数相加
double add(int a, double b) {std::cout << "add a integer and a double: ";return a + b;
}// 调换顺序
double add(double a, int b) {std::cout << "add a double and a integer: ";return a + b;
}
//参数个数的缺省
int add(int a, int b) {std::cout << "add two integer: ";return a + b;
}// 处理两个浮点数相加
int add(int a) {std::cout << "a integer";return a;
}

重载的作用

函数重载的语法支持,让我们不用对仅参数不相同要执行的逻辑相同的,避免为每种不同的输入类型或参数组合创建新的函数名称。这使得代码更加简洁,并且更容易理解和维护。

注意不构成重载的情况

//不构成函数重载的情况
double add(int a, double b) {std::cout << "add a integer and a double: ";return a + b;
}// 调换顺序
double add(int c, double b) {std::cout << "add a double and a integer: ";return a + b;
}
//上述代码片的参数类型和顺序都是一样的,只不过参数换了一个名字而已
//故不构成函数重载

缺省参数

生活上的缺省参数
用户可以选择商品的基本信息(如商品名称),也可以选择额外的属性(如颜色、尺寸等)。如果没有特别指定,系统会提供默认值。

  1. 购买一件T恤(默认颜色和尺码)
    (这就是缺省的体现)
  2. 购买一件红色L号的T恤(指定颜色和尺码)

1.全缺省

顾名思义,全缺省就是对所有形式参数带上默认值
1.什么参数都不传,默认使用的就是缺省值
在这里插入图片描述>传入了参数就不使用缺省值了在这里插入图片描述

2.半缺省

半缺省就是给部分参数设置缺省值
在这里插入图片描述

注意事项

1.半缺省的顺序必须从右往左:
是传参是从左到右的,若从左到右设置缺省,实际参数任然要传入N个的参数
如图,我们必须先给 a 传参,后给b传参,a的缺省值形同虚设就没有了意义

在这里插入图片描述
2.当缺省参数遇上函数重载
如图,两个add函数构成参数个数类型的函数重载
但是由于第一个add参数a缺省导致第185行调用add()函数二义性
编辑器不确定到底是调第一个add还是第二个add故报错
在这里插入图片描述

auto关键字

auto关键字是C++11新引入的特性,具有自动推到类型的作用

auto i = 42;           // i 是 int 类型
auto d = 3.14;         // d 是 double 类型
auto s = "Hello";      // s 是 const char* 类型
auto str = std::string("Hello"); // str 是 std::string 类型

当变量的类型非常复杂或冗长时,使用 auto 可以显著简化代码。例如,使用迭代器时:
(未来的文章会详细介绍迭代器,现在你只要知道迭代器类似于指针,它的类型非常冗长)

std::vector<int> vec = {1, 2, 3, 4, 5};
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {std::cout << *it << " ";
}

使用auto自动推到迭代器类型后

for (auto it = vec.begin(); it != vec.end(); ++it) {std::cout << *it << " ";
}

auto关键字的注意事项

初始化时不能仅声明

auto x;  // 错误:缺少初始化表达式

数组类型的推导涉及到多个维度和元素类型,使得推导过程变得复杂。
不能直接用auto 定义数组

auto arr[] = {1, 2, 3};  // 错误不能直接用auto定义数组

引用

什么是引用

引用本质上是给一个对象起了一个“外号”,
在我国四大名著《水浒传》中
说到及时雨我们会想到宋江
说到黑旋风我们会想到李逵
宋江和及时雨是一个人,李逵和黑旋风是一个人
引用也是如此,被引用的对象和引用对象是一个对象不会开额外的空间
如图,a和b的地址相同
在这里插入图片描述
修改a,b也修改了
在这里插入图片描述

引用应用场景和作用

1. 作为形式参数传参,减少拷贝构造:

函数传值调用的本质(重要)

传值调用会先生成实参的临时拷贝对象,然后把临时拷贝对象赋值给形式参数
在这里插入图片描述

由此可见,若是传值非常大的结构体对象,中间拷贝形成临时对象代价非常大
传引用则不需要形成临时拷贝对象然后赋值,大大提高了效率
在这里插入图片描述
整个过程中 a,b指向同一块地址,改变a会改变b

  1. 作为返回值返回,减少拷贝构造
    和传值调用一样,传值返回会先生成一个临时的对象,然后把临时拷贝对象赋值给接受者
    在这里插入图片描述
    若返回引用则不需要创建临时对象
    在这里插入图片描述

返回引用虽好,切忌不可滥用

看了返回引用的好处之后,千万不要觉得返回引用就是比返回值更好:

切记不可返回栈空间临时对象引用
栈空间用于存储函数的局部变量。
当函数执行结束时,栈帧会被销毁,局部变量的内存会被释放。
返回栈空间的引用后,引用指向的内存已经无效

int& getLocalReference() {int localVar = 42;  // 局部变量,存储在栈空间return localVar;    // 错误:返回局部变量的引用
}int main() {int& ref = getLocalReference();  // 获取局部变量的引用std::cout << ref << std::endl;   // 未定义行为:访问已释放的栈空间return 0;
}

引用和“权限const”的关系

口诀,大权限(可读可改)“为所欲为”,小权限(只读不改)“唯唯诺诺”
const是小权限,引用过去后还想变成大权限?,当然不行
在这里插入图片描述
只能const变const
在这里插入图片描述

大权限,引用过去后想变成小权限?,当然可以

在这里插入图片描述
在这里插入图片描述

引用和指针的区别(重要)

引用 VS 指针(初始化与绑定)

指针:
指针是一个变量,用来存储地址
大小为4字节或8字节(取决于32位机器或64位机器)
指针可以初始化为空,后续可以指向其他对象
int a = 10;

int* ptr = &a;  // ptr 指向 a 的地址
ptr = nullptr;  // ptr 可以指向空//重新绑定
int a = 10, b = 20;
int* ptr = &a;  // ptr 指向 a
ptr = &b;      // ptr 现在指向 b

引用:
引用是一个变量的别名,用来绑定其他对象
不需要额外空间
引用必须初始化绑定一个对象,并且后续不可以换绑

// int& ref;  // 错误:引用必须初始化
int a = 10;
int& ref = a;  // 正确//重新绑定
int a = 10, b = 20;
int& ref = a;  // ref 绑定到 a
// ref = b;    // 错误:引用不能重新绑定

引用 VS 指针(多级间接访问)

只有指针的指针(二级指针),没有引用的引用
指针支持多级访问,引用不支持多级访问

int a = 10;
int* ptr = &a;
int** ptr2 = &ptr;  // 指针的指针int a = 10;
int& ref = a;
// int&& ref2 = ref;  // 错误:没有引用的引用

引用 VS 指针(传参)

指针作为参数,传的是地址的拷贝
因此可以通过同一指向地址改变原始内容(要改变指针本身的值要传二级指针)
而引用直接传的是对象的别名
在这里插入图片描述

//传的是地址的拷贝
oid func(int* ptr) {*ptr = 20;
}
int a = 10;
func(&a);  // a 的值被修改为 20//传的是地址的拷贝
void func(int& ref) {ref = 20;
}
int a = 10;
func(a);  // a 的值被修改为 20

引用 VS 指针(安全性)

引用必须初始化绑定一个对象,而且其未来不能换绑。故引用的安全性比指针高

int* ptr = nullptr;
*ptr = 10;  // 未定义行为:空指针解引用int a = 10;
int& ref = a;  // 安全

C++语法糖:基于范围的for循环

基于范围的for循环,在这个例子中element是一个局部变量,迭代时它会依次的被赋值为
容器的一个元素
在这里插入图片描述
这下我们学的auto关键字就派上用场了
在这里插入图片描述

上述例子中,element都是被容器元素赋值的对象,并不是元素本身,想要在迭代的过程中改变容器元素的值,那就要传引用(也就是传别名)
例,不传引用无法改变容器的值
在这里插入图片描述

C++的空指针nullptr

C语言null指针的局限

null常被定义为 整数 0 或零的空指针类型 (void*)0

在这里插入图片描述

null被解释成0,又能被解释成 零的空指针是非常不合理的
NULL被定义为 0 ,调用了func(int)
在这里插入图片描述

二义性:
NULL又可以初始化空指针,又可以被解析为0
在这里插入图片描述

为了解决上述NULL所带来的困扰,科学家们在C++11引入了新关键字nullptr
nullptr只能解释为指针,空指针可以隐式类型转化任意指针类型
在这里插入图片描述

今天的你又一点进步了哟,明天继续加油

在这里插入图片描述

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

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

相关文章

[快乐学坊management_1] With Cursor | Mysql设计 | 服务接口设计与开发

目录 数据库设计流程 三张表 测试 接口设计 部门管理接口文档 1. 查询所有部门 2. 新增部门 ⭕3. 根据ID查询部门 4. 修改部门 5. 删除部门 &#xff08;部门分页条件查询&#xff09; 错误响应示例 接口设计规范 服务端开发 接口开发 数据库设计流程 01 明确业…

实用插件推荐 -------- 一个可以将任意语言(python、C/C++、go、java等)的程序转换为汇编语言的小插件

链接为&#xff1a; Compiler Explorer 界面&#xff1a; 参考自&#xff1a;如何获取虚函数表及内存分析_com的虚函数表怎么寻找-CSDN博客

vue学习八

十七 组件通信方式 1 props 父传子 //父组件 <script setup>//book来源省略import Subview1 from ./Subview1.vue;function updatebook(updatetimes){book.value.updatetimes updatetimes} </script> <template><Subview1 :book"book" :upd…

51单片机的寻址方式(完整)

目录 一、立即数寻址 二、直接寻址 三、寄存器寻址 四、寄存器间接寻址 五、变址寻址 六、位寻址 七、指令寻址 &#xff08;一&#xff09;绝对寻址 &#xff08;二&#xff09;相对寻址 在 51 单片机中&#xff0c;寻址方式是指在执行指令时&#xff0c;CPU 寻找操作…

每日一题:动态规划

如题&#xff08;基础题&#xff09;&#xff1a; 经典的爬楼梯问题&#xff0c;先从递归想起&#xff1b; class Solution { public:int climbStairs(int n) {if(n1)return 1;if(n2)return 2;return climbStairs(n-1)climbStairs(n-2);} }; 之后可以想办法&#xff08;如哈希…

【论文阅读】FairCLIP - 医疗视觉语言学习中的公平性提升

FairCLIP - 医疗视觉语言学习中的公平性提升 1.研究背景与动机2.核心贡献3.方法论细节4.实验结果与洞见5.总结 FairCLIP: Harnessing Fairness in Vision-Language Learning FairCLIP - 医疗视觉语言学习中的公平性提升 Accepted by CVPR2024 github:链接 1.研究背景与动机…

Linux 入门:权限的认识和学习

目录 一.shell命令以及运行原理 二.Linux权限的概念 1.Linux下两种用户 cannot open directory .: Permission denied 问题 2.Linux权限管理 1).是什么 2).为什么&#xff08;权限角色目标权限属性&#xff09; 3).文件访问者的分类&#xff08;角色&#xff09; 4).文…

大语言模型的压缩技术

尽管人们对越来越大的语言模型一直很感兴趣&#xff0c;但MistralAI 向我们表明&#xff0c;规模只是相对而言的&#xff0c;而对边缘计算日益增长的兴趣促使我们使用小型语言获得不错的结果。压缩技术提供了一种替代方法。在本文中&#xff0c;我将解释这些技术&#xff0c;并…

Java高频面试之集合-14

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本baby今天来报道了&#xff01;哈哈哈哈哈嗝&#x1f436; 面试官&#xff1a;为什么 HashMap 的容量是 2 的倍数呢&#xff1f; HashMap的容量被设计为2的幂次&#xff0c;主要基于以下原因&#xff…

TreelabPLMSCM数字化供应链解决方案0608(61页PPT)(文末有下载方式)

详细资料请看本解读文章的最后内容。 资料解读&#xff1a;TreelabPLMSCM 数字化供应链解决方案 0608 在当今快速变化的市场环境中&#xff0c;企业面临着诸多挑战&#xff0c;Treelab 数智化 PLM_SCM 行业解决方案应运而生。该方案聚焦市场趋势与行业现状&#xff0c;致力于解…

Docker搭建MySQL主从服务器

一、在主机上创建MySQL配置文件——my.cnf master服务器配置文件路径&#xff1a;/data/docker/containers/mysql-cluster-master/conf.d/my.cnf slave服务器配置文件路径&#xff1a; /data/docker/containers/mysql-cluster-master/conf.d/my.cnf master服务配置文件内容 …

JS逆向案例-HIKVISION-视频监控的前端密码加密分析

免责声明 本文仅为技术研究与渗透测试思路分享,旨在帮助安全从业人员更好地理解相关技术原理和防御措施。任何个人或组织不得利用本文内容从事非法活动或攻击他人系统。 如果任何人因违反法律法规或不当使用本文内容而导致任何法律后果,本文作者概不负责。 请务必遵守法律…

SENT接口

文章目录 前言SENT接口简介物理层数据链路层编码方式帧结构消息格式短串行消息格式增强型串行消息格式 CRC校验和CRC4CRC6 错误检测机制 IP 设计结构框图接口设计上板验证 前言 本文参考标准《SAE J2716_201604》。 SENT接口 简介 SENT&#xff08;Single Edge Nibble Tran…

Qt-搭建开发环境

1.环境搭建 开发工具概述&#xff1a; Qt ⽀持多种开发⼯具&#xff0c;其中⽐较常⽤的开发⼯具有&#xff1a;Qt Creator、Visual Studio、Eclipse. 1.1Qt Creator Qt Creator 是⼀个轻量级的跨平台集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为使⽤ Qt 框架进…

Odoo18 Http鉴权+调用后端接口

最近在调研Odoo18&#xff0c;包括它的前后端原理、源码等。发现官方的开发文档并不十分实用&#xff0c;比如标题这种简单的实用需求&#xff0c;竟然浪费了一点时间&#xff0c;特此记录。 官方文档&#xff1a;External API — Odoo 18.0 documentation 前提&#xff1a;首…

【第13节】windows sdk编程:GDI编程

目录 一、GDI 概述 二、设备环境概念 三、使用 GDI 绘图对象 四、使用 GDI 坐标系统 五、使用GDI绘图 5.1 输出文字 5.2 画点和线 5.3 画矩形框、圆和多边形 5.4 画位图和图标 5.5 双缓冲技术 六、综合代码示例 一、GDI 概述 Windows 应用程序不支持标准输出函数&am…

离开页面取消请求

前言 上一篇文章我们处理了axios的重复请求问题axios重复请求&#xff0c;今天来说一下如何在离开某个页面的时候将正在发送的请求取消掉 开始 基于上一篇的axios封装&#xff0c;当我们在编写某个页面的请求的时候 import request from /request/index;export const test2…

C++输入输出流第一弹:标准输入输出流 详解(带测试代码)

目录 C输入输出流 流的四种状态&#xff08;重点&#xff09; 标准输入输出流 标准输入流 逗号表达式 1. 逗号表达式的基本规则 示例 2. 图片中的代码分析 关键点解析 3. 常见误区 误区 1&#xff1a;逗号表达式等同于逻辑与 && 误区 2&#xff1a;忽略输入…

Z 轴热膨胀系数:PCB 可靠性的关键因素与选材策略

在电子设备小型化与高性能化的趋势下&#xff0c;PCB&#xff08;印刷电路板&#xff09;的可靠性成为决定产品寿命的核心因素。其中&#xff0c;Z 轴热膨胀系数&#xff08;α2/z-CTE&#xff09;作为板材的关键参数&#xff0c;直接影响多层板的层间结合力、焊点稳定性及整体…

【C++】Virtual function and Polymorphism

《C程序设计基础教程》——刘厚泉&#xff0c;李政伟&#xff0c;二零一三年九月版&#xff0c;学习笔记 文章目录 1、多态性的概念2、虚函数的定义2.1、引入虚函数的原因2.2、虚函数的定义与使用2.3、虚函数的限制 3、抽象类3.1、纯虚函数3.2、抽象类 4、应用实例 更多有趣的代…