【C++进阶】01:概述

news2025/6/21 1:14:19

概述


OVERVIEW

  • 概述
      • C++11新特性:
      • C++14新特性:
      • C++17新特性:
      • C++20新特性:
      • C++程序编译过程
      • C++内存模型
      • C++STL
        • 1.Queue&Stack
        • 2.String
        • 3.Map

C语言C++语言
面向过程编程
面向对象编程(类和对象)
泛型编程、元编程(模板)
函数式编程(Lambda)
STL(function、bind、thread、智能指针)
其他(左值与右值、深拷贝、移动构造、返回值优化)
异常处理
设计模式(创建型模式4种、结构型模式7种、行为型模式7种)

在这里插入图片描述

C++11新特性:

  1. auto关键字
  2. decltype关键字
  3. nullptr字面值
  4. constexpr关键字
  5. for (declaration : expression)
  6. Lambda表达式
  7. initializer_list(初始化列表)
  8. 标准库bind函数
  9. 智能指针shared_ptr, unique_ptr
  10. 右值引用&&(C++性能得到非常大的提升)
  11. STL容器std::array, std::forward_list, std::unordered_map, std::unordered_set

C++14新特性:

  1. 扩展了lambda表达式,增加泛型:支持auto
  2. 扩展了类型推导至任意函数:C11只支持lambda返回类型的auto
  3. 弃用关键字deprecated

C++17新特性:

  1. 扩展了constexpr至switch if等:C++11的constexpr函数只能包含一个表达式
  2. typename嵌套
  3. inline内联变量
  4. 模板参数推导
  5. 元组类std::tuple\std::pair实现两个元素的组合
  6. 类模板std::variant表示一个类型安全的联合体
  7. 引用包装器std::reference_wrapper
  8. 边长参数模板
  9. 结构化绑定(函数多值返回时用{}合成struct)
  10. 非类型模板参数可传入类的静态成员
  11. 在if和switch中可进行初始化
  12. 初始化(如struct)对象时可用花括号对其成员进行赋值
  13. 简化多层命名空间的写法
  14. lambda表达式可捕获*this的值,但this及其成员为只读
  15. 十六进制的单精度浮点数
  16. 继承与改写构造函数
  17. usingB1::B1;//表示继承B1的构造函数
  18. 当模板参数为非类型时,可用auto自动推导类型
  19. 判断有没有包含某文件__has_include

C++20新特性:

  1. concept用于声明具有特定约束条件的模板类型

    template<typename T> concept number = std::is_arithmetic<T>::value; //声明一个数值类型的concept

  2. 范围库Ranges Library

  3. 协程Coroutines

  4. 模块Modules

C++程序编译过程

在这里插入图片描述

  1. 预处理Preprocessing:将.cpp文件转化为.i文件,cpp -o test.i test.cppgcc -E test.c -o test.i

    预处理器把所有include的文件包括递归包含的文件内容,都展开到输出文件,并展开了所有的宏定义。

  2. 编译Compilation:将.cpp/.h文件转换成.s文件,cc test.i -o test.sgcc -S test.i -o test.x

    编译的过程将预处理的文件进行一系列的词法分析、语法分析、语义分析及优化成相应的汇编代码。这一步中一般会进行优化,比如去除没有用到的类的声明、循环语句的优化等。

  3. 汇编Assemble:将.s文件转化为.o文件,as -o test.o test.sgcc -c test.s -o test.o

    as汇编器会将汇编代码转换为机器指令,并以特定的二进制格式输出保存在目标文件中

  4. 链接Linking:将.o文件转换为可执行程序,ld test.o -o testgcc test.c

    ld链接器将程序的相关目标文件组合链接在一起,生成程序的可执行映像文件。要解决的问题是:可能调用了库函数、或者一个目标文件中调用了另外一个文件中的库函数,需要通过链接器建立对应的关系,使程序能够正常的执行。

补充:静态链接与动态链接

  • 静态链接:将源代码从静态链接库中拷贝到最终的可执行程序中,这样可能会导致最终的目标文件很大。
  • 动态链接:需要调用的库函数以动态链接库的形式存在,多个进程之间共享。而链接的时候只需要知道要调用的函数的位置即可。在程序执行时当需要调用某个动态链接库中的函数式,操作系统首先会查找所有正在运行的程序,看内存中是否已经有该库函数的拷贝了,如果有则多进程之间可以共享该拷贝,否则才会将其载入到该进行的虚拟内存中。

C++内存模型

C++程序内存分为5个区:堆、栈、静态全局区、常量区、代码区

在这里插入图片描述

  • 堆:new/malloc创建的内存,堆在内存中位于bss区和栈区之间,用于动态内存分配,一般由程序员分配和释放。
  • 栈:函数中的临时变量(局部变量)、函数的参数值,由编译器自动分配释放,
  • 全局区:声明变量既不在函数中也不再类中,分为未初始化和已初始化全局变量,存放静态数据、常量,程序结束后由系统释放。
  • 只读常量区:存放常量字符串,程序结束后由系统释放
  • 代码区:函数的定义、类定义、相关的程序逻辑(函数体的二进制代码)

补充:静态分配与动态分配

  • 静态分配:指发生在程序编译和链接的阶段
  • 动态分配:发生在程序的运行阶段

C++STL

如果对SLT不够熟练,在企业开发当中将会导致开发效率十分低,

1.Queue&Stack

#include<iostream>
#include<queue>
using namespace std;

int main() {
    queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);
    
    cout << "front = " << q.front() << " back = " << q.back() << " size = " << q.size() << endl;
    q.pop();
    cout << "front = " << q.front() << " back = " << q.back() << " size = " << q.size() << endl;
    q.pop();
    cout << "front = " << q.front() << " back = " << q.back() << " size = " << q.size() << endl;
    q.pop();
    cout << "front = " << q.front() << " back = " << q.back() << " size = " << q.size() << endl;
    q.pop();
    return 0;
}

在这里插入图片描述

可以看到虽然队列中只push了3次元素,但是使用queue进行第4次pop时程序也没有报错提醒,并且back的值居然得到了结果。

#include<iostream>
#include<stack>
using namespace std;

int main() {
    stack<int> s;
    s.push(1);
    s.push(2);
    s.push(3);

    cout << "top = " << s.top() << " size = " << s.size() << endl;
    s.pop();
    cout << "top = " << s.top() << " size = " << s.size() << endl;
    s.pop();
    cout << "top = " << s.top() << " size = " << s.size() << endl;
    s.pop();
    cout << "top = " << s.top() << " size = " << s.size() << endl;
    s.pop();
    return 0;
}

在这里插入图片描述

栈中只push了3次元素,使用stack进行第4次pop时程序直接给出了segmentfault错误。

  • 总结:在使用queue和stack等容器时,一定要做有效性的校验,否则拿到的数据可能会出错,或者直接导致segmentfault.
if (!q.empty()) cout << "front = " << q.front() << " back = " << q.back() << " size = " << q.size() << endl;
else cout << "queue is empty!" << endl;
if (!s.empty()) cout << "top = " << s.top() << " size = " << s.size() << endl;
else cout << "stack is empty!" << endl;

2.String

  1. str1 == str2调用的是str1的方法还是str2的方法?(运算符重载)

    答:理解为调用的是类对象str1的函数,而str2作为参数传入函数中,str1是一个this指针(this对象是str1)

  2. str1=“abcdefg”; str1[7]=‘K’;不报错,而str1[20]=‘K’;报错segmentation fault的原因?

    答:string对象会进行自动扩容1.5~2倍(编译器决定)

    #include<iostream>
    #include<string>
    using namespace std;
    
    int main() {
        string str1 = "helloworld";
    
        cout << "str1 = " << str1 << " size = " << str1.size() << endl;
        cout << "str1[0] = " << str1[0] << endl;
        cout << "str1[9] = " << str1[9] << endl;
        cout << "str1[10] = " << str1[10] << endl;
        cout << "str1[11] = " << str1[11] << endl;
        cout << "str1[12] = " << str1[12] << endl;
        cout << "str1[13] = " << str1[13] << endl;
        cout << "str1[20] = " << str1[20] << endl;
        cout << "str1[50] = " << str1[50] << endl;
        cout << "str1[120] = " << str1[120] << endl;
    
        int n = 1000;
        while (n--) str1 += "T";
        cout << "str1 = " << str1 << " size = " << str1.size() << endl;
        return 0;
    }
    

    在这里插入图片描述

  3. str1.length()与strlen(str1)的区别?

    答:strlen的时间复杂度为O(n),而string.length的时间复杂度为O(1),string类中存储着length的大小,strlen为遍历方式

    #include<iostream>
    #include<string>
    #include<cstring>
    using namespace std;
    
    int main() {
        int n = 100000000;
        string s1;
        while (n--) s1 += 'T';
    
        long start = clock();
        int size = s1.size();
        cout << "c++ size = " << size << " time = " << clock() - start << endl;
    
        start = clock();
        size = strlen(s1.c_str());
        cout << "c size = " << size << " time = " << clock() - start << endl;
    
        return 0;
    }
    

    在这里插入图片描述

    很明显的计算时间的差异

  4. cout对字符串的输出结束判定是通过str.size()的,而不是像C语言一样通过字符串末尾的\0

  5. 直接使用 str[11] = T 等赋值操作无法像 += 操作一样新增string字符串内容并触发string.size的修改。

3.Map

Map头文件命名空间
hash_map<hash_map>/<ext/hash_map>__gnu_cxx;
unordered_map<unordered_map>std
  1. 映射过程是根据哈希函数进行映射的,结果是乱序的,hash_map底层是利用数组实现的,在数组上再挂在链表。

  2. 使用map时需要预先进行find查找,以免访问未分配空间造成size增加!

    #include<iostream>
    #include<unordered_map>
    using namespace std;
    
    int main() {
    	unordered_map<string, int> hashmap;
    	hashmap["abc"] = 1;
    	hashmap["abcd"] = 2;
    	hashmap["abcde"] = 3;
    	hashmap.insert(pair<string, int>("adcdef", 4));
    	cout << "size = " << hashmap.size() << endl;
    
    	cout << "hashmap[\"hello\"] = " << hashmap["hello"] << endl;//访问非法空间则自动生成一个默认的类型
    	cout << "size = " << hashmap.size() << endl;
    	return 0;
    }
    

    在这里插入图片描述

    auto it = hashmap.find("hello");
    if (it != hashmap.end()) cout << "hashmap[\"hello\"] = " << hashmap["hello"] << endl;
    else cout << "hashmap[\"hello\"] is not exist!" << endl;
    
  3. 当map集合非常大时,使用swap方法比直接使用运算符重载的=进行赋值更快!

    swap方法将两个数据集进行对换,对换的过程中没有出现内存的拷贝,速度比使用重载的赋值运算符更快。

    #include<iostream>
    #include<map>
    using namespace std;
    
    int main() {
    	map<int, int> mymap1;
    	int n = 10000;
    	while (n--) mymap1[n] = 2;//map集合的数据集非常大10000条数据
    
    	unsigned long tick = clock();
    	map<int, int> mymap2 = mymap1;
    	cout << "time(operator) = " << clock() - tick << endl;//直接使用运算符重载时消耗的时间
    
    	tick = clock();
    	map<int, int> mymap3;
    	mymap3.swap(mymap1);
    	cout << "time(switch) = " << clock() - tick << endl;//使用switch方法对换数据消耗的时间
    
    	return 0;
    }
    

    在这里插入图片描述

  4. 遍历hashmap

    int main() {
    	unordered_map<string, int> hashmap;
    	hashmap["abc"] = 1;
    	hashmap["abcd"] = 2;
    	hashmap["abcde"] = 3;
    	hashmap.insert(pair<string, int>("adcdef", 4));
    	cout << "size = " << hashmap.size() << endl;
    
    	auto it = hashmap.find("hello");
    	if (it != hashmap.end()) cout << "hashmap[\"hello\"] = " << hashmap["hello"] << endl;
    	else cout << "hashmap[\"hello\"] is not exist!" << endl;
    
    	for (auto it = hashmap.begin(); it != hashmap.end(); ++it) {
    		cout << "key = " << it->first << "\tvalue = " << it->second << endl;
    	}
        for (auto it : hashmap) {
    		cout << "key = " << it.first << "\tvalue = " << it.second << endl;
        }
    	return 0;
    }
    

    在这里插入图片描述

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

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

相关文章

基于PaddlePaddle的图片分类实战 | 深度学习基础任务教程系列

图像相比文字能够提供更加生动、容易理解及更具艺术感的信息&#xff0c;图像分类是根据图像的语义信息将不同类别图像区分开来&#xff0c;是图像检测、图像分割、物体跟踪、行为分析等其他高层视觉任务的基础。图像分类在安防、交通、互联网、医学等领域有着广泛的应用。 一般…

LeetCode:77. 组合——回溯法,是暴力法?

&#x1f34e;道阻且长&#xff0c;行则将至。&#x1f353; &#x1f33b;算法&#xff0c;不如说它是一种思考方式&#x1f340;算法专栏&#xff1a; &#x1f449;&#x1f3fb;123 一、&#x1f331;77. 组合 题目描述&#xff1a;给定两个整数 n 和 k&#xff0c;返回范…

风场数据抓取程序实现(java+python实现)

一、数据源参数定义 关键参数代码&#xff1a; package com.grab.catchWindData.pram;/*** ClassName: DevPrams* Description: TODO**/ public class DevPrams {public static String lev_0to0p1_m_below_ground "lev_0-0.1_m_below_ground";public static Stri…

【微服务笔记08】微服务组件之Hystrix实现请求合并功能

这篇文章&#xff0c;主要介绍微服务组件之Hystrix实现请求合并功能。 目录 一、Hystrix请求合并 1.1、什么是请求合并 1.2、请求合并的实现 &#xff08;1&#xff09;引入依赖 &#xff08;2&#xff09;编写服务提供者 &#xff08;3&#xff09;消费者&#xff08;Se…

React | 认识React开发

✨ 个人主页&#xff1a;CoderHing &#x1f5a5;️ Node.js专栏&#xff1a;Node.js 初级知识 &#x1f64b;‍♂️ 个人简介&#xff1a;一个不甘平庸的平凡人&#x1f36c; &#x1f4ab; 系列专栏&#xff1a;吊打面试官系列 16天学会Vue 11天学会React Node专栏 &#x…

【分享】免梯子的GPT,玩 ChatGPT 的正确姿势

火了一周的 ChatGPT&#xff0c;HG 不允许还有小伙伴不知道这个东西是什么&#xff1f;简单来说就是&#xff0c;你可以让它扮演任何事物&#xff0c;据说已经有人用它开始了颜色文学创作。因为它太火了&#xff0c;所以&#xff0c;本周特推在几十个带有“chatgpt”的项目中选…

双交叉注意学习用于细粒度视觉分类和目标重新识别

目录Dual Cross-Attention Learning for Fine-Grained Visual Categorization and Object Re-Identification摘要本文方法消融实验Dual Cross-Attention Learning for Fine-Grained Visual Categorization and Object Re-Identification 摘要 目的&#xff1a; 探索了如何扩展…

JDK8——新增时间类、有关时间数据的交互问题

目录 一、实体类 二、数据库 三、数据交换 四、关于LocalDateTime类型 (java 8) 4.1 旧版本日期时间问题 4.2 新版日期时间API介绍 4.2.1 LocalDate、LocalTime、LocalDateTime 4.2.2 日期时间的修改与比较 4.2.3 格式化和解析操作 4.2.4 Instant: 时间戳 4.2.5 Duration 与…

Doris(6):数据导入(Load)之Stream Load

Broker load是一个同步的导入方式&#xff0c;用户通过发送HTTP协议将本地文件或者数据流导入到Doris中&#xff0c;Stream Load同步执行导入并返回结果&#xff0c;用户可以通过返回判断导入是否成功。 1 适用场景 Stream load 主要适用于导入本地文件&#xff0c;或通过程序…

小厂实习要不要去?

大家好&#xff0c;我是帅地。 最近暑假实习招聘&#xff0c;不少 训练营 学员都拿到了小厂实习来保底&#xff0c;但是很多小厂基本要求一周内给答复&#xff0c;中大厂就还在流程之中&#xff0c;所以很纠结小厂实习要不要去。 不知道你是否有这样的纠结&#xff0c;今天帅地…

【测试面试汇总2】

目录Linux操作系统1.Linux操作命令2.在Linux中find和grep的区别&#xff1f;3.绝对路径用什么符号表示&#xff1f;4.当前目录、上层目录用什么表示&#xff1f;5.主目录用什么表示&#xff1f;6.怎么查看进程信息&#xff1f;7.保存文件并退出vi 编辑?8.怎么查看当前用户id&a…

【Python从入门到进阶】15、函数的定义和使用

接上篇《14、字典高级应用》 上一篇我们学习了有关字典的高级应用操作&#xff08;字典的增删改查&#xff09;&#xff0c;本篇我们来学习Python中函数的定义和使用&#xff0c;包括函数的参数、返回值、局部变量和全景变量等操作。 一、一个思考 例如这里有一段大东北洗浴中…

2023年PMP报考时间安排攻略!

1.2023年PMP考试时间 PMP一年开考4次&#xff0c;分别为3月、6月、9月、12月&#xff0c;预计2023年PMP第一次考试时间在2023年3月左右&#xff0c;具体以基金会官方通知为准。 1&#xff09;为什么考PMP&#xff1f; 大部分人考 PMP 无非以下几个原因&#xff0c;总的来说&…

运行时内存数据区之程序计数器

内存是非常重要的系统资源&#xff0c;是硬盘和CPU的中间仓库及桥梁&#xff0c;承载着操作系统和应用程序的实时选行。JVM内存布局规定了Java在运行过程中内存申请、分配、管理的策略&#xff0c;保证了JVM的高效稳定运行。 不同的VM对于内存的划分方式和管理机制存在着部分差…

算法时间复杂度计算

目录 1.时间复杂度计算 1.1 时间复杂度例题 1.1.1例题 1.1.2例题 1.1.3例题 1.1.4例题 1.2时间复杂度leetcode例题 1.时间复杂度计算 首先&#xff0c;我们需要了解时间复杂度是什么&#xff1a;算法的时间复杂度是指算法在编写成可执行程序后&#xff0c;运行时需要耗费…

一天吃透操作系统八股文

操作系统的四个特性&#xff1f; 并发&#xff1a;同一段时间内多个程序执行&#xff08;与并行区分&#xff0c;并行指的是同一时刻有多个事件&#xff0c;多处理器系统可以使程序并行执行&#xff09; 共享&#xff1a;系统中的资源可以被内存中多个并发执行的进线程共同使…

MATLAB | 给热图整点花哨操作(三角,树状图,分组图)

前段时间写的特殊热图绘制函数迎来大更新&#xff0c;基础使用教程可以看看这一篇&#xff1a; https://slandarer.blog.csdn.net/article/details/129292679 原本的绘图代码几乎完全不变&#xff0c;主要是增添了很多新的功能&#xff01;&#xff01;&#xff01; 工具函数完…

FastChat开放,媲美ChatGPT的90%能力——从下载到安装、部署

FastChat开放&#xff0c;媲美ChatGPT的90%能力——从下载到安装、部署前言两个前置软件创建FastChat虚拟环境安装PyTorch安装 FastChat下载 LLaMA&#xff0c;并转换生成FastChat对应的模型Vicuna启动FastChat的命令行交互将模型部署为一个服务&#xff0c;提供Web GUI前言 最…

Cesium:自定义MaterialProperty

在项目中应用Cesium.js时,时常遇到需要对Cesium.js的Material材质或者MaterialProperty材质属性进行拓展的应用场景。如果对GLSL(openGL Shading Language ),即:OpenGL着色语言熟悉的话,参考Cesium官方文档,构建一个新的Material必定不是难事。而MaterialProperty材质属…

【C语言进阶:动态内存管理】动态内存函数的介绍

本节重点内容&#xff1a; malloc 和 free 函数calloc 函数realloc 函数&#x1f338;为什么存在动态内存分配 到目前为止&#xff0c;我们已经掌握的内存开辟方式有两种&#xff1a; 创建变量&#xff1a;int val 20; //在栈空间上开辟四个字节 创建数组&#xff1…