深入计算机语言之C++:C到C++的过度-1

简介: 深入计算机语言之C++:C到C++的过度-1

一、什么是C++

C++(c plus plus)是一种计算机高级程序设计语言,由C语言扩展升级而产生 ,最早于1979年由本贾尼·斯特劳斯特卢普在AT&T贝尔工作室研发。


我们之前学习的C语言就是一种面向过程的语言,它强调事件的具体实现过程,一般以函数来具体实现。C++就是一门典型的面向对象的语言,它将问题分成多个对象,更强调对象与对象之间的联系。它完善了C语言的许多缺陷,并且引入了面向对象的程序设计思想,包括面向对象的四个特性:封装,继承,多态,抽象。  


无论是面向过程还是面向对象的语言,都有其优缺点:

面向过程 面向对象
优点 流程化分工明确,效率高 结构化更清晰,易维护
缺点 可维护性差,扩展能力差 开销大,性能低


二、C++的标准库

标准的 C++ 由三个重要部分组成:

  • 核心语言,提供了所有构件块,包括变量、数据类型和常量,等等。
  • C++ 标准库,提供了大量的函数,用于操作文件、字符串等。
  • 标准模板库(STL),提供了大量的方法,用于操作数据结构等。


这三个部分包含了C++这门语言的核心,我们后面的内容就主要围绕上面三个部分展开。


三、第一个C++程序

C++兼容C语言的大多数语法,所以C语言实现的 hello world 依旧可以运行,C++中需要把定义文件代码后缀改成.cpp,vs编译器看到是.cpp就会调用C++编译器,Linux下亚勇g++编译,不再是gcc。


当然C++有一套自己的输入输出,严格说C++版本的 hello world 应该是这么写:

// test.cpp 
// 这⾥的std cout等我们都看不懂,没关系,下⾯我们会依次讲解 
#include<iostream> 
using namespace std;
 
int main() 
{
    cout << "hello world\n" << endl;
 
    return 0;
}


四、命名空间

4.1 域作用限定符

作用域限定符:  " : ",其作用是通知编译器应从作用域限定符左侧的名字所示的作用域中寻找右侧那个名字,即指定访问哪个名字空间的哪个成员。当左侧为空时,默认访问的就是全局域。

#include<iostream>
 
int a = 1;
 
int main()
{
  int a = 0;
 
  printf("%d\n", a);
  printf("%d\n", ::a);
 
  return 0;
}


我们知道C语言遵循局部优先的规则,即当局部变量与全局变量冲突时,默认使用局部变量。而在C++中,我们可以通过域作用限定符来访问全局变量。

输出结果为:

0

1


4.2 为什么要存在命名空间

在C/C++中,变量、函数和后⾯要学到的类都是⼤量存在的,这些变量、函数和类的名称将都存在于全 局作⽤域中,可能会导致很多冲突。使⽤命名空间的⽬的是对标识符的名称进⾏本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。


c语⾔项⽬类似下⾯程序这样的命名冲突是普遍存在的问题,C++引⼊namespace就是为了更好的解决这样的问题

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


当我们定义rand变量时,就会与stdlib库中的rand函数出现命名冲突,这在C语言中只能通过修改变量名称来解决。但是在C++中,我们可以就可以使用命名空间来解决。


4.3 命名空间的定义

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。


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


4.3.1 正常的命名空间定义

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

#include<iostream>
#include<stdlib.h>
namespace ake
{
  int rand = 1;
}
int main()
{
  printf("%d\n", ake::rand);
  //使用域作用限定符,指定作用域
  return 0;
}


输出结果为 :1

4.3.2 命名空间的嵌套定义

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

#include<iostream>
using namespace std;
namespace ake1
{
  int a = 1;
  namespace ake2//嵌套
  {
    int Add(int a, int b)
    {
      return a + b;
    }
  }
}
int main()
{
  cout << ake1::a << endl;
  //访问通过限定符依次访问
  cout << ake1::ake2::Add(1, 1) << endl;
  return 0;
}


4.3.3 多文件中同名定义合并

在同一个工程中(可以是同一个工程下的不同文件),我们可以定义多个名称相同的命名空间,在编译时命名空间会自动合并,认为是⼀个namespace,不会冲突。

namespace ake
{
  int a = 1;
}
namespace ake
{
  int b = 1;
}
//编译时会自动合并


4.4 命名空间的使用

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


4.4.1 指定命名空间访问

这我们在前面已经实验演示过,现在我们来演示一下访问C++标准命名空间。(cout,endl等常用函数都被定义在C++标准命名空间std中)。

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

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

4.4.2 using 部分展开

在我们书写代码时,可能会频繁调用某个函数,这是我们可以使用using部分展开,来简化代码。使用方式为using 命名空间名称:: 成员。

#include<iostream>
#include<stdlib.h>
namespace ake
{
  int a = 1;
    int b = 2;
}
 
using ask::a;
 
int main()
{
  printf("%d\n", a);
    printf("%d\n", a);
    printf("%d\n", a);
    printf("%d\n", a);
    printf("%d\n", ake::b);
  
  return 0;
}

项⽬中经常访问的不存在冲突的成员推荐这种⽅式

4.4.3 using namespace 全部展开

除了部分展开,自然也有全局展开。其格式为using namespace 命名空间名

#include<iostream>
#include<stdlib.h>
namespace ake
{
  int a = 1;
    int b = 2;
}
 
using namespace ask;
 
int main()
{
  printf("%d\n", a);
    printf("%d\n", b);
  
  return 0;
}

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

五、C++的输入和输出

C++的标准输入与输出函数是cin与cout,分别对应C语言的printf与scanf。但是相较于C语言,C++输入输出并不需要指定占位符,如:%d,%c等,输出可以⾃动识别变量类型

#include<iostream>
using namespace std;//展开命名空间
int main()
{
  cout << "hello world" << endl;
  //endl相当于换行符
  cout << "hello world" << '\n';
  cout << 'a' << endl;
  int b = 1;
  cout << b << endl;
  cout << &b << endl;
  return 0;
}


注:在C++中使用 cin 与 cout 以及 endl 都属于C++标准库,需要包含头文件iostream以及std标准命名空间。

六、缺省参数

6.1 缺省参数的使用

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参缺省值,否则使用指定的实参。

void func(int a = 0)
{
  cout << a << endl;
}
int main()
{
  func();  // 没有传参时,使用参数的默认值,输出0
  func(1); // 传参时,使用指定的实参,输出1
  return 0;
}


运行结果:

0

1

6.2 缺省参数的分类

根据其缺省参数的个数,我们我可以将缺省参数分为全缺省半缺省。

6.2.1 全缺省

每一个参数都有缺省值。

#include<iostream>
using namespace std;
void func(int a = 0, int b = 1, int c = 2)
{
  cout << "a = " << a << endl;
  cout << "b = " << b << endl;
  cout << "c = " << c << endl << endl;;
}
int main()
{
  func();//不穿参数
  func(10, 20);//半传参数
  func(10, 20, 30);//全传
  return 0;
}
 

6.2.2 半缺省

只有一部分参数有缺省值,并且半缺省参数必须从右往左依次来给出,不能间隔着给。同时传参只能从左往右依次传参。

#include<iostream>
using namespace std;
void func(int a ,int b=1,int c=2)
{
  cout <<"a = " << a << endl;
  cout << "b = " << b << endl;
  cout << "c = " << c << endl;
}
int main()
{
 
  func(10,20);//半传参数
  cout << endl;
  func(10, 20, 30);//全传
  return 0;
}

5.2.3 注意

在使用缺省参数时,我们也要知道一些注意事项:

1. 传参时不能间隔传参

void func(int a ,int b=1,int c=2)
{
  cout <<"a = " << a << endl;
  cout << "b = " << b << endl;
  cout << "c = " << c << endl;
}
func(,10,20)//error


2. 缺省参数不能在函数的声明和定义同时出现

1. //test.h
2. void Func(int a = 10);//声明
3. // test.cpp
4. void Func(int a = 20)//定义
5. {}


深入计算机语言之C++:C到C++的过度-2

https://developer.aliyun.com/article/1624613

相关文章
|
2天前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1519 4
|
29天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
5天前
|
人工智能 Rust Java
10月更文挑战赛火热启动,坚持热爱坚持创作!
开发者社区10月更文挑战,寻找热爱技术内容创作的你,欢迎来创作!
502 19
|
2天前
|
存储 SQL 关系型数据库
彻底搞懂InnoDB的MVCC多版本并发控制
本文详细介绍了InnoDB存储引擎中的两种并发控制方法:MVCC(多版本并发控制)和LBCC(基于锁的并发控制)。MVCC通过记录版本信息和使用快照读取机制,实现了高并发下的读写操作,而LBCC则通过加锁机制控制并发访问。文章深入探讨了MVCC的工作原理,包括插入、删除、修改流程及查询过程中的快照读取机制。通过多个案例演示了不同隔离级别下MVCC的具体表现,并解释了事务ID的分配和管理方式。最后,对比了四种隔离级别的性能特点,帮助读者理解如何根据具体需求选择合适的隔离级别以优化数据库性能。
179 1
|
8天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
21天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
9天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
457 5
|
7天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
314 2
|
23天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
25天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2608 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析