一.初始C++

C++的历史

C++的起源可以追溯到1979年,当时Bjarne Stroustrup(本贾尼·斯特劳斯特卢普,这个翻译的名字不同的地⽅可能有差异)在贝尔实验室从事计算机科学和软件⼯程的研究⼯作。⾯对项⽬中复杂的软件开发任务,特别是模拟和操作系统的开发⼯作,他感受到了现有语⾔(如C语⾔)在表达能⼒、可维护性和可扩展性⽅⾯的不⾜。

1983年,Bjarne Stroustrup在C语⾔的基础上添加了⾯向对象编程的特性,设计出了C++语⾔的雏形, 此时的C++已经有了类、封装、继承等核⼼概念,为后来的⾯向对象编程奠定了基础。这⼀年该语⾔被 正式命名为C++。

这就是我们c++的本贾尼博士

C++在工业领域的应用

C++的应⽤领域服务器端、游戏(引擎)、机器学习引擎、⾳视频处理、嵌⼊式软件、电信设备、⾦融 应⽤、基础库、操作系统、编译器、基础架构、基础⼯具、硬件交互等很多⽅⾯都有。

1.大型系统软件开发:如编译器,数据库,操作系统等。

2.音视频处理:常见的音视频开源库和方案有FFmpeg,WebRTC,Mediasoup,ijkplayer,音视频开发用到的技术栈主要是C++

3.pc客户端开发:一般是开发Window上的桌面软件,比如WPS之类的,技术栈的话一般是C++QT,QT是一个跨平台的C++图形用户界面程序。

4.服务器开发:各种大型应用网络连接的高并发后台服务,C++主要用于一些性能要求比较高的地方,例如游戏服务,流媒体服务,量化高频交易服务等

5.游戏引擎开发。很多游戏的引擎开发都是用的c++,游戏开发要掌握c++基础和数据结构,学习图形化的知识,掌握游戏引擎和框架,了解引擎开发,引擎源代码可以学习UE4,Cocos2D-x等开源引擎开发

6.嵌入式开发:嵌入式把有计算能力的主控板嵌入到机器装置或电子装置内部,通过软件能够控制这些装置。比如:智能手环,摄像头,扫地机器人,智能音响,门禁系统,等。粗略一点  嵌入式开发主要分为嵌入式应用和嵌入式驱动开发

7.机器学习引擎。机器学习的底层都是C++来实现的,上层用python封装起来,如果你想做机器学习系统的开发需要学习c++/ 

二.学习c++

C++第一个程序

注:c++兼容大多数c语言中的语法

话不多说,我们开始第一个c++的小程序

#include<iostream>
using namespace std;
int main()
{
    cont<<"hello!world\n"<<endl;
    return 0;
}

哈哈我们每个学习都从这个hello!world开始,okok我们注意到这跟之前学的C语言上面有很多不一样的地方,没关系听我慢慢道来

C++的命名空间

欸,我们看上面程序这个using namespace std;这段代码啥意思?

这其实是我们c++区别c的地方了,我们在c语言中啊如果要写一个 大程序,用到的变量名那岂不是非常多,我们绞尽脑汁也有可能重复这个namespace这个关键字就是解决这样的一个问题

补充一点C++把这个域分为了四种---1.函数局部域(函数中定义的变量自己用) 2.全局域(定义在全局变量作用域整个程序) 3.命名空间域  4.类域

namespace的定义

这个关键字就是定义在全局的将变量放在这个域可以将域之间隔离开--这个域跟全局是相互独立的这样也就解决了命名的冲突

他的使用  --- namespace name  {} 在{}里面定义各个变量/函数/类型

在多个文件中定义同一个名字的域不会有冲突,会被当成一个域

C++标准库都放在一个叫std(standard)的命名空间里

namespace的使用

编译查找一个变量时默认只会在局部或者全局查找,不会主动到命名空间里去找,所以我们

命名空间中定义的函数有三种方式:

1.指定命名空间访问,项目中推荐使用

2.using将命名空间中某个成员展开,项目中经常访问的不存在冲突的变量

3.展开命名空间的所有成员,项目中不推荐,冲突图风险大

#include<stdio.h>
namespace bit
{
int a = 0;
int b = 1;
}
int main()
{
// 编译报错:error C2065: “a”: 未声明的标识符
printf("%d\n", a);
return 0;
}
// 指定命名空间访问
int main()
{
printf("%d\n", N::a);
return 0;
}
// using将命名空间中某个成员展开
using N::b;
int main()
{
printf("%d\n", N::a);
printf("%d\n", b);
return 0;
}
// 展开命名空间中全部成员
using namespce N;
int main()
{
printf("%d\n", a);
printf("%d\n", b);
return 0;
}

C++的输入和输出

<iostream>时Input Output Stream的缩写,是标准的输入,输出流图,定义了标准的输入,输出对象。

std::cin是istream类的对象,它主要面向窄字符的输入

std::out是ostream类的对象,他是面向窄字符的标准输出

std::endl是一个函数,流插入输出时,相当于插入一个换行符加刷新缓冲区。

<<是流输入运算符,>>是流输出运算符

使⽤C++输⼊输出更⽅便,不需要像printf/scanf输⼊输出时那样,需要⼿动指定格式,C++的输⼊ 输出可以⾃动识别变量类型(本质是通过函数重载实现的,这个以后会讲到),其实最重要的C++的流能更好的⽀持⾃定义类型对象的输⼊输出。

cout/cin/endl等都是属于C++标准库,C++标准库都放在一个叫std(standard)的命名空间中,所以通过命名空间使用方法使用它们

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
int main()
{
int a = 0;
double b = 0.1;
char c = 'x';
cout << a << " " << b << " " << c << endl;
std::cout << a << " " << b << " " << c << std::endl;
scanf("%d%lf", &a, &b);
printf("%d %lf\n", a, b);
// 可以⾃动识别变量的类型
cin >> a;
cin >> b >> c;
cout << a << endl;
cout << b << " " << c << endl;
return 0;
}
#include<iostream>
using namespace std;
int main()
{
    // 在io需求⽐较⾼的地⽅,如部分⼤量输⼊的竞赛题中,加上以下3⾏代码
    // 可以提⾼C++IO效率
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    return 0;
}

缺省参数

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时当没有传参时,函数就会用缺省值,传参了就用穿的参数值

全缺省就是全部形参给缺省值,半缺省就是在函数值从右往左依次给缺省值传参是从左往右,不能间接传参。

缺省参数声明和定义时    规定必须在声明时给缺省参数赋值定义不声明

#include <iostream>
#include <assert.h>
using namespace std;
void Func(int a = 0)
{
    cout << a << endl;
}
int main()
{
    Func(); // 没有传参时,使⽤参数的默认值
    Func(10); // 传参时,使⽤指定的实参
    return 0;
}
#include<iostream>
using namespace std;
//全缺省
void fun1(int a = 10,int b = 20, int c = 30)
{
    cont << a <<endl;
    cont << b << endl;
    cont << c << endl;
}
// 半缺省
void Func2(int a, int b = 10, int c = 20)
{
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << "c = " << c << endl << endl;
}
int main()
{
    Func1();
    Func1(1);
    Func1(1,2);
    Func1(1,2,3);
    Func2(100);
    Func2(100, 200);
    Func2(100, 200, 300);
    return 0;
}

函数重载

C++支持在同意作用域下有同名函数的出现(要求参数不同),可以时参数的数量,参数的类型,这样C++函数调用表现出多态行为,使用更加方便。仅返回类型不同,调用时不能无法区分   

#include<iostream>
using namespace std;
// 1、参数类型不同
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;
}
// 2、参数个数不同
void f()
{
    cout << "f()" << endl;
}
void f(int a)
{
    cout << "f(int a)" << endl;
}
// 3、参数类型顺序不同
void f(int a, char b)
{
    cout << "f(int a,char b)" << endl;
}
    void f(char b, int a)
{
    cout << "f(char b, int a)" << endl;
}
    // 返回值不同不能作为重载条件,因为调⽤时也⽆法区分
    //void fxx()
    //{}
    //
    //int fxx()
    //{
        // return 0;
    //}
    // 下⾯两个函数构成重载
    // f()但是调⽤时,会报错,存在歧义,编译器不知道调⽤谁
void f1()
{
    cout << "f()" << endl;
}
void f1(int a = 10)
{
    cout << "f(int a)" << endl;
}
int main()
{
    Add(10, 20);
    Add(10.1, 20.2);
    f();
    f(10);
    f(10, 'a');
    f('a', 10);
    return 0;
}

   

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐