初始C++

简介: 初始C++

一、C++发展历史

       C++是一种广泛使用的高级编程语言,它由丹麦计算机科学家比雅尼·斯特劳斯特卢普(Bjarne Stroustrup)于1979年在AT&T贝尔实验室开始设计开发,并在1983年正式命名。

       C++的发展历程大致如下:

       1. 起源(1979年-1983年):斯特劳斯特卢普开始着手“C with Classes”的研发工作,旨在为C语言添加面向对象的特性。这门新语言保留了C语言的高效性和可移植性,同时引入了类、简单继承、内联机制、函数默认参数以及强类型检查等特性。

       2. 早期发展(1983年-1985年):1983年,“C with Classes”语言正式更名为C++。这一时期加入了许多重要特性,如虚函数、函数重载、引用机制(符号为&)、const关键字以及双斜线的单行注释(从BCPL语言引入)。

       3. 第一个版本发布(1985年):斯特劳斯特卢普的C++参考手册《C++ Programming Language》出版,同年C++的商业版本问世。由于当时C++没有正式的语言规范,这本书成为了业界的重要参考。

        4. 版本更新(1989年):引入了多重继承、保护成员以及静态成员等语言特性。

        5. 标准化(1998年):C++标准委员会发布了C++语言的第一个国际标准—ISO/IEC 14882:1998,即C++98。标准模板库(STL)也被纳入该标准。

        6. 修订与改进(2003年):针对C++98版本中的问题进行修订,发布了C++03。

        7. 新特性引入(2011年):新的C++标准C++11面世,Boost库对该版本影响很大,一些新模块直接衍生于Boost中的相应模块。C++11引入了众多新特性,包括正则表达式、完备的随机数生成函数库、新的时间相关函数、原子操作支持、标准线程库、一种新的for语法(能够和某些语言中的foreach语句达到相同效果)、auto关键字、新的容器类、更好的union支持、数组初始化列表的支持以及变参模板的支持等。

        8. 持续发展(2014年、2017年等):2014年发布了C++14标准,对C++11进行了一些小的改进和修复;2017年发布了C++17标准,引入了变量模板、文件系统库、并行算法等新特性。之后C++标准仍在不断更新和发展,以适应新的编程需求和技术趋势。 C++通过不断吸收新特性和改进,逐渐成为一种功能强大、灵活且高效的编程语言,被广泛应用于系统软件、游戏开发、嵌入式系统、大型数据库和交易系统等众多领域。

二、C++在⼯作领域中的应⽤

       C++在以下工作领域中有广泛的应用:

       1. 游戏开发:C++因其高效的性能和对硬件的直接控制能力,常用于开发大型游戏的核心引擎和关键模块。

       2. 操作系统开发:如 Windows、Linux 等操作系统的部分关键组件是用 C++编写的。

       3. 嵌入式系统:在诸如智能家居设备、汽车电子系统、工业控制系统等嵌入式领域,C++能够高效地利用有限的资源。

       4. 金融交易系统:需要处理大量数据和高并发交易,对性能要求极高,C++能够满足这种需求。

       5. 科学计算和数值分析:用于编写高性能的数值计算库和模拟软件。

       6. 图形图像处理:在图像和视频处理软件、计算机辅助设计(CAD)等领域,C++能够实现复杂的算法和高效的图形渲染。

       7. 网络编程:开发高性能的网络服务器和网络应用程序。

       8. 数据库系统:数据库的底层引擎和优化部分常使用 C++。

       9. 虚拟现实和增强现实:构建实时渲染和交互的系统。

       总之,在对性能、效率和资源控制要求较高的工作领域,C++都有着重要的地位。

三、参考文档

       Reference - C++ Reference

       cppreference.com

       说明:第⼀个链接不是C++官⽅⽂档,标准也只更新到C++11,但是以头⽂件形式呈现,内容⽐较易看好懂。后者是C++官网文档,信息很全,更新到了最新的C++标准,但是 相⽐第⼀个不那么易看。所以,我们可以结合使用。

四、C++程序

       C++语言是如何产生的?是咱们的祖师爷对于C语言的不满时所为做也。因此,C++兼容C语言。我们开始学C语言,我们启蒙代码为:

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

       在C++编译器中这个代码也可以运行。但,这毕竟不是正经的C++代码。就好比:普通话是我们的官方语言,但我说你们当地方言你肯定可以听明白。这毕竟不是官方的,我们肯定要明白官方的如何书写,代码如下:

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

       这里的代码看不明白,很正常,就好比你开始学C语言看不懂代码一样,跟着我学习脚本你肯定能看明白,接下来开始我们的学习吧!

五、命名空间

       1.什么是命名空间

               在C语言我们学习函数的时候,我们学习过生命周期这个概念。那么,什么是生命周期呢?生命周期通常指的是一个对象或变量从创建到销毁所经历的时间段。那么,命名空间是什么?咱们可以这样理解:在这个空间的生命周期内,对这个空间内的全部标识符起一个名字,可对其进行引用,可类似与C语言中的结构体。可用于解决以下情况:

#include<stdio.h>
#include<stdlib.h>//此处不包此头文件代码可正常运行,那该如何解决此处情况呢?
 
int main()
{
  int rand = 10;
  printf("%d\n", rand);//此处编译不通过原因为:在不包头文件前为变量,包含后为函数。
  return 0;
}

       解决方法如下:

#include<stdio.h>
#include<stdlib.h>
 
namespace example
{
  // 命名空间中可以定义变量/函数/类型
  int rand = 10;
}//注意:此处无;号
int main()
{
  printf("%d\n",example::rand );
  return 0;
}

               我们可用命名空间来解决此类问题。

       2.命名空间定义

               定义命名空间,需要使⽤到namespace关键字,后⾯跟命名空间的名字,然后接⼀对{}即可,{}中 即为命名空间的成员。命名空间中可以定义变量/函数/类型等。

                namespace本质是定义出⼀个域,这个域跟全局域各⾃独⽴,不同的域可以定义同名变量,所以下⾯的rand不在冲突了。

                C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找⼀个变量/函数/ 类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。局部域和全局域除了会影响 编译查找逻辑,还会影响变量的声明周期,命名空间域和类域不影响变量声明周期。

               namespace只能定义在全局,当然他还可以嵌套定义。

               项⽬⼯程中多⽂件中定义的同名namespace会认为是⼀个namespace,不会冲突。

               C++标准库都放在⼀个叫std(standard)的命名空间中。

       3.命名空间使⽤

               编译查找⼀个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间⾥⾯去查找。所以 下⾯程序会编译报错。所以我们要使⽤命名空间中定义的变量/函数,有三种⽅式:

                指定命名空间访问,项⽬中推荐这种⽅式。

                using将命名空间中某个成员展开,项⽬中经常访问的不存在冲突的成员推荐这种⽅式。

               展开命名空间中全部成员,项⽬不推荐,冲突⻛险很⼤,⽇常⼩练习程序为了⽅便推荐使⽤。

               对于第二种方式类似于C语言中头文件,在C语言进行编译时,编译器会把头文件里的东西拷贝过来。

六、C++输⼊&输出

       可参考以下代码:

#include<iostream>
using namespace std;
 
int main()
{
  int a = 1;
  double b = 0.1;
  char c = 'a';
  std::cout << a << " " << b << " " << c << endl;//可多个输出
  cout << a << " " << b << " " << c << endl;//此处可省略std原因为:std为全展开
  std::cin >> a;
  cin >> b >> c;//可多个输入
  cout << a << " " << b << " " << c << endl;
  return 0;
}

       • <iostream>是 Input Output Stream 的缩写,是标准的输⼊、输出流库,定义了标准的输⼊、输 出对象。

       • std::cin 是 istream 类的对象,它主要⾯向窄字符(narrow characters (of type char))的标准输 ⼊流。

       • std::cout 是 ostream 类的对象,它主要⾯向窄字符的标准输出流。

       • std::endl 是⼀个函数,流插⼊输出时,相当于插⼊⼀个换⾏字符加刷新缓冲区。

       • >是流提取运算符。(C语⾔还⽤这两个运算符做位运算左移/右移)

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

       • IO流涉及类和对象,运算符重载、继承等很多⾯向对象的知识,这些知识我们还没有讲解,所以这 ⾥我们只能简单认识⼀下C++ IO流的⽤法,后⾯我们会有专⻔的⼀个章节来细节IO流库。

       • cout/cin/endl等都属于C++标准库,C++标准库都放在⼀个叫std(standard)的命名空间中,所以要 通过命名空间的使⽤⽅式去⽤他们。

       • ⼀般⽇常练习中我们可以using namespace std,实际项⽬开发中不建议using namespace std。

七、缺省参数

       • 缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值。在调⽤该函数时,如果没有指定实参 则采⽤该形参的缺省值,否则使⽤指定的实参,缺省参数分为全缺省和半缺省参数。(有些地⽅把 缺省参数也叫默认参数)

       • 全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。C++规定半缺省参数必须从右往左 依次连续缺省,不能间隔跳跃给缺省值。

       • 带缺省参数的函数调⽤,C++规定必须从左到右依次给实参,不能跳跃给实参。

       • 函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省值。

       缺省参数可这样理解:你传参数时,这个函数有参数,不会使用这个函数本身的参数,使用你传来的参数;但当你传空参时,便会用函数本身参数。简单来讲便是:有的话,不考虑你;没有的话,便考虑你。(是不是像某个群体,这里希望各位不要成为缺省参数(手动[doge]))。

       可结合以下代码理解:

#include<iostream>
 
using namespace std;
 
void Func(int a = 0)
{
  cout << a << endl;
}
 
int main()
{
  Func();   // 没有传参时,使⽤参数的默认值
  Func(10); // 传参时,使⽤指定的实参
  return 0;
}
#include<iostream>
 
using namespace std;
 
// 全缺省
void Func1(int a = 10, int b = 20, int c = 30)
{
  cout << "a = " << a << endl;
  cout << "b = " << b << endl;
  cout << "c = " << c << endl << endl;
}
 
//半缺省
void Func2(int a, int b = 20, int c = 30)//此处缺省要连续,不可跳跃且要从右向左,不可从左向右
{
  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(); 此处参数不可传空,原因a未定义
  Func2(100);
  Func2(100, 200);
  Func2(100, 200, 300);
  return 0;
}

八、函数重载

       在C语言中,以加法函数为例,要是传参类型不同,我们就要对其进行重写一个函数且要用不同的函数名,是不是过于麻烦?这里简单说一下面向对象的三大特点之一——多态的思想来解决。

       C++⽀持在同⼀作⽤域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或者 类型不同。这样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 Func()
{
  cout << "Func()" << endl;
}
 
void Func(int a)
{
  cout << "Func(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 f()
//{
//  ;
//}
 
//int f()
//{
//  return 0;
//}
 
 
//以下两个函数虽然构成重载,但会有歧异,编译器无法明白调谁,无法运行
void f()
{
  cout << "f()" << endl;
}
 
void f(int a = 10)
{
  cout << "f(int a)" << endl;
}
 
int main()
{
  Add(10, 20);
  Add(10.1, 20.2);
 
  Func();
  Func(10);
 
  F(10, 'a');
  F('a', 10);
 
  return 0;
}

最后:

       今天的学习到这里就结束了,希望各位读者下去后能多练,不要因为简单从而对自己要求降低。


相关文章
|
6月前
|
算法 前端开发
3020. 子集中元素的最大数量
3020. 子集中元素的最大数量
36 0
|
6月前
|
算法
HashMap的默认初始长度是多少?为什么?
HashMap的默认初始长度是多少?为什么?
110 0
|
4月前
|
运维 安全 Serverless
函数计算产品使用问题之怎么调整单个服务下最大允许创建的函数个数
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
6月前
|
人工智能 分布式计算 Java
【c++】初始c++
【c++】初始c++
【c++】初始c++
|
JavaScript Python
从列表中或数组中随机抽取固定数量的元素组成新的数组或列表
从列表中或数组中随机抽取固定数量的元素组成新的数组或列表
63 0
|
算法 Python
通过初始时间和流逝的分钟数计算终止时间
通过初始时间和流逝的分钟数计算终止时间
99 0
|
Kubernetes pouch 开发者
K8S 初识_ K8S 初始总结 | 学习笔记
快速学习 K8S 初识_ K8S 初始总结
114 1
K8S 初识_ K8S 初始总结 | 学习笔记
|
存储 Java
HasMap初始容量设置
HasMap初始容量设置
102 0
|
机器学习/深度学习 人工智能 算法
【算法 | 实验8】分配最小页数(数组划分和最大值最小化问题)
【算法 | 实验8】分配最小页数(数组划分和最大值最小化问题)
280 0
【算法 | 实验8】分配最小页数(数组划分和最大值最小化问题)