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

     时隔三月,继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++入门第二课。

 

  • 24
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贰月磐石

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值