初学者无痛C转C++

初学者无痛C转C++

文章目录

为什么要转C++

首先,对于C语言,它初见虽然简单,但是深入后确实非常的难并且不方便的。

例如C语言使用排序qsort必须要写排序函数,但是用C++的std::sort就很方便,而且对于一些常见的数据结构C++也有相对应的STL容器如:queue,stack,vector
最重要的还是C++在C++11之前和C语言相差不大,如果仅仅是打算法竞赛那么C++=C + STL,转起语言来几乎完全没有压力

C++语言基础

对于初学者而言,我们只需要记住如下代码

#include<bits/stdc++.h>usingnamespace std;intmain(void){return0;}

初看这个和C语言极为相似除了using namespace std;和#include <bits/stdc++.h>
对于using namespace std;我们只需要记住不需要了解,如果有人想了解的话可以去搜下C++的命名空间

然后对于#include <bits/stdc++.h>是C++的万能头(竞赛专用,你下的gcc里面是没有这个的,需要额外配置),后续内容中如果学习C++只为了打算法竞赛,那么后续所有头文件都不需要记忆

C++如何输入输出

#include<iostream>#include<string>usingnamespace std;intmain(void){int n; string s; cin >> n; cin >> s; cout << n <<"\n"<< s << endl;}

上述头文件的iostream就相当于C的stdio.h,而string是C++特有的字符串对象
其中C输入为scanf而且还需要记住类似于%d,%s之类的格式化符号,而C++之间cin就可以了,输出的话直接cout

C++string相关

对于C语言我们处理字符串很痛苦(虽然C++也很痛苦),但C++处理字符串却比C语言简单多了

以下列举一些本人常用的字符串处理方法

去除前导空格

#include<iostream>#include<string>usingnamespace std;intmain(void){ string s;while(getline(cin , s)){int pos = s.find_first_not_of(" "); s.erase(0, pos); std::cout << s <<"\n";} std::cout <<"hello , world";}

提示:C++的cin会自动去除掉前导空格
如果是去除前导0的话直接把" "换成"0"就可以了

提取和拼接子串

#include<iostream>#include<string>usingnamespace std;intmain(void){ string s ="hello , world";//从第0个位置开始截取长度为5的子串 string s1 = s.substr(0,5);//从第6个位置开始截取后面的所有字符 string s2 = s.substr(6);//将s1和s2拼接位一个字符串 string s3 = s1 + s2;//运行下二者输出的结果相同 cout << s1 << s2 <<"\n"; cout << s3;}

string截取子串的成员函数为substr相关解释已经在注释当中

一些常用的C++操作

C++sort(排序函数的用法)

#include<algorithm>#include<iostream>#include<string>usingnamespace std;boolcomp(int& a ,int& b){return a > b;}intmain(void){int a[1000]={0,1,1,4,5,1,4};//这个sort第一个参数是这是你要排序的起始位置,第二个参数是终止位置sort(a +1, a +1+6);for(int i =1; i <=6; i++) cout << a[i];//C++排序默认的升序 std::cout <<"\n";//如果我们要用降序的话可以添加第三个参数,也就是我们的自定义比较函数sort(a +1, a +1+6, comp);for(int i =1; i <=6; i++) cout << a[i];}

C++的sort排序的时间复杂度是O(nlogn)比大家常用的冒泡排序快速多了,所有如果要有排序的话推荐一直用这个,至于comp函数,我这里使用了&也就是引用,这样可以避免复制数值,但是大家在平时使用时不添加引用符也可以正常运行

数组去重

#include<algorithm>#include<iostream>#include<string>#include<vector>usingnamespace std;intmain(void){//使用原始数组的方法//数组去重需要我们先排序int a[1000]={0,1,1,4,5,1,4};sort(a +1, a +1+6);//这里去重int* pos =unique(a +1, a +1+6);//这里计算去重后的数组个数int new_count = pos -(a +1);for(int i =1; i <= new_count; i++) std::cout << a[i]<<" ";}//如果不打算了解C++进阶相关,这下面部分可以不看#include<algorithm>#include<iostream>#include<vector>intmain(void){//使用vector(动态数组的做法)  std::vector<int>arr ={0,1,1,4,5,1,4};//这里至于为什么使用arr.begin(),这里暂不讲解,在进阶部分再讲解 std::sort(arr.begin()+1, arr.begin()+1+6);//这里返回的是一个迭代器auto pos =unique(arr.begin()+1, arr.begin()+1+6); arr.erase(pos , arr.end());return0;}

unique函数返回的是检查范围的数据,如果有相同的则移到传入的末尾,之后直接计算剩余元素数量后使用去重过后的数组就行了,详细操作见上述代码

二分查找

在这里插入图片描述
#include<algorithm>#include<iostream>#include<vector>#include<stack>#include<queue>#include<map>#include<set>usingnamespace std;intmain(void){//这里为了演示,我这边就直接用有序数组了int a[105];for(int i =1; i <=100; i++) a[i]= i;//查找第一个小于等于25的元素int* lb1 = std::lower_bound(a +1, a +101,25);int index1 = lb1 - a;// 计算索引 std::cout <<"elem is"<<*(lb1)<<" index is"<< index1 << endl;//查找第一个大于25的元素int* lb2 = std::upper_bound(a +1, a +101,25);int index2 = lb2 - a;// 计算索引 std::cout <<"elem is"<<*(lb2)<<" index is"<< index2 << endl;int* result = std::lower_bound(a +1, a +101,101);//二分超出范围的话if(result == a +101){ std::cout <<"lower_bound(101) return a+101\n";// 因为数组中没有不小于101的元素}return0;}

STL容器相关

常见的STL容器使用

这部分设计数据结构,例如:栈,队列,红黑树,二叉搜索树

常见队列

#include<algorithm>#include<iostream>#include<queue>#include<vector>intmain(void){ std::queue<int>q;//这里模拟插入数据for(int i =0; i <10; i++) q.push(i);//一般我们是不知道队列里面的元素个数的,所以我们一般用while语句来处理//这里的empty返回的是一个bool变量,如果不了可以理解为true = 1(判断为真),false = 0(判断为假)while(!q.empty()){//队列可以查看队头和队尾的元素//其中队头的元素是第一个被插入的元素 std::cout << q.front()<<" "<< q.back()<<"\n";//这里默认弹出队头元素 q.pop();}//双端队列和普通队列的区别就是可以弹出和插入元素到队头和队尾的任意一部分 std::deque<int>qu;for(int i =0; i <10; i++){ qu.push_back(i);//qu.push_front(i);}while(!qu.empty()){ std::cout << qu.front()<<" "<< qu.back()<<"\n";//弹出队尾 qu.pop_back();//弹出队首 qu.pop_front();}}

C++的队列使用和声明极为简单,其中内部实现为一个数组,是根据先进先出(FIFO)思想设计的,所有上述操作时间复杂度都为O(1)
如果使用了using namespace std;,那么上述的的"std::"可以去掉

#include<algorithm>#include<iostream>#include<vector>#include<stack>#include<queue>usingnamespace std;intmain(void){ stack<int>s;for(int i =0; i <10; i++) s.push(i);while(!s.empty()){//默认弹出最后一个元素 std::cout << s.top()<<" "; s.pop();}}

栈和队列的使用方式差不多,最具有分辨力的区别是:栈是根据先进后出(FILO)的思想设计的

map(键值对)

键值对又称字典,是一个相互进行映射(一个键对应一个值)的STL容器,内部实现为红黑树或(二叉搜索树),其插入的时间复杂度为O(logn)是一个在算法竞赛中很实用的STL容器

#include<algorithm>#include<iostream>#include<vector>#include<stack>#include<queue>#include<map>usingnamespace std;intmain(void){ std::map<int,int>mp;int temp =114514;for(int i =0; i <10; i++){//插入数据(这两种方法都可以)if(i <4) mp[i]= temp *(10- i);else mp.insert({i , temp *(10- i)});}//遍历mapfor(auto&[key , value]: mp){//这里的key代表第一个也就是键,第二个代表值,这两个可以随意命名 std::cout <<"mp["<< key <<"] = "<< value <<"\n";//遍历是根据键的大小来输出的,也可以自定义排序(属于进阶内容,新手不必要掌握)}//查找操作,其中时间复杂度为O(logn)if(mp.find(2)!= mp.end()) std::cout <<"Yes";if(mp.find(10)== mp.end()) std::cout <<"No"; std::cout <<"\n";int idx =0;while(1){ mp.erase(idx); idx++;if(mp.empty()){ std::cout <<"已弹出所有元素";break;}}return0;}

我们这里只讲map的插入,删除和遍历以及查找这种基础内容

还有一种map是unordered_map,其结构和map很像,这里不再介绍。
unordered_map和map的区别是,map是红黑树,而它的实现为哈希表,查找,插入的速度为O(1),并且unordered_map是无序的

set(集合)

set和map极为相似,你可以把set理解为只有一个value的的map(一般map有键和值),其中时间复杂度和map基本一致,这里不再介绍

#include<algorithm>#include<iostream>#include<vector>#include<stack>#include<queue>#include<map>#include<set>usingnamespace std;intmain(void){ set<int>s;for(int i =0; i <100; i++) s.insert(0); s.insert(5); s.insert(3); s.insert(114514);//set里面是自动有序而且是会自动去重的for(auto i : s) cout << i <<" "; cout <<"\n";if(s.find(3)!= s.end()) cout <<"Yes"<<" ";if(s.find(6)== s.end()) cout <<"No"<<" "; cout <<"\n";//查看集合的大小 cout << s.size()<<"\n";for(auto i : s) s.erase(i); cout << s.size()<<"\n";return0;}

C++进阶相关

标准输入输出加快

 ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);

lambda表达式(无名函数)

 std::vector<int>arr ={1,1,4,5,1,4}; std::sort(arr.begin(), arr.end(),[](int& a ,int& b){return a > b;});

这里只不过是将函数换成了lambda表达式

优先对列自定义排序

structNode{int x , y;booloperator<(Node &a)const{return x < a.x;};};intmain(void){ std::priority_queue<Node>q;}

对于我们自定义的结构体它是无法直接比较大小的,那么直接使用operator进行重载,可以使它们在一个陌生的结构体有明确的大小顺序
由于作者赖的写了,这里简单的介绍下优先队列。优先队列就是我们所说的堆,其中内部是二叉搜索树,插入和弹出都是logn的复杂度,堆顶元素默认是最大(最小)元素

stringstream流

#include<vector>#include<string>#include<sstream>#include<iostream>usingnamespace std;intmain(void){//将字符类型转化为整数 std::string s ="1 2 3 4 5 6"; std::vector<int>arr; stringstream stream(s);int num;while(stream >> num){ arr.push_back(num);}for(auto i : arr) cout << i <<" "; cout <<"\n";//将数据为某个字符串分割 string data ="apple,banana,orange,grape"; stringstream ss(data); string fruit;while(getline(ss, fruit,',')) cout << fruit << endl;return0;}

结语

以上内容属于C++基础内容,如果以后有从事C++相关行业的话属于基础中的基础,相反则需要掌握一些C++基础内容,虽然文章中分为了基础和进阶,但即便是只打算打一些简单的算法比赛,以上编码技巧也只属于基础内容

Read more

2025最新【Digital Micrograph】下载安装完整教程(超详细全流程)

文章目录 * Digital Micrograph下载 * Digital Micrograph安装步骤 * 步骤1:安装前准备工作 * 步骤2:解压并安装许可证 * 步骤3:完成许可证安装 * 步骤4:安装主程序 * 步骤5:按照向导完成安装 * 步骤6:完成安装并启动软件 * Digital Micrograph常见问题解答 * 为什么Digital Micrograph安装后无法启动? * Digital Micrograph与其他TEM分析软件的区别 本篇文章为你提供详细的Digital Micrograph软件安装教程,从下载到安装成功的全部流程一步到位。特别适合TEM(透射电镜)用户和材料科学研究人员,这份Digital Micrograph安装教程将帮你快速上手这款专业软件。 Digital Micrograph下载 https://pan.quark.cn/s/0ee93493dc7c Digital Micrograph安装步骤 步骤1:安装前准备工作 首先关闭电脑上的杀毒软件,这一点非常重要

By Ne0inhk
从DeepSeek-R1爆火看开源大模型推理优化:我在脉脉找到的实战方案

从DeepSeek-R1爆火看开源大模型推理优化:我在脉脉找到的实战方案

🎁个人主页:User_芊芊君子 🎉欢迎大家点赞👍评论📝收藏⭐文章 🔍系列专栏:AI 文章目录: * 【前言】 * 一、场景痛点直击:两个行业的共性困境与差异化难题 * 1. 电商智能客服场景(日均请求10万+) * 2. 金融智能咨询场景(日均请求3万+) * 二、实战突破:分场景落地优化方案(附完整代码+流程图) * 1. 核心优化架构总览(流程图) * 2. 分场景核心代码实现(新增4个关键代码片段) * (1)量化分级实现(适配金融场景精度需求) * (2)多租户隔离与共享实例实现(适配电商、金融双场景) * (3)边缘节点轻量化部署代码(适配电商峰值卸载) * (4)动态批处理与负载调度优化(核心优化代码) * 3. 优化效果对比表(分场景) * 三、脉向AI核心价值:技术人破圈的“

By Ne0inhk

Stable-Diffusion-v1-5-archive创意设计师指南:将SD1.5嵌入Figma/PS工作流

Stable-Diffusion-v1.5-archive创意设计师指南:将SD1.5嵌入Figma/PS工作流 你是不是也遇到过这种情况?在Figma里画了半天,总觉得缺一张完美的背景图;在PS里修图,想找个合适的素材却要翻遍图库。灵感来了,但手头的素材库却跟不上。 今天,我们来聊聊一个能彻底改变你工作流的“创意外挂”——Stable Diffusion v1.5 Archive。它不是要取代你的设计软件,而是要成为你最得力的“素材生成器”和“灵感加速器”。想象一下,在Figma里画个草图,就能立刻生成一张风格匹配的渲染图;在PS里想换个背景,输入一句话就能得到。这不再是科幻,而是可以立刻上手的现实。 这篇文章,就是为你——创意设计师、UI/UX设计师、视觉艺术家——量身定制的实战指南。我们不谈复杂的算法,只聚焦一件事:如何把SD1.5这个强大的文生图模型,无缝嵌入到你熟悉的Figma或Photoshop工作流中,让它真正为你所用。 1. 为什么设计师需要关注SD1.5? 在开始动手之前,我们先搞清楚,

By Ne0inhk
MHT-MD761 与云影无人机的集成实操要点,硬件安装与接口对接

MHT-MD761 与云影无人机的集成实操要点,硬件安装与接口对接

MHT-MD761 与无人机的集成核心分为硬件安装和接口对接两部分,需严格遵循产品的安装规范和接口定义,才能保障惯导器件发挥最优性能,避免因安装偏差、接线错误导致的导航精度下降或设备故障,以下为具体的实操要点,均基于 MHT-MD761 官方安装规范和云影无人机的集成实际。 1. 硬件安装要点 (1)安装位置与坐标系匹配 MHT-MD761 的产品坐标系采用 “右 - 前 - 上” 坐标系,安装时需将器件的 X 轴与无人机的前进方向保持一致,Z 轴朝下,同时确保器件与无人机旋转中心的测量误差≤5cm,否则会因杆臂误差导致导航精度下降;安装位置应选择无人机机身振动较小、远离强磁部件的区域,如飞控模块附近,避免机身发动机、电机等强振动部件的振动传递,同时远离电池、金属支架等强磁部件,防止磁场干扰磁力计的测量精度。 (2)机械安装要求 安装面需保证平面度≤0.01mm、垂直度≤0.02mm、表面粗糙度≤0.8μm,通过

By Ne0inhk