重生之我要学C++第一课

news2024/11/27 12:53:45

     时隔三月,继C语言之后,博主学成C++归来,欲重开博客,与诸位分享经验,共同学习,今天就开始我们的c++第一课——入门篇。

    既然要开始学习c++,就要了解

    什么是c++:

    C 语言是结构化和模块化的语言,适合处理较小规模的程序。对于复杂的问题,规模较大的
程序,需要高度的抽象和建模时,C语言则不合适。为了解决软件危机, 20世纪80年代, 计算机
界提出了OOP(object oriented programming:面向对象)思想,支持面向对象的程序设计语言
应运而生。
    1982年,Bjarne Stroustrup博士在C语言的基础上引入并扩充了面向对象的概念,发明了一
种新的程序语言。为了表达该语言与C语言的渊源关系,命名为C++。因此:C++是基于C语言而
产生的,它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的
程序设计,还可以进行面向对象的程序设计

    c++的发展历史:

    1979年,贝尔实验室的本贾尼等人试图分析unix内核的时候,试图将内核模块化,于是C
语言的基础上进行扩展,增加了类的机制,完成了一个可以运行的预处理程序,称之为C with
classes

     关于更多的关于c++的历史,大家可以搜索贝尔实验室或者点击这个链接

      https://zhuanlan.zhihu.com/p/107360459

关于学习c++的重要性

下图数据来自 TIOBE 编程语言社区 2023 年6 月最新的排行榜,在 30 多年的发展中, C/C++ 几乎一
致稳居前 5

 可谓经典永不过时,排名不能说明那个语言好,那个不好,每门编程语言都有适应自己的应用场景。

c++在工作领域的应用

1. 操作系统以及大型系统软件开发
所有操作系统几乎都是C/C++写的,许多大型软件背后几乎都是C++写的,比如:
Photoshop、Offiffiffice、JVM(Java虚拟机)等,究其原因还是性能高,可以直接操控硬件。
2. 服务器端开发
后台开发:主要侧重于业务逻辑的处理,即对于前端请求后端给出对应的响应,现在主流采
用java,但内卷化比较严重,大厂可能会有C++后台开发,主要做一些基础组件,中间件、
缓存、分布式存储等。服务器端开发比后台开发跟广泛,包含后台开发,一般对实时性要求
比较高的,比如游戏服务器、流媒体服务器、网络通讯等都采用C++开发的。
3. 游戏开发
PC平台几乎所有的游戏都是C++写的,比如:魔兽世界、传奇、CS、跑跑卡丁车等,市面上
相当多的游戏引擎都是基于C++开发的,比如:Cocos2d、虚幻4、DirectX等。三维游戏领
域计算量非常庞大,底层的数学全都是矩阵变换,想要画面精美、内容丰富、游戏实时性
搞,这些高难度需求无疑只能选C++语言。比较知名厂商:腾讯、网易、完美世界、巨人网
络等。
4. 嵌入式和物联网领域
嵌入式:就是把具有计算能力的主控板嵌入到机器装置或者电子装置的内部,能够控制这些
装置。比如:智能手环、摄像头、扫地机器人、智能音响等。
谈到嵌入式开发,大家最能想到的就是单片机开发(即在8位、16位或者32位单片机产品或者
裸机上进行的开发),嵌入式开发除了单片机开发以外,还包含在soc片上、系统层面、驱动
层面以及应用、中间件层面的开发。
常见的岗位有:嵌入式开发工程师、驱动开发工程师、系统开发工程师、Linux开发工程
师、固件开发工程师等。
知名的一些厂商,比如:以华为、vivo、oppo、小米为代表的手机厂;以紫光展锐、乐鑫为
代表的芯片厂;以大疆、海康威视、大华、CVTE等具有自己终端业务厂商;以及海尔、海
信、格力等传统家电行业。
随着5G的普及,物联网(即万物互联,)也成为了一种新兴势力,比如:阿里lot、腾讯lot、京
东、百度、美团等都有硬件相关的事业部。
5. 数字图像处理
数字图像处理中涉及到大量数学矩阵方面的运算,对CPU算力要求比较高,主要的图像处理
算法库和开源库等都是C/C++写的,比如:OpenCV、OpenGL等,大名鼎鼎的Photoshop
就是C++写的。
6. 人工智能
一提到人工智能,大家首先想到的就是python,认为学习人工智能就要学习python,这个
是误区,python中库比较丰富,使用python可以快速搭建神经网络、填入参数导入数据就
可以开始训练模型了。但人工智能背后深度学习算法等核心还是用C++写的。
7. 分布式应用
近年来移动互联网的兴起,各应用数据量业务量不断攀升;后端架构要不断提高性能和并发
能力才能应对大信息时代的来临。在分布式领域,好些分布式框架、文件系统、中间组件等
都是C++开发的。对分布式计算影响极大的Hadoop生态的几个重量级组件:HDFS、
zookeeper、HBase等,也都是基于Google用C++实现的GFS、Chubby、BigTable。包括分
布式计算框架MapReduce也是Google先用C++实现了一套,之后才有开源的java版本。
除了上述领域外,在:科学计算、浏览器、流媒体开发、网络软件等都是C++比较适合的场景,
作为一名老牌语言的常青树,C++一直霸占编程语言前5名,肯定有其存在的价值。
所以各位同学了解到c嘎嘎的重要性了吗,开始真正的学习吧!!!

本节知识点安排目的

    
  C++是在C的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式 
等。熟悉C语言之后,对C++学习有一定的帮助,本章节主要目标: 
1. 补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的,比如:作用 
域方面、IO方面、函数方面、指针方面、宏方面等。 
2. 为后续类和对象学习打基础
 

    命名空间

c++的发明一开始其实是为了补C语言的坑,所以C语言的很多问题在这里都被解决了,比如大家看这个代码

 这是一个很简单的输出代码,我们定义了一个全局变量rand=0,且输出了它。

那么在这个代码的基础上进行一个小改动

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

    加了一个新的头文件,大家猜猜还可不可以运行输出

     

很遗憾,他报了一个错误,说rand重定义了 ,明明我们只定义了一个rand,这是C语言的经典问题,因为头文件stdlib.h里包含一个函数rand,编译器无法识别,判定为重定义,所以c++完美解决了这个问题,来看看c++是怎么解决的:

    C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决

命名空间定义

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}
中即为命名空间的成员。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
// sc是命名空间的名字,一般开发中是用项目名字做命名空间名。
// 我用的是sc,大家下去以后自己练习用自己名字缩写即可,如张三:zs
// 正常的命名空间定义
namespace sc
{

   int rand = 0;
}
//主函数
int main()
{
    printf("%d", rand);
    return 0;
}

这样就可以运行成功了,默认调用全局里的rand
那么我们怎么才能用我们自己命名空间里的rand呢,老规矩直接上代码看结果

 

 

两个rand位于不同的地址,用::来访问我们自己的命名空间区域
这就是c++解决命名冲突的方式
当然了命名空间里不局限于定义变量,像函数,类型都是可以直接定义的,只是使用上有些差异
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
namespace sc
{
    // 命名空间中可以定义变量/函数/类型
    int rand = 10;
    int Add(int left, int right)
    {
        return left + right;
    }
    //注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中命名空间使用

    //命名空间中成员该如何使用呢?比如:
    struct Node
    {
        struct Node* next;
        int val;
    };
}
int main()
{
    printf("%d\n", sc::rand);
    //::域作用限定符,用来访问我们自己命名空间里的变量
    printf("%d\n", sc::Add(1,2));
    //结构体的命名时::加的位置要注意
    struct sc::Node node;

    return 0;
}

想要调用自己命名区域里的函数等必须用名字加::,并且结构体的命名时::加的位置要注意!

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
namespace sc
{
    int Add(int left, int right)
    {
        return left + right;
    }
}
int Add(int left, int right)
{
    return left + right;
}
int main()
{
    printf("%d\n", sc::Add(1,2));
    printf("%d\n", Add(2,3));

    return 0;
}

在这段代码里,我们有两个Add函数,作用和名字均相同,但是我们不用顾及冲突的问题,这就是c++改良的第一点

运行截图:

有的同学认为每次都是用::这个符号太麻烦了,那么有没有什么方法可以直接用,有的

 using namespace sc

就是在命名空间后加上这句话,这句话的意思就是展开命名空间,use使用的意思,本质就是把命名空间展开了,不用再::就可以使用sc这个命名空间里的各种东西,就像是你拥有一个果园,平时只有拥有一把名字为::的药匙才能进入,现在在门口使用了万能钥匙,无限制就可以用,也不需要钥匙

当使用了这句话,首当其冲的就是一个问题,就是选择问题,什么意思呢

请看代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
namespace sc
{
    int Add(int left, int right)
    {
        return left + right;
    }
}
int Add(int left, int right)
{
    return left + right;
}
using namespace sc;
int main()
{
    printf("%d\n", Add(1, 2));
    printf("%d\n", Add(2, 3));
    printf("%d\n", Add(3, 4));
    printf("%d\n", Add(4, 5));
    printf("%d\n", Add(5, 6));
    return 0;
}

仔细阅读代码,这种情况下,你能准确分出我们调用的五个Add都是那个命名空间里的吗,计算机业分不清,所以在没有把握的情况下不要轻易展开命名区域,还是用::最为稳妥。

有完全展开,就有部分展开,在大多数c++从业的代码中,这种方式是最多的

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
namespace sc
{
    int rand = 0;
    int Add(int left, int right)
    {
        return left + right;
    }
}
//部分展开
using sc::Add;
int main()
{
    printf("%d\n", rand);
    printf("%d\n", Add(2, 3));
    return 0;
}

这就是部分展开,只展开的Add函数,但是rand并未展开,想要打印我们命名区域里的rand,依旧要用::。

命名空间的嵌套

命名空间可以套命名空间,无限套娃,上代码:

namespace sc
{
int a;
int b;
int Add(int left, int right)
 {
     return left + right;
 }
namespace sd
 {
     int c;
     int d;
     int Sub(int left, int right)
     {
         return left - right;
     }
 }
}

顾名思义就是在一个命名空间里再套用一个命名空间

使用方式:

也就是嵌套::的事,由图可见,图中三个rand都位于不同的地址,编译器也没有发现问题

 

c++标准输入输出流

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
int main()
{
    cout<<"hello world"<<endl;

    return 0;
}

这一串代码相信学过C语言的大家都有些似曾相识,没错,这就是c++输出hello world 的代码

根据我们对命名区域的讲解,其中std是c++标准库的命名空间,和C语言不同,c++的语句都位于命名空间中,所以我们想进行输入输出一定要using namespace std

说明:
1. 使用cout标准输出对象(控制台)cin标准输入对象(键盘)时,必须包含< iostream >头文件
以及按命名空间使用方法使用std。
2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含<
iostream >头文件中。
3. <<是流插入运算符,>>是流提取运算符
4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。
C++的输入输出可以自动识别变量类型。
5. 实际上cout和cin分别是ostream和istream类型的对象,>>和<<也涉及运算符重载等知识,
这些知识博主后续都会更新,所以我们这里只是简单学习他们的使用。

缺省参数

缺省参数的概念

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实
参则采用该形参的缺省值,否则使用指定的实参。
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
void Func(int a = 1)
{
	cout << a << endl;
}
int main()
{
	Func();     //没有传参时,使用参数的默认值
	Func(10);   //传参时,使用指定的实参
	return 0;
}

大家看这段代码,思考一下输出应该是什么?

运行截图:

 相信大家心中已经有了想法,我们在函数参数中定义一个a,在c++中可以给这个参数定义一个值,当主函数调用有实参传过来的时候,就用传过来的参数,如果没有传参,就用我们自己定义的数字,这个a就是缺省参数,是不是很好理解。

缺省参数分类

全缺省参数

顾名思义就是哈纳树中所有的形参都是缺省参数:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
void Func(int a = 10, int b = 20, int c = 30)
{
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl;
}
int main()
{
	Func();
	Func(1);
	Func(1,2);
	Func(1,2,3);

	return 0;
}

代码中所有的形参都是缺省参数,主函数中我们有四种玩法,传参个数从0到多,且看运行截图

通俗易懂,在此就不过多赘述。
 半缺省参数

也就是只有一部分参数是缺省参数

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
void Func(int a, int b = 10, int c = 20)
{
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl<<endl;
}
int main()
{
	Func(1);
	Func(1,2);
	Func(1,2,3);

	return 0;
}

如代码所示,函数的参数只有两个是缺省的,大家自己试试运行一下

注意事项:

1. 半缺省参数必须从右往左依次来给出,不能间隔着给
2. 缺省参数不能在函数声明和定义中同时出现
  //a.h
  void Func ( int a = 10 );
  // a.cpp
  void Func ( int a = 20 )
{}
  // 注意:如果声明与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那个缺省值。
3. 缺省值必须是常量或者全局变量
4. C语言不支持(编译器不支持)

 

函数重载

概念:

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这
些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型
不同的问题。也就是一个函数可以有多个意思
编程的学习最好方法就是直面代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
// 1、参数类型不同
//C语言不允许同名函数
//cpp可以,但是要求构成函数重载
//函数名相同,参数不同
int Add(int left, int right)
{
	cout << "int Add(int left, int right)" << endl;
	return left + right;
}
double Add(double left, double right)
{
	cout << "double Add(double left, double right)" << endl;
	return left + right;
}
int main()
{
	cout << Add(1, 2) << endl;
	cout << Add(1.2, 2.2) << endl;
	return 0;
}

look代码,仔细阅读不难发现我们定义了两个名字完全相同的函数,这在C语言中无疑是不允许的,但是在c++中完全可以,c++的特点是自动匹配函数,我们在主函数中两次调用Add函数,一个传参都是浮点数,一个都是整数,c++十分只能,它能自己分析你传参的类型选择对应的函数,所以两个参数不同,但是名字相同的函数在c++中被允许,这就是函数重载

运行截图:

怎么样,c++是不是比C语言简便只能多了,真是🐕都不用C语言(哈哈哈哈开玩笑啦)

返回值不同,不能构成重载!!!

本期的内容就到这里,下期博主给大家带来c++入门第二课。

 

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

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

相关文章

Vue2 ➔ Vue3 都做了哪些改变?

不是吧&#xff0c;兄弟&#xff0c;Vue3 都出来多久了&#xff0c;你还对这个感兴趣&#xff0c;说&#xff01;是不是没好好卷&#xff1f;&#x1f60f; 俺也一样 &#x1f602;&#xff0c;Vue3 出来之后只是简单了解了一下&#xff0c;然后还是转头一直在写 Vue2。当然&a…

如何升级iOS17/iPadOS17公测版?iOS17公测版升级教程

苹果官方发布了iOS 17/iPadOS 17系统首个公测版更新&#xff0c;其版本号及更新内容与iOS 17 beta 3一致&#xff0c;版本号为21A5277j。 对于想升级iOS 17/iPadOS 17 公测版的用户&#xff0c;可以参考本教程进行操作。 升级注意事项&#xff1a; 1. 为防止意外情况&#xf…

AlignPS中的TOIM损失

本文介绍了CVPR2021行人重识别领域中一篇名为AlignPS论文中的TOIM损失函数 论文链接&#xff1a;https://arxiv.org/abs/2109.00211 代码链接&#xff1a;GitHub - daodaofr/AlignPS: Code for CVPR 2021 paper: Anchor-Free Person Search TOIM TOIM Loss OIM Loss Trip…

【STM32零基础入门教程02】STM32环境获取及搭建

(14条消息) 【STM32零基础入门教程01】STM32入门基础知识_小超电子笔记的博客-CSDN博客 工欲善其事必先利其器&#xff0c;在上一章了解完STM32的一些基础知识之后&#xff0c;我们需要对使用的环境进行获取和安装。 一、MDK&#xff08;KEIL&#xff09;的获取 Keil是一种…

CCF 202209-2 何以包邮? (01背包动态规划练习)

一、先温习一下01背包问题 有N件物品和一个容量为V的背包。第i件物品的体积是c[i]&#xff0c;价值是w[i]。求解将哪些物品装入背包可使价值总和最大。 条件汇总 -------- 背包限制容量&#xff1a;Z 此时背包容量&#xff1a;C 物品&#xff1a;1 , i ... …

WSA - root,frida与ida测试

本文旨在配置windows subsystem for android(win安卓子系统)来作为win在开启了hyper-v的情况下的一种轻量的安卓模拟器方案。使用MagiskOnWsa设置root权限&#xff0c;最终使其正常与开发环境、frida、ida打通。 1. Root的WSA 常用的Wsa版本在目前是没有默认root的。在物理机…

matlab滤波器设计-IIR滤波器的设计与仿真

matlab滤波器设计-IIR滤波器的设计与仿真 1 引言 在现代通信系统中&#xff0c;由于信号中经常混有各种复杂成分&#xff0c;所以很多信号的处理和分析都是基于滤波器而进行的。但是&#xff0c;传统的数字滤波器的设计使用繁琐的公式计算&#xff0c;改变参数后需要重新计…

【Matlab】智能优化算法_猎豹优化算法CO)

【Matlab】智能优化算法_猎豹优化算法CO 1.背景介绍2.数学模型2.1 搜索策略2.2 坐等策略2.3 攻击策略2.4 假设 3.文件结构4.伪代码5.详细代码及注释5.1 CO.m5.2 CO_VectorBased.m5.3 Get_Functions_details.m 6.运行结果7.参考文献 1.背景介绍 猎豹&#xff08;Achinonyx jubat…

Kubernetes部署服务到集群中的指定节点

# kubectl get node NAME STATUS ROLES AGE VERSION k8s-master Ready master 25h v1.17.3 k8s-node2 Ready <none> 25h v1.17.3 集群只有两个节点&#xff0c;这里打算将应用部署在k8s-node2节点上&#xff0c;需要先记下这个节点的…

【3】Vite Vue3 用户、角色、岗位选择组件封装

在当今前端开发的领域里&#xff0c;快速、高效的项目构建工具以及使用最新技术栈是非常关键的。ViteVue3 组合为一体的项目实战示例专栏将带领你深入了解和掌握这一最新的前端开发工具和框架。 作为下一代前端构建工具&#xff0c;Vite 在开发中的启动速度和热重载方面具有突…

攻不下dfs不参加比赛(十三)

标题 为什么练dfs题目为什么练dfs 相信学过数据结构的朋友都知道dfs(深度优先搜索)是里面相当重要的一种搜索算法,可能直接说大家感受不到有条件的大家可以去看看一些算法比赛。这些比赛中每一届或多或少都会牵扯到dfs,可能提到dfs大家都知道但是我们为了避免眼高手低有的东…

24 - 数组和广义表 - 二维数组

前面我们学习了一维数组、今天来看看二维数组,比一维数组更加复杂! 数组的特点 存储的空间连续 存储类型相同 可以使用地址+偏移快速访问 二维数组定义 二维数组本质上是以数组作为数组元素的数组,即“数组的数组”,语法格式如下: 类型说明符 数组名[常量表达式][常量表达…

977.有序数组的平方

977.有序数组的平方 1.暴力排序 这道题最直观的方法在于&#xff0c;将数组中的每个数平方之后&#xff0c;排个序 public int[] sortedSquares(int[] nums) {int[]ans new int[nums.length];for(int i0;i<nums.length;i){ans[i] nums[i]*nums[i];} Arrays.sort(ans);ret…

人工智能LLM模型:奖励模型的训练、PPO 强化学习的训练、RLHF

人工智能LLM模型&#xff1a;奖励模型的训练、PPO 强化学习的训练 1.奖励模型的训练 1.1大语言模型中奖励模型的概念 在大语言模型完成 SFT 监督微调后&#xff0c;下一阶段是构建一个奖励模型来对问答对作出得分评价。奖励模型源于强化学习中的奖励函数&#xff0c;能对当前…

高通芯片android进入EDL模式 下载 热启动 串口指令

参考&#xff1a;高通方案的Android设备几种开机模式的进入与退出_edl模式怎么退出_Rookie20190715的博客-CSDN博客 切换为EDL模式 向串口发送 4b 65 01 00 54 0f 7e 或者adb reboot edl

Ceph的安装部署

文章目录 一、存储基础1.1 单机存储设备1.2 单机存储的问题1.3分布式存储&#xff08;软件定义的存储 SDS&#xff09; 二、Ceph 简介2.1 Ceph 优势2.2 Ceph 架构2.3 Ceph 核心组件2.4 Pool、PG 和 OSD 的关系&#xff1a;2.5 OSD 存储后端2.6 Ceph 数据的存储过程2.7 Ceph 版本…

PID控制系列--(1、最形象的PID)

目录 1、 比例控制系统的标准结构2、最简单的例子3、第二个例子4、积分控制器6、微分控制7 总结 今天 看到了B站上一个叫洋葱auto的UP主搬来的介绍PID控制的视频&#xff0c;感觉讲得形象易懂&#xff0c;为便于让和我一样看了无数文章还是不能很好理解PID控制本质的人共同分享…

2. DATASETS DATALOADERS

2. DATASETS & DATALOADERS PyTorch提供了两个数据基元&#xff1a;torch.utils.data.DataLoader和torch.uutils.data.data集&#xff0c;允许使用预加载的数据集以及自己的数据。数据集存储样本及其相应的标签&#xff0c;DataLoader在数据集周围包装了一个可迭代项&…

Sentinel整合OpenFegin

之前学习了openFeign的使用&#xff0c;我是超链接 现在学习通过Sentinel来进行整合OpenFegin。 引入OpenFegin 我们需要在当前的8084项目中引入对应的依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-sta…

网络套接字编程(一)(UDP)

gitee仓库&#xff1a;https://gitee.com/WangZihao64/linux/tree/master/chat_udp 预备知识 源IP地址和目的IP地址 它是用来标识网络中不同主机的地址。两台主机进行通信时&#xff0c;发送方需要知道自己往哪一台主机发送&#xff0c;这就需要知道接受方主机的的IP地址&am…