AlgoC++第三课:C++世界观

目录

  • C++世界观
    • 前言
    • 1. 程序逻辑
    • 2. 内存的逻辑
    • 3. 调度的逻辑
    • 4. 编译的逻辑
    • 5. 作用域的逻辑
    • 6. 命名空间的逻辑
    • 7. 生命周期的逻辑
    • 8. C++类的逻辑
    • 9. 编译时和运行时的逻辑
    • 总结

C++世界观

前言

手写AI推出的全新面向AI算法的C++课程 Algo C++,链接。记录下个人学习笔记,仅供自己参考。

本次课程主要讲解 C++ 世界观

课程大纲可看下面的思维导图

在这里插入图片描述

1. 程序逻辑

在操作系统层面上,可以有多个程序进程, 而每个进程又是由一个主线程和多个子线程组成,值得注意的是:

  • 进程是静态的是上下文,线程是动态的,用来执行具体代码

  • 每个进行必有主线程,主线程结束,则进程停止,子线程可以创建多个

  • 每个进程都有属于它的堆内存,进程内所有线程共用,但与其它进程是隔离的

在这里插入图片描述

2. 内存的逻辑

之前提到过每个进程都有属于它的堆内存,而每个线程又有属于它的栈内存,我们主要关注栈和堆内存。C++ 是强调内存的语言,你需要知道你的变量在哪里,进而生命周期是如何定义的,值得注意的是:

  • 每个进程都有属于它的堆内存,进程内所有线程共用,但与其它进程是隔离的
  • 每个线程都有属于自己的栈内存,用来储存当前执行位置的函数调用入参、局部变量
  • 之所以叫栈内存,因为采用的是栈的数据结构来表示函数的调用入参
  • 堆内存很大,基本接近内存条大小,栈内存很小,一般4MB。stackoverflow 就是递归超过栈空间时的异常
  • 比如 char a[100] 开辟的就是堆内存空间,而 new a[100] 开辟的就是栈内存空间

在这里插入图片描述

3. 调度的逻辑

CPU 可以形象化为一个工人,不考虑多核,它就是个一次执行一个任务的工人。它只能串行执行任务,但是它的速度特别特别快,一秒数亿次计算。现实生活中,我们需要大量并行的场景,比如播放音乐的同时打游戏,那串行的 CPU 如何来解决并行的问题呢?因此引入线程调度的概念

想象下这样一个场景,假如你是一名厨师,现在有三个餐桌等着你上菜,你应该如何上菜保证让客户都满意?

在这里插入图片描述

我会采用每个桌子各出一个菜的方式,使得大家觉得出餐是并行的,营造一种厨房里有三个厨师的假象,其实只有你一个,只不过你有点强,同时炒了三个锅的菜,来回切换,只是你切换的时间非常快,让人毫无察觉😂

在炒菜的同时厨师还需要为每个餐桌记住状态(如已经上了几个菜了,都上了些啥菜,还剩下啥菜),在第二次为该餐桌炒菜时可以顺序推进

在这里,餐桌的菜品就是需要执行的代码,餐桌即线程,而餐桌的状态,则采用寄存器存储,当下一次处理该线程时,调出寄存器内的状态

寄存器存储的线程状态,称之为现场,储存现场,恢复现场,值得注意的是:

  • 引入线程调用是为了串行模拟并行,CPU 太快了,使用者感受不出来区别
  • 每个线程分配的执行时间,称之为时间片,通常是非常小的单位
  • 由于调度的存在,它会在机器指令层面的任何一句上中断,而后调用其它线程。这也是 C++ 语言需要了解的逻辑
  • 过多的线程,会让 CPU 消耗大量精力处理存储现场、恢复现场等准备工作。降低执行任务的频率,让电脑变得卡顿

4. 编译的逻辑

在 C++ 的世界观中,我们一定要有编译和链接的概念,一个程序从代码到执行是包括编译和链接两个部分的。

其中,编译又可以分为预处理、编译、汇编三个部分

  • 预处理:把 C++ 源代码的宏语法进行展开,并整理 C++ 代码为翻译单元
  • 编译:将整理后的翻译单元编译成汇编代码
  • 汇编:将汇编代码编译为目标机器的机器码

链接时将所有的 C++ 得到的机器码联合起来,成为一个最终的可执行程序(集中力量办大事)

编译时只处理语法的正确性,对于函数调用,仅储存名称符号;链接时全局查找,为每一个符号找到具体实现,找到多个或者没找到都会编译失败,也因此我们引入声明实现的概念,声明是外壳,实现是实体

int compute(int a, int b);  // 声明

int compute(int a, int b){	// 实现
    return a * b;
}

5. 作用域的逻辑

作用域有文件构建的作用域和大括号构建的作用域

对于文件构建的作用域,直接在 C++ 文件最外层定义的任何东西(如变量、类、函数),其作用于整个程序所有位置,而加上了 static 后,只作用于当前文件内

编译时,各文件相互不干扰

链接时,同名全名变量或同名同参的函数会冲突。static 可使得链接时对外不可见

访问其它 C++ 变量可以加上 extern 关键字,访问其它 C++ 函数加声明

对于大括号构建的作用域,出作用域,变量失效,内存释放;任何作用域,都应该能访问其父级领域内的所有成员,反过来不行

{
    int x = 123;
    
    {
        int y = x + 5;
    }
}

{
    int x = 567;
}

6. 命名空间的逻辑

命名空间是为作用域设置一个名称,方便写代码。访问时采用作用域 :: 符合,未命名的作用域,视作全局作用域

namespace{
    int number = 123;
}

namespace AA{
    int number = 567;
}

int main(){
    
    cout << number << endl;		// 123
    cout << ::number << endl;	// 123
    cout << AA::number << endl;	// 567
    
    return 0;
}

7. 生命周期的逻辑

关于声明周期的逻辑,有以下几点值得注意:

  • 每个作用域都有生命周期,是动态存在的。而命名空间是静态的,是为了写代码方便的
  • 全局变量,属于全局作用域,随程序结束而销毁
  • 进入作用域,变量构造,出作用域,变量释放,析构

8. C++类的逻辑

解决多态,是 C++ 类处理 OOP(Object Oriented Programming) 的核心逻辑而二级指针和虚表,是实现多态动态绑定的主要手段

9. 编译时和运行时的逻辑

C++ 有编译时(链接时)和运行时的区分

链接时:关注的是 cpp 文件、o 文件、so、a,关头文件路径、库文件位置

运行时:关注运行依赖的库所在位置,当前工作目录(workspace folder),环境变量

库路径:在链接时和运行时都要关注,容易让人混淆。链接时只关注是否找到即可。而运行时必须保证加载成功。并且链接时与运行时查找 so 的方式截然不同。运行时查找 .so 动态库的方式是通过设置环境变量 LD_LIBRARY_PATH 来指定动态库搜索路径,而链接时查找 .so 动态库的方式则是通过编译链接时指定 -l 选项和 -L 选项来指定动态库的搜索路径和库名

工作目录:很多人容易忽视的问题,当你 open("a.txt") 时,这个 a.txt 表示工作目录下的 a.txt,工作目录也称之为当前目录,在各个配置中可以看到如 cwd、workspacedir、pwd。当在调试或者运行程序时提示找不到文件,可以检查下文件是否放在了工作目录下。

总结

本次课程了解整个C++的世界观,特别是调度和编译的逻辑,要区分链接时和运行时库路径的查找方式。而对于C++类的逻辑并没有深究,期待下次课程😄

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

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

相关文章

Vue+Vant封装通用模态框单选框组件

前言 我们知道&#xff0c;在vant组件中提供的组件往往是比较基础的&#xff0c;能够满足基本需求。但是我们想实现ui设计的一些比较丰富效果的组件&#xff0c;需要自己去实现&#xff0c;且当项目中多次用到的时候&#xff0c;我们将以组件化的思想将其封装起来&#xff0c;…

Linux服务器出现503 服务不可用错误怎么办?

​  HTTP 503 服务不可用错误代码表示网站暂时不可用。无论您是网站访问者还是管理员&#xff0c;503 页面都很麻烦。尽管该错误表明存在服务器端问题&#xff0c;但对于访问者和网络管理员来说&#xff0c;有一些可能的解决方案。本文将解释Linux服务器出现503 服务不可用错…

scratch足球射门练习 中国电子学会图形化编程 少儿编程 scratch编程等级考试一级真题和答案解析2023年3月

目录 scratch足球射门练习 一、题目要求 1、准备工作 2、功能实现 二、案例分析

【网络安全】红队基础免杀

引言 本文主要介绍“反射型 dll 注入”及“柔性加载”技术。 反射型 dll 注入 为什么需要反射型 dll 注入 常规的 dll 注入代码如下&#xff1a; int main(int argc, char *argv[]) {HANDLE processHandle;PVOID remoteBuffer;wchar_t dllPath[] TEXT("C:\\experime…

分享几个国内免费的ChatGPT镜像网址(亲测有效-4月25日更新)

最近由于ChatGPT的爆火也让很多小伙伴想去感受一下ChatGPT的魅力&#xff0c;那么今天就分享几个ChatGPT国内的镜像网址&#xff0c;大家可以直接使用&#xff01;记得点赞收藏一下呦&#xff01; 1、AQ Bot&#xff0c;网址&#xff1a;点我 https://su.askaiw.com/aq 缺点&…

面试篇:Redis

一、缓存穿透 1、缓存穿透 查询一个不存在的数据&#xff0c;mysql查询不到数据也不会直接写入缓存&#xff0c;就会导致每次请求都查数据库。即&#xff1a;大量请求根本不存在的key 2、查询流程 3、出现原因 业务层误将缓存和库中的数据删除了&#xff0c;也可能是有人恶…

JUC-多线程(12. AQS-周阳)学习笔记

文章目录 1. 可重入锁1.1. 概述1.2. 可重入锁类型1.3. Synchronized 可重入实现机理 2. LockSupport2.1. LockSupport 是什么2.2. 3种线程等待唤醒的方法2.2.1 Object 的等待与唤醒2.2.2. Condition接口中的等待与唤醒2.2.3. 传统的 synchronized 和 Lock 实现等待唤醒通知的约…

【手把手做ROS2机器人系统开发一】开发环境搭建

【手把手做ROS2机器人系统开发一】开发环境搭建 目录 【手把手做ROS2机器人系统开发一】开发环境搭建 一、专栏介绍&#xff1a; 二、开发环境搭建&#xff1a; 1.Ubuntu系统安装 2.ROS2系统环境安装 3.测试系统运行 一、专栏介绍&#xff1a; 大家好&#xff0c;今天给大家…

栈的基本操作(C语言实现)创建,销毁,入栈,出栈

前言 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 压栈&#xff1a;栈的…

同样是测试,朋友到了30k,我才12K,这份测试面试8股文确实牛

程序猿在世人眼里已经成为高薪、为人忠诚的代名词。 然而&#xff0c;小编要说的是&#xff0c;不是所有的程序员工资都是一样的。 世人所不知的是同为程序猿&#xff0c;薪资的差别还是很大的。 众所周知&#xff0c;目前互联网行业是众多行业中薪资待遇最好的&#xff0c;…

Fedora 38 正式发布

Fedora Linux 38 正式发布&#xff0c;用户可以访问官网下载安装最新版本。 新网站 如果你点击了上面的官网链接&#xff0c;你应该会注意到 Fedora 的官网看起来与之前有了很大不同。这是 Fedora Websites & Apps 团队与 Design & Infrastructure 团队以及广大社区合作…

【视频课程】算法工程师需要的ChatGPT大模型算法理论与实践课程!非粗浅科普...

前言 自从2022年11月ChatGPT发布之后&#xff0c;迅速火遍全球。其对话的交互方式&#xff0c;能够回答问题&#xff0c;承认错误&#xff0c;拒绝不适当的请求&#xff0c;高质量的回答&#xff0c;极度贴近人的思维的交流方式&#xff0c;让大家直呼上瘾&#xff0c;更是带火…

安装配置SVN版本控制管理工具

SVN工具能帮我们做什么&#xff1f; 核心功能&#xff1a;文档版本管理系统 适合对象&#xff1a;个人与团队都可以使用&#xff0c;企业中项目资源的重要管理工具 举例&#xff1a;一个文件夹里面的文档管理 1.下载安装SVN服务器 VisualSVN-Server 2.下载安装SVN客户端 T…

<网络编程>网络套接字

目录 理解源IP地址和目的IP地址 认识端口号 端口号和进程ID的关系 理解源端口号和目的端口号 初步认识TCP、UDP协议 TCP协议 UDP协议 网络字节序列 socket网络接口 socket常见API sockaddr结构 UDPsocket 编码&#xff1a; 理解源IP地址和目的IP地址 源IP&#xf…

Jupyter Notebook的安装与使用

Jupyter Notebook Jupyter Notebook介绍Jupyter Notebook使用安装启动创建文件编写代码和文本常用命令配置文件 Anaconda Jupyter Notebook介绍 Jupyter Notebook是一个基于Web的交互式计算环境&#xff0c;可以让用户以文档形式记录代码、数据分析结果和说明文本&#xff0c;并…

从零开始的ChatGLM 配置详细教程

从零开始的ChatGLM配置教程 文章目录 从零开始的ChatGLM配置教程一&#xff0c;前言二&#xff0c;环境配置1、下载ChatGLM项目2、配置程序运行环境 三、在HuggingFace下载chatGLM-6B模型1&#xff0c;安装 Git Lfs2&#xff0c;下载相关文件3&#xff0c;在HuggingFace中下载相…

一致性 Hash 算法 及Java TreeMap 实现

1、一致性 Hash 算法原理 一致性 Hash 算法通过构建环状的 Hash 空间替线性 Hash 空间的方法解决了这个问题&#xff0c;整个 Hash 空间被构建成一个首位相接的环。 其具体的构造过程为&#xff1a; 先构造一个长度为 2^32 的一致性 Hash 环计算每个缓存服务器的 Hash 值&…

基于Java+Spring+vue+element实现旅游信息管理平台系统

基于JavaSpringvueelement实现旅游信息管理平台系统 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码联系方式 文…

抢先看,甘特图工具DHTMLX gantt 灯箱编辑器通过套件 UI 小部件进行了扩展

DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的大部分开发需求&#xff0c;具备完善的甘特图图表库&#xff0c;功能强大&#xff0c;价格便宜&#xff0c;提供丰富而灵活的JavaScript API接口&#xff0c;与各种服务器端技术&am…

为什么重写equals时必须重写hashCode()

不重写equals和不重写 hashCode()之前&#xff1a;equals()比较的是对象的内存地址&#xff0c;hashCode()比较的其实也是内存地址(内存地址输入到哈希函数中得到的整数) 重写了之后&#xff0c;equals()比较的是对象的内容值&#xff0c;如果hashCode()不重写&#xff0c;还是…