C++:入门基础

目录

C++版本

C++参考文档

C++输入输出

C++对比C

命名空间

相较C语言它存在的意义

命名空间的使用

缺省参数

全缺省

半缺省

函数重载

引用

注意事项

引用和指针的关系(区别)

inline

 为什么要有inline?

注意事项

nullptr


C++版本

时间阶段内容
1998年C++98C++官方第一个版本,绝大多数编译器都支持,得到了国际标准化组织(ISO)和协会认可,以模板方式重写C++标准库,引入了STL(标准模板库)
2003年C++03C++标准第二个版本,语言特性无大改变,主要:修订错误、减少多异性
2011年C++11增加了许多特性,使得C++更像一种新语言,比如:正则表达式、基于范围for循环、auto关键字、新容器、列表初始化、标准线程库等
2014年C++14
C++11 的扩展,主要是修复 C++11 中漏洞以及改进,比如:泛型的 lambda
达式, auto 的返回值类型推导,二进制字面常量等
2017年C++17
C++11 上做了一些小幅改进,增加了 19 个新特性,比如: static_assert() 的文 本信息可选,Fold 表达式用于可变的模板, if switch 语句中的初始化器等
2020年C++20
C++11 以来最大的发行版 ,引入了许多新的特性,比如: 模块 (Modules) 、协 (Coroutines) 、范围 (Ranges) 、概念 (Constraints) 等重大特性,还有对已有特性的更新:比如Lambda 支持模板、范围 for 支持初始化等
2023年C++23C++23是一个小版本的更新,进一步完善和改进现有特性,增加了if consteval、falt_map,import std导入标准库等
2026年C++26制定ing

C++参考文档

Reference - C++ Reference (cplusplus.com)

C++ 参考手册 - cppreference.com

cppreference.com

第一个链接是个人比较喜欢使用的C++文档,因为它是以头文件形式呈现,所以它的内容相较后两个比较易懂,但它并不是官方文档,而且只更新到了C++11版本

第二个和第三个是C++官方文档,第二个是中文版的文档,第三个是英文版的文档,信息很全,但是相较第一个来说有点不易看

C++输入输出

C++对比C

来看看C语言和C++输入输出的区别

输入:

#include<stdio.h>int main()
{printf("hello world\n"); //C语言return 0;
}

#include<iostream>
using namespace std;int main()
{cout << "hello C++" << endl; //C++return 0;
}

输出:

#include<stdio.h>int main()
{int a = 0;scanf("%d", &a); //C语言printf("%d", a);return 0;
}

#include<iostream>
using namespace std;int main()
{int a = 0;cin >> a;cout << a << endl; //C++return 0;
}

我们可以看到C++包的头文件名字为 <iostream> ,该单词是Input Output Stream的缩写,是标准的输入、输出流库

using namespace是命名空间的语法,是在<iostream>文件中将std这个命名空间给展开的意思,关于命名空间的使用下面将叙述

cout是ostream类的对象,主要面向窄字符的标准输出流

cin是istream类的对象主要面向窄字符的标准输入流

endl是一个函数,相当于C语言在字符串里的\n的作用(换行)

<<是流插入运算符,>>是流提取运算符,当然也可以和C语言的运算符一样作为左右移位运算符

命名空间

相较C语言它存在的意义

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

在C语言中这样定义一个rand全局变量看起来没什么问题,但真正编译的时候就会发现编译不过去,理由如下

 这说明了rand是一个函数,那它在哪呢?

它就在我们包的stdlib.h头文件里,当预处理完头文件展开后就会存在一个rand的函数,这时候就会出现两个rand从而无法编译通过,但去掉stdlib.h的时候就可以编译通过并运行了

若是在多人协同的一个项目当中,每个人都有自己的命名风格,当每个人做的部分最终合起来的时候,万一命名重复就会变得很麻烦,所以C++之父本贾尼博士就解决了这个问题

命名空间的使用

在C++中发明了命名空间这个东西

#include<iostream>
using namespace std;namespace lyw
{int a = 10;
}int main()
{int a = 5;cout << a << endl;return 0;
}

我们用namespace关键字创建了一个名为lyw的命名空间,这个命名空间里可以存储变量,函数,结构体等,这样就算名字相同也不会冲突

我们只需小小的修改就能访问到lyw命名空间里的a变量

cout << lyw::a << endl;

在前面输入输出的演示中,使用了标准输入、输出流库,并还使用了命名空间

#include<iostream>
using namespace std;

std就类似于上面lyw的一个命名空间,它封装着一些类,其中就包括cout,endl、cin,所以我们为了使用它我们就要访问到命名空间中

所以我们可以这样写

#include<iostream>int main()
{std::cout << "hello C++" << std::endl;return 0;
}

所以using namespace的作用是将std这个命名空间展开,将它变成全局变量类似的效果,这样我们就能正常使用了,这种做法只推荐在几十行的那种小项目中进行,代码量大不推荐

如果我们需要多次使用cout、endl和cin但又不想将std展开,我们也可以这样

#include<iostream>
using std::cout;
using std::endl;int main()
{cout << "hello C++" << endl;return 0;
}

只单独展开了cout和endl,就可以正常使用了 

缺省参数

缺省参数就类似于我们给函数参数赋一个默认值,若我们有给函数传参,那么函数会使用我们传递的数值 ,但若没有传参则使用函数的默认值

全缺省

全缺省就是函数的所有参数都赋一个初始值

具体实例如下:

#include<iostream>
using namespace std;void func(int a = 6)
{cout << a << endl;
}int main()
{func(7);return 0;
}

若没有传参

func();

半缺省

我们还可以半缺省

半缺省就是函数的部分参数具有初始值

但是它只能从右往左缺省(别问为什么,问就是C++之父规定的)

#include<iostream>
using namespace std;void func(int a, int b, int c = 2, int d = 3)
{cout << a << endl;cout << b << endl;cout << c << endl;cout << d << endl;
}int main()
{func(9, 8, 7);return 0;
}

函数重载

C++支持在同一作用域中出现同名函数,但是要求形参不同,可以是参数个数不同或者类型不同,在C语言中是不支持同名函数的

#include<iostream>
using namespace std;int Add(int a, int b)
{return a + b;
}double Add(double a, double b)
{return a + b;
}int main()
{cout << Add(1, 2) << endl;cout << Add(1.1, 2.2) << endl;return 0;
}

注:返回值不同并不能作为函数重载的一个条件

函数重载这里是有坑的,如下:

#include<iostream>
using namespace std;void func()
{cout << "func()" << endl;
}void func(int a = 1)
{cout << "func(int a = 1)" << endl;
}int main()
{func();return 0;
}

这两个func是构成重载的,如果我们不调用func我们的编译就不会报错,但是如果我们调用func()的时候为什么会出错呢?

func()是可以对于上面两个函数来说都是可以调用的,如果我们去掉这两个函数任意一个,都能运行成功,但是如果有两个它都能调用,编译器怎么知道我们要调用的是哪个func呢?

引用

引用是给一个变量起一个别名,而不是定义一个新的变量,编译器不会为引用变量开辟内存空间,它和它引用的变量共用一块空间

它的使用方法是在类型后面加上一个&符号,像定义一个变量类似的方法给其他变量起一个别名

#include<iostream>
using namespace std;int main()
{int a = 1;int& b = a;cout << a << endl;cout << b << endl;return 0;
}

再来看看地址

我们通过上图的调试界面可以看出

在取a和b的地址的时候它们的地址是相同的,说明它们是同一个“人”

注意事项

定义时必须初始化

int& b; // 错误写法,没有对这个别名初始化

一个变量能有多个引用,甚至可以引用别名

#include<iostream>
using namespace std;int main()
{int a = 66;int& b = a;int& c = a;int& d = c;cout << a << endl;cout << b << endl;cout << c << endl;cout << d << endl;return 0;
}

 

引用一旦引用一个实体,就不能再引用其他的实体

#include<iostream>
using namespace std;int main()
{int a = 66;int& b = a;int tmp = 55;b = tmp;cout << a << endl;cout << b << endl;return 0;
}

 

这里并不是b引用了tmp,而是tmp的值赋给了别名b,所以a也被影响了

权限放大问题

#include<iostream>
using namespace std;int main()
{const int a = 22;int& b = a;return 0;
}

 

上图的a是被const修饰的,只可读不可写,没有const限制的b自然也无法变成a的别名,因为b是可读可写,如果可以引用的话那a的权限就相当于被b放大了,这是不被允许的

const int& b = a;

当然改成这样就可以了

权限放大不行权限缩小是可以的,例如: 

#include<iostream>
using namespace std;int main()
{int b = 20;const int& rb = b;return 0;
}

不能引用常量

#include<iostream>
using namespace std;int main()
{int& a = 5;return 0;
}

 

也不能是这样

#include<iostream>
using namespace std;int main()
{int x = 2, y = 3;int& a = x + y;return 0;
}

 

一样的结果

引用和指针的关系(区别)

我们知道C++是在C的基础上诞生的,引用的出现自然解决了很多使用指针比较麻烦的场景,指针对大多数人来说是比较难写的一块知识

引用的底层是指针

但引用并不能代替指针,它们的功能有重叠,但它们也可以是相辅相成的关系

1. 在语法概念上引用是一个变量的别名,不开空间。而指针是存储一个变量的地址,要开空间

2. 引用必须初始化,指针是建议初始化,不是必须的

3. 引用初始化之后就不能再引用其他的对象,而指针可以不断改变指向

4. 引用可以直接访问指向对象,而指针需要解引用才能访问指向对象

5. sizeof中含义不同,引用的结果为引用类型的大小,而指针是地址空间所占字符数(32位平台下占4byte,64位平台下占8byte)

6. 指针比较出现空指针、野指针的问题,引用很少出现问题,相对安全

inline

用inline修饰的函数叫做内联函数,简单来说被inline修饰的函数像宏函数一样会被编译器展开,这样调用的函数就不需要再建立栈帧,提高效率

我们只需要将inline加在返回值类型的前面即可

#include<iostream>
using namespace std;inline int Add(int a, int b)
{return a + b;
}int main()
{int x = 3, y = 9;int ret = Add(x, y);cout << ret << endl;return 0;
}

 为什么要有inline?

众所周知,C语言中有一种东西叫做宏函数,例如:

#define Add(x, y) ((x) + (y))

这就是一个加法Add的宏函数

想更详细了解宏函数可以看看下面的博客

C语言:预处理详解-CSDN博客 

但是上面的宏函数写的就已经需要很多细节了,如果想写更复杂一些的宏函数那么就需要更多细节,很容易让人写出问题,写宏函数也是能提高效率

但我们写正常的函数就基本上很少出问题(相对来说),所以我们用了inline就可以像宏函数一样类似的效果展开代码,提高效率

C++设计inline的目的就是替代宏函数

注意事项

inline对于编译器来说只是一个建议,编译器并不一定要去执行,也就是说加了inline也并不一定会将函数展开

因为编译器不能随意的展开一段代码,假设我们的func函数有1000条代码来完成,但是我们在main函数或者其他地方调用了func函数100次,全部都展开的话就是1000*100的代码量,这样会使我们的内存负担极大,相反,不展开的话只需要一个个call func函数的地址即可

inline使用于频繁调用的短小函数(小于10行),对于递归函数,代码相对更多的就算加上inline也会被编译器忽略

vs编译器 debug版本下默认是不展开inline的,这样方便调试

inline不建议声明和定义分离,因为文件打开会导致地址不存在,从而导致链接错误

nullptr

nullptr:空指针

在以前的C语言中,使用空指针需要用到NULL宏,它是在头文件 stddef.h中定义的

#ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif
#endif

 这是条件编译的知识:

C语言:预处理详解-CSDN博客

可以从上面的代码浅浅的看出,如果是cpp,NULL被定义为了0,否则NULL被定义为了((void *)0)

这有什么问题呢?看看如下代码的结果是?

#include<iostream>
using namespace std;void func(int a)
{cout << "func(int a)" << endl;
}void func(int* a)
{cout << "func(int* a)" << endl;
}int main()
{func(NULL);return 0;
}

NULL不是应该是空指针的意思吗?结果没有调用int*的形参反而调用了int类型的形参,于程序的初衷相悖

说明在C++中的NULL定义是有问题的,为了解决这个问题,在C++11中诞生了nullptr

nullptr是一个特殊的关键字,它可以转换成任意其他类型的指针类型

使用nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被隐式类型转换为指针类型,而不能被转换成整数类型

#include<iostream>
using namespace std;void func(int a)
{cout << "func(int a)" << endl;
}void func(int* a)
{cout << "func(int* a)" << endl;
}int main()
{func(nullptr);return 0;
}


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

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

相关文章

今天小编强烈推荐几款国产APP!

AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/ 今天小编强烈推荐几款国产APP,算得上是国产之光。如果能帮助到大家&#xff0c;别忘了给小编点点赞加关注哟&#xff01;更多精彩还在后面。 一、…

新国立祭出视频生成“无限宝石“:2300帧仅需5分钟,提速100倍

天下武功唯快不破—— 火云邪神 前一段时间&#xff0c;想必大家都有被各种文生视频给刷屏&#xff0c;但当看完之后&#xff0c;不知道大家是否都有一种意犹未尽的感觉&#xff1a;“这也太短了吧&#xff0c;我还没看够呢”。受限于机器资源与生成效率&#xff0c;目前大部分…

WebRTC批量发送消息API接口的特性有哪些?

WebRTC批量发送消息api接口怎么样&#xff1f;接口性能怎么用&#xff1f; WebRTC技术允许浏览器和移动应用进行实时通信。通过WebRTC&#xff0c;开发者可以构建视频、语音、数据共享等应用。AokSend将重点探讨WebRTC批量发送消息API接口的特性。 WebRTC批量发送消息API接口…

关于前端数据库可视化库的选择,vue3+antd+g2plot录课计划

之前&#xff1a;antdv 现在&#xff1a;g2plot https://g2plot.antv.antgroup.com/manual/introduction 录课内容&#xff1a;快速入门 图表示例&#xff1a; 选择使用比较广泛的示例类型&#xff0c;录课顺序如下&#xff1a; 1、折线图2、面积图3、柱形图4、条形图5、饼…

W外链短网址平台怎么样?抖音/小红书/快手/微信卡片生成

在当今数字化时代&#xff0c;网址的便捷性和易记性对于用户体验和网站推广至关重要。短网址技术应运而生&#xff0c;以其简洁、易记、方便分享的特性&#xff0c;逐渐成为网站优化和推广的重要手段之一。其中&#xff0c;W外链作为一个功能全面的短网址服务平台&#xff0c;以…

一文彻底搞懂性能测试

性能测试概念 我们经常看到的性能测试概念&#xff0c;有人或称之为性能策略&#xff0c;或称之为性能方法&#xff0c;或称之为性能场景分类&#xff0c;大概可以看到性能测试、负载测试、压力测试、强度测试等一堆专有名词的解释。 针对这些概念&#xff0c;我不知道你看到的…

react 组件通信 —— 父子传值 【 函数式/类式 】

1、函数式组件通信 父子间通信 —— 父传子 父组件 export default function father() {return (<div style{{width:400px,height:200px,background:pink,marginLeft:500px}}>我是父组件<hr /><Son name{"韩小刀"}/></div>) } 子组件 ex…

刷代码随想录有感(131):动态规划——回文子串

题干&#xff1a; 代码&#xff1a; class Solution { public:int countSubstrings(string s) {vector<vector<bool>>dp(s.size(), vector<bool>(s.size(), false));int res 0;for(int i s.size() - 1; i > 0; i--){for(int j i; j < s.size(); j)…

[leetcode] shortest-subarray-with-sum-at-least-k 和至少为 K 的最短子数组

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int shortestSubarray(vector<int>& nums, int k) {int n nums.size();vector<long> preSumArr(n 1);for (int i 0; i < n; i) {preSumArr[i 1] preSumArr[i] nums[i];}int res n…

获取商铺信息,以及商铺信息的增删改查

本文章主要讲述如何对商铺信息进行基本的增删改查操作&#xff0c;及数据库对比。 1、获取首页仪表盘统计数据接口 待收费金额&#xff1a; SELECT count(1) as count,IFNULL(sum(total),0)as sum FROM payment_bill WHERE enabled_mark 1 AND pay_state0 欠费数据&#xf…

C++基础编程100题-021 OpenJudge-1.4-01 判断数正负

更多资源请关注纽扣编程微信公众号 http://noi.openjudge.cn/ch0104/01/ 描述 给定一个整数N&#xff0c;判断其正负。 输入 一个整数N(-109 < N < 109) 输出 如果N > 0, 输出positive; 如果N 0, 输出zero; 如果N < 0, 输出negative 样例输入 1样例输出…

【Neo4j】实战 (数据库技术丛书)学习笔记

Neo4j实战 (数据库技术丛书) 第1章演示了应用Neo4j作为图形数据库对改进性能和扩展性的可能性, 也讨论了对图形建模的数据如何正好适应于Neo4j数据模型,现在到了该动 手实践的时间了。第一章 概述 Neo4j将数据作为顶点和边存储(或者用Neo4j术语,节点和关系存 储)。用户被定…

Pytorch版本、安装和检验

基于conda包的环境创建、激活、管理与删除 CUDA版本 CUDA 是 NVIDIA 专为图形处理单元 (GPU) 上的通用计算开发的并行计算平台和编程模型&#xff0c;CUDA版本需满足对应的Pytorch要求 进入NVIDIA控制面板 进入左下角“系统信息”&#xff0c;找到组件 “NVIDIA CUDA 12.3.10…

DNS 杂谈

一、定义 DNS&#xff08;Domain Name System&#xff09;&#xff0c;域名系统&#xff0c;该系统记录域名和Ip地址的相互映射关系。用户访问互联网时&#xff0c;通过域名地址得到对应的IP地址&#xff0c;这个过程称为域名解析。DNS运行于UDP协议之上&#xff0c;使用的端口…

手撸俄罗斯方块(一)——简单介绍

手撸俄罗斯方块 简单介绍 《俄罗斯方块》&#xff08;俄语&#xff1a;Тетрис&#xff0c;英语&#xff1a;Tetris&#xff09;&#xff0c;是1980年末期至1990年代初期风靡全世界的电脑游戏&#xff0c;是落下型益智游戏的始祖&#xff0c;电子游戏领域的代表作之一&a…

【代码随想录】【算法训练营】【第64天】 [卡码117]软件构建 [卡码47]参加科学大会

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 卡码网。 day 64&#xff0c;周三&#xff0c;继续ding~ 题目详情 [卡码117] 软件构建 题目描述 卡码117 软件构建 解题思路 前提&#xff1a; 思路&#xff1a; 重点&#xff1a; 代码实现 C语言 [卡码…

算法的复杂度

文章目录 一、算法的效率1、复杂度的概念2、复杂度的重要性 二、时间复杂度三、空间复杂度四、大O的渐进表示发五、计算复杂度案例1、计算Func1函数的复杂度2、计算Fun2的时间复杂度3、计算Func3的时间复杂度4、计算Func4的时间复杂度5、计算strchr的时间复杂度6、计算Func5的时…

MySQL空间索引

空间类型是建立在空间类型字段上的。 空间类型 MySQL的空间类型很多&#xff0c;我就不逐一介绍了。重要分四大类&#xff1a; GeometryCurveSurfaceGeometryCollection 前三种&#xff0c;地理、曲线、曲面都是不可实例化的。Geometry有一个子类Point, Curve有一个直接子类L…

电脑误删除的文件怎么恢复免费 电脑误删文件导致无法开机怎么办

在使用电脑的时候&#xff0c;有时候可能会因为一些错误的操作&#xff0c;导致删除一些文件&#xff0c;如果是普通的文件&#xff0c;最坏的情况也就是文件找回来&#xff0c;如果删除的是系统文件&#xff0c;那么很有可能导致电脑开不了机。下面就给大家详细讲解&#xff0…

什么牌子充电宝好用?推荐四款质量与性价比双优充电宝!

在如今高度数字化的生活中&#xff0c;充电宝已经成为我们日常生活中必不可少的电子设备。然而&#xff0c;随着市场上充电宝品牌的不断增多&#xff0c;人们对充电宝的质量和安全性也越来越关注。充电宝作为一个涉及电池和充电技术的产品&#xff0c;安全性至关重要。选择一款…