了解C++工作机制
基于hello.cpp对C++的运行进行一个初步认识,并介绍国外C++大佬Cherno常用的项目结构和调试Tips
C++是如何工作的
- C++工作流程
- 1.实用工程(project)结构
- (1)Microsoft Visual Studio2022新建项目后,自动生成的原始文件和文件夹:
- (2)写一个简单的main.cpp,编译运行后,自动创建文件加和生成中间文件(obj)和可执行文件(exe)
- (3)从默认工程/项目(project)结构到实用工程/项目结构
- 2.调试(debug)
- 3.1整体代码
- 3.2预处理
- 3.3.编译
- 3.4链接
- 4.C++编译器
- 4.1定义与作用
- 4.2示例
- 4.3编译器的优化代码例子 ——“常数折叠”
- 5.C++链接器
- 6.头文件
- 6.1定义与作用
- 6.2示例
- 4.3在实现函数的 functions.cpp 文件中包含 #include "functions.h" 的目的
C++工作流程
1.实用工程(project)结构
(1)Microsoft Visual Studio2022新建项目后,自动生成的原始文件和文件夹:
(2)写一个简单的main.cpp,编译运行后,自动创建文件加和生成中间文件(obj)和可执行文件(exe)
(3)从默认工程/项目(project)结构到实用工程/项目结构
- 实用如下宏修改输出目录和中间目录
$(SolutionDir)bin\$(Platform)\$(Configuration)\
$(SolutionDir)bin\intermediates\$(Platform)\$(Configuration)\
-$(SolutionDir)代表当前解决方案,不同的的解决方案会进行不同的具体的实例化,$(Platform)以此类推
2. 切换为“显示所有文件”的视图,并且新建一个src文件夹,用于收录.cpp文件
3.写一个简单的cpp文件,并且查看编译运行后的目录结构
这样的目录结构是不是更清晰喜人呢?
2.调试(debug)
Ctrl+F5进入调试模式,F11可单步执行,调试–>窗口–>内存–>内存1,可以查看当前程序使用的内存的内存的状态
断点之上的代码已经运行,断点及断点之下的代码将要运行,这里我们键入参数a的地址,并且回车
3.1整体代码
#include<iostream>int main()
{std::cout << "hello, cpp!" << std::endl;std::cin.get();return 0;
}
}
3.2预处理
预处理(Preprocessing)是 C++ 编译过程中的第一个阶段,它在实际的编译之前对源代码进行一系列的文本替换和处理操作。
#include <iostream>
在编译之前,C++ 编译器会进行预处理,经预处理后,iostream文件中的内容就被copy到我们的源文件中了。
项目中每一个cpp文件都会被编译,但头文件不会被编译,因为其已经被预处理过了。
3.3.编译
编译是将高级程序设计语言(如C++)编写的源代码转换成计算机可以执行的机器代码的过程。
cpp的代码正常情况下是从上到下一行一行编译的(头文件不会被执行编译,其在预处理时被包含进来,和后面的代码一起编译)。
#include<iostream> int main()
{std::cout << "hello, cpp!" << std::endl;std::cin.get();return 0;
}
完成编译后,生成了obj文件。在 Windows 平台上,“.obj” 文件通常是使用 Microsoft Visual Studio 编译器生成的。
obj文件包含了编译器对源代码的翻译结果。 这个文件中包含了与源代码中的每个函数和变量相关的机器代码,并且还可能包含一些调试信息、符号表、重定位信息等。目标文件的生成是编译的一部分,它还需要经过链接过程,与其他目标文件和库文件一起生成最终的可执行文件(exe)。
3.4链接
链接(Linking)是 C++编译过程中的一个重要阶段,它将编译器生成的目标文件和其他可能用到的目标文件或库文件合并成最终的可执行文件。
每一个cpp源文件都对应一个obj,链接器将其连接后,生成可执行文件。
增加一个cpp源文件,如下:
#include<iostream>void log(const char* message)
{std::cout << message << std::endl;
}
对其编译后,在debug文件夹下会看到其生成的obj文件:
4.C++编译器
4.1定义与作用
C++编译器是一种将C++源代码翻译成目标代码(通常是机器代码)的工具。其工作包括词法分析、语法分析、语义分析、优化和代码生成等阶段。
-
词法分析(Lexical Analysis):编译器首先会将源代码分解成基本单元,这些单元被称为词法单元(tokens),比如关键字、标识符、运算符等。
-
语法分析(Syntax Analysis):在这个阶段,编译器将词法单元组织成语法树,以检查代码的结构是否符合语法规则。
-
语义分析(Semantic Analysis):编译器会检查代码的语义是否合法,比如变量是否被正确声明和使用,函数是否正确调用等。
-
优化(Optimization):在生成目标代码之前,编译器可能会进行一系列的优化操作,以提高程序的性能或减小生成的目标代码的体积。
-
代码生成(Code Generation):最终阶段是生成目标代码,这是计算机可以直接执行的机器代码。这些代码通常是针对特定硬件架构的。
4.2示例
#include <iostream>int main() {int x = 5; // 变量声明和赋值int y = 10;int result = x + y; // 加法操作std::cout << "The result is: " << result << std::endl;return 0;
}
在这个示例中,编译器将首先进行词法分析,将代码分解成词法单元。然后进行语法分析,构建语法树。接着进行语义分析,确保变量被正确声明和使用。最后,编译器会生成目标代码,执行加法操作并输出结果。这是一个简化的过程,实际编译器会进行更多的优化和处理。
4.3编译器的优化代码例子 ——“常数折叠”
常数折叠(Constant Folding)是指编译器在编译阶段对常量表达式进行计算,并将其结果直接替换回表达式的值。这个过程发生在编译器静态分析阶段,有助于优化代码,减少运行时的计算量。
举个例子:
int result = 5 + 3 * 2;
在常数折叠过程中,编译器会对表达式进行计算。在这个例子中,3 * 2是一个常量表达式,编译器可以在编译阶段计算出其结果为6。因此,整个表达式可以被折叠为:
int result = 5 + 6;
这个过程可以减少程序运行时的计算量,提高代码的执行效率。
5.C++链接器
链接器(Linker)是编译器工具链中的一个部分,它负责将多个目标文件(Object Files)或者库文件(Library Files)中的代码和数据结合起来,生成最终的可执行文件或者库文件。在程序编译过程中,源代码会被编译成目标文件,这些目标文件可能包含了程序的不同部分,比如函数、变量等。
链接器的主要任务包括:
-
符号解析(Symbol Resolution):处理各个目标文件中使用的符号(如函数、变量名),将其与实际的内存地址或者其他目标文件中的符号联系起来。
-
符号合并(Symbol Combining):将各个目标文件中定义的符号整合到最终的输出文件中,解决多个目标文件中可能存在的重复定义。
-
地址重定位(Address Binding):将各个目标文件中的符号地址绑定到最终的可执行文件或库文件中,以便在程序加载到内存并执行时,能够正确地定位和访问各个符号。
-
生成可执行文件或库文件(Executable or Library Generation):最终将链接后的目标文件生成可执行文件(例如.exe文件)或者库文件(例如.dll或.lib文件),供操作系统或其他程序使用。
链接器的工作分为静态链接和动态链接两种方式。静态链接是将所有的目标文件和库文件在编译时链接成一个完整的可执行文件,而动态链接是在程序运行时才进行链接,可以实现共享库(Shared Library)的功能。
总的来说,链接器在编译过程的最后阶段,将各个模块或库文件整合在一起,生成可执行的程序或者库文件,使得程序能够正确地运行。
6.头文件
6.1定义与作用
头文件(Header File)是一种文本文件,通常以.h为扩展名,包含了函数、类、变量等的声明和定义。头文件的主要作用是提供接口和声明,让程序能够访问和使用某些功能而无需了解其具体实现细节。
头文件的作用包括:
-
声明和接口提供: 头文件通常包含函数、类、变量的声明,允许在不暴露实现细节的情况下使用这些元素。其他文件可以包含头文件,从而访问其中声明的内容,而不必了解其实现细节。
-
模块化和组织性: 头文件有助于组织代码,将相关的功能组织到单独的模块中,并通过包含不同的头文件来实现模块化。这样可以提高代码的可维护性和可读性。
-
重用和共享代码: 头文件中的声明和接口可以被多个文件共享和重用,使得相同的函数、类或变量能够在多个文件中使用,减少重复编写代码的工作量。
头文件在以下场景中能够发挥作用:
-
多文件项目: 当程序由多个源文件组成时,头文件能够提供接口和声明,使得各个文件能够互相访问和使用彼此的功能,提高了代码的组织性和可维护性。
-
库开发: 在开发库或框架时,头文件对外提供了公共接口和声明,允许其他开发者使用库的功能而无需了解其内部实现。
-
项目协作: 在团队协作开发项目时,头文件定义了函数、类等的接口,让团队成员了解如何使用这些接口而无需深入了解实现细节。
6.2示例
创建头文件(例如:functions.h):头文件包含函数的声明和可能的结构、常量或其他相关内容。
// functions.h
#pragma once// 函数声明
int add(int a, int b);
float divide(float a, float b);
在源文件中包含头文件:在需要使用这些函数的源文件中,包含头文件。
// main.cpp#include <iostream>
#include "functions.h" // 包含头文件int main() {int result = add(5, 3); // 调用头文件中声明的函数std::cout << "Result: " << result << std::endl;return 0;
}
实现函数:在源文件中实现头文件中声明的函数。
// functions.cpp#include "functions.h" // 包含对应的头文件int add(int a, int b) {return a + b;
}float divide(float a, float b) {if (b != 0) {return a / b;} else {return 0; // 可以根据实际需求进行异常处理或错误提示}
}
好处:
-
模块化和组织性: 使用头文件可以将函数的声明和结构、常量等信息组织在一起,使得代码更模块化和易于维护。
-
可读性: 头文件提供了函数接口的清晰定义,使得阅读和理解代码更为容易。
-
代码重用: 通过头文件的方式,可以在多个源文件中重复使用相同的函数声明,提高了代码的重用性。
-
错误检查: 预编译器指令(#ifndef、#define、#endif)用于防止头文件被多次包含,避免了重复定义和编译错误。
-
维护方便: 当需要修改函数接口时,只需在头文件中修改函数的声明,而不必修改所有使用该函数的源文件。
4.3在实现函数的 functions.cpp 文件中包含 #include “functions.h” 的目的
在实现函数的 functions.cpp 文件中包含 #include “functions.h” 是为了确保函数的实现与其声明一致。这样做有以下作用:
-
检查一致性: #include “functions.h” 会将头文件中的函数声明包含到 .cpp 文件中,这样编译器就能检查函数的实现是否与其声明一致。如果实现与声明不一致,编译器会报错,提醒修正错误。
-
可读性和维护性: 包含头文件可以让读者清晰地看到函数的接口和声明。这样使得代码更易读、易懂,并且方便维护。
-
代码一致性: 保持函数声明和定义的一致性是良好编程实践的一部分,有助于代码的可靠性和一致性。
在某些情况下,如果函数的实现非常简单,不需要使用头文件中的其他信息(例如结构、常量等),有时可以省略包含头文件。但是,为了代码的可读性和一致性,我们最好在函数的实现文件中包含对应的头文件。
相关文章:

了解C++工作机制
基于hello.cpp对C的运行进行一个初步认识,并介绍国外C大佬Cherno常用的项目结构和调试Tips C是如何工作的 C工作流程1.实用工程(project)结构(1)Microsoft Visual Studio2022新建项目后,自动生成的原始文件…...

力扣题目学习笔记(OC + Swift) 14. 最长公共前缀
14. 最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 “”。 方法一 竖向扫描法 个人感觉纵向扫描方式比较直观,符合人类理解方式,从前往后遍历所有字符串的每一列,比较相同列上的…...

WinSW设置应用程序开机启动
前言 由于使用windows自动的自启方法,不管是将程序启动服务放到开机自启文件夹中,还是创建任务计划程序,都没有很好的实现程序的开机自启效果,而WinSW很好的解决了这个问题。 下载 WinSW下载地址 注意:不同版本&#…...

Leetcode—96.不同的二叉搜索树【中等】
2023每日刷题(六十四) Leetcode—96.不同的二叉搜索树 算法思想 实现代码 class Solution { public:int numTrees(int n) {vector<int> G(n 1, 0);G[0] 1;G[1] 1;for(int i 2; i < n; i) {for(int j 1; j < i; j) {G[i] G[j - 1] * …...
正则表达式零宽断言
正则表达式零宽断言 工具类,正则表达式匹配文本内容正则表达式语法例子例子01零宽断言?< 不包含左边值? 不包含右边值例子 常用正则表达式校验数字的表达式校验字符的表达式 工具类,正则表达式匹配文本内容 /*** 正则表达式工具类*/ public class…...
uni-app学习记录
uni-app注意点记录 跳转到 tabBar 页面只能使用 switchTab 跳转路由API的目标页面必须是在pages.json里注册的vue页面。如果想打开web url,在App平台可以使用 plus.runtime.openURL或web-view组件;H5平台使用 window.open;小程序平台使用web…...

API资源对象StorageClass;Ceph存储;搭建Ceph集群;k8s使用ceph
API资源对象StorageClass;Ceph存储;搭建Ceph集群;k8s使用ceph API资源对象StorageClass SC的主要作用在于,自动创建PV,从而实现PVC按需自动绑定PV。 下面我们通过创建一个基于NFS的SC来演示SC的作用。 要想使用NFS的SC,还需要安装一个NFS…...

Databend 开源周报第 124 期
Databend 是一款现代云数仓。专为弹性和高效设计,为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务:https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展,遇到更贴近你心意的 Databend 。 新增对 Delta 和…...

Arduino开发实例-液体流量测量
液体流量测量 文章目录 液体流量测量1、流量传感器介绍2、硬件准备及接线3、代码实现在本文中,将介绍如何流量传感器进行测量液体流量。 流量传感器用于测量液体流速。 市场上有不同类型的流量传感器,在本文中,我们将使用霍尔效应流量传感器。 这些类型的流量传感器是非侵入…...

【idea】解决sprintboot项目创建遇到的问题
目录 一、报错Plugin ‘org.springframework.boot:spring-boot-maven-plugin:‘ not found 二、报错java: 错误: 无效的源发行版:17 三、java: 无法访问org.springframework.web.bind.annotation.CrossOrigin 四、整合mybatis的时候,报java.lang.Ill…...
ADC芯片CS1237在电子秤方案的优势
随着科技的不断发展,电子秤已经成为我们日常生活中不可或缺的测量工具。为了满足用户对于高精度、高稳定性的需求,芯海ADC芯片CS1237应运而生,为电子秤方案带来了革命性的变革。 一、芯海ADC芯片CS1237介绍 芯海ADC芯片CS1237是一款高性能…...
Leetcode的AC指南 —— 哈希表:202. 快乐数
摘要: Leetcode的AC指南 —— 哈希表:202. 快乐数。题目介绍:编写一个算法来判断一个数 n 是不是快乐数。 文章目录 一、题目二、解析1、哈希表 一、题目 题目介绍:编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为…...
机器学习 项目结构 数据预测 实验报告
需求: 我经过处理得到了测试值,然后进一步得到预测和真实值的比较,然后再把之前的所有相关的参数、评估指标、预测值、比较结果都存入excel,另外我还打算做测试报告模板,包括敏感性分析等。您建议我这些功能如何封装这些功能&…...

[Verilog] 设计方法和设计流程
主页: 元存储博客 文章目录 1. 设计方法2. 设计流程 3 Vivado软件设计流程总结 1. 设计方法 Verilog 的设计多采用自上而下的设计方法(top-down)。设计流程是指从一个项目开始从项目需求分析,架构设计,功能验证&#…...

C语言:指向数组的指针和指向数组元素的指针
相关阅读 C语言https://blog.csdn.net/weixin_45791458/category_12423166.html?spm1001.2014.3001.5482 指向数组的指针和指向数组元素的指针常常被混淆,或者笼统地被称为数组指针,但它们之间是有差别的,本文就将对此进行讨论。 下面的代码…...
SQL基础:SQL 介绍和数据库基础
SQL简介 常用的Java等语言是和计算机交流的工具,告诉计算机,让计算机做一些事。 和其类似,SQL是 Structured Query Language 的缩写,即结构化的查询语言,是和数据库交互的工具,即通过既定的一些格式&…...

SpringSecurity入门
前言 Spring Security是一个用于在Java应用程序中提供身份验证和授权功能的强大框架。它构建在Spring框架之上,为开发人员提供了一套灵活且全面的安全性服务,本篇将为大家带来Spring Security的详细介绍及入门 一.安全框架 在学习了解Spring Security之…...
iOS 应用在前台时显示通知
背景: 在iOS应用中,当应用在前台运行时,是不会默认弹出通知的。这是iOS的设计决定,以避免用户在使用应用的过程中被打扰。然而,如果你希望在应用在前台的时候也能收到通知,你可以在你的应用代码中进行一些…...
Hamming space
汉明距离表示两个相同长度字符串对应位置的不同字符的数量。 对两个字符串异或运算,并统计1的个数并相减,这个数就是汉明距离。...

anaconda 安装 使用 pytorch onnx onnxruntime
一:安装 如果不是 x86_64,需要去镜像看对应的版本 安装 Anaconda 输入命令 bash Anaconda3-2021.11-Linux-x86_64.sh 然后输入 yes 表示同意 确认安装的路径,一般直接回车安装在默认的 /home/你的名字/anaconda3 很快就安装完毕。输入 yes…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁
赛门铁克威胁猎手团队最新报告披露,数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据,严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能,但SEMR…...
命令行关闭Windows防火墙
命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)方法二:CMD命令…...

轻量级Docker管理工具Docker Switchboard
简介 什么是 Docker Switchboard ? Docker Switchboard 是一个轻量级的 Web 应用程序,用于管理 Docker 容器。它提供了一个干净、用户友好的界面来启动、停止和监控主机上运行的容器,使其成为本地开发、家庭实验室或小型服务器设置的理想选择…...
python打卡第47天
昨天代码中注意力热图的部分顺移至今天 知识点回顾: 热力图 作业:对比不同卷积层热图可视化的结果 def visualize_attention_map(model, test_loader, device, class_names, num_samples3):"""可视化模型的注意力热力图,展示模…...