admin管理员组

文章数量:1794759

【C++】踏上C++学习之旅(一):初识C++和命名空间

前言

本文是正式踏上C++学习之旅的第一篇文章,也是我分享C++笔记的第一篇文章。在这篇文章中,我会给大家介绍C++的发展历史,让大家更好从C语言过渡到C++,也会让大家认识到为什么C++能够兼容C语言的语法。

光是讲解C++的历史那可就太无趣了,所以在本文中我还会给大家加一点料 —— “命名空间”,以及如何高效的使用C++中命名空间。

还会教大家如何用C++的方式,输出"Hello World"。

1. 初识C++

C语言是结构化和模块化的语言,适合处理较小规模的程序。对于复杂的问题,规模较大的程序,需要高度的抽象和建模时,C语言则不合适。为了解决软件危机, 20世纪80年代, 计算机界提出了OOP(objectoriented programming:面向对象)思想,支持面向对象的程序设计语言应运而生。所以我们经常说到C++是面向对象的语言,而C语言是面向过程的语言。

1982年,Bjarne Stroustrup博士在C语言的基础上引入并扩充了面向对象的概念,发明了一种新的程序语言。为了表达该语言与C语言的渊源关系,命名为C++。因此:C++是基于C语言而产生的,它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行面向对象的程序设计。

请大家记住C++诞生的时间(1982年)以及发明C++的大佬 —— “本贾尼”!

2. C++的发展阶段

作为了解就好,但是也要知道我们现在是在用C++版本是多少。

阶段

内容

C with classes

类及派生类、公有和私有成员、类的构造和析构、友元、内联函数、赋值运算符重载等

C++1.0

添加虚函数概念,函数和运算符重载,引用、常量等

C++2.0

更加完善支持面向对象,新增保护成员、多重继承、对象的初始化、抽象类、静态成员以及const成员函数

C++3.0

进一步完善,引入模板,解决多重继承产生的二义性问题和相应构造和析构的处理

C++98

C++标准第一个版本,绝大多数编译器都支持,得到了国际标准化组织(ISO)和美国标准化协会认可,以模板方式重写C++标准库,引入了STL(标准模板库)

C++03

C++标准第二个版本,语言特性无大改变,主要:修订错误、减少多异性

C++05

C++标准委员会发布了一份计数报告(Technical Report,TR1),正式更名C++0x,即:计划在本世纪第一个10年的某个时间发布

C++11

增加了许多特性,使得C++更像一种新语言,比如:正则表达式、基于范围for循环、auto关键字、新容器、列表初始化、标准线程库等

C++14

对C++11的扩展,主要是修复C++11中漏洞以及改进,比如:泛型的lambda表达式,auto的返回值类型推导,二进制字面常量等

C++17

在C++11上做了一些小幅改进,增加了19个新特性,比如:static_assert()的文本信息可选,Fold表达式用于可变的模板,if和switch语句中的初始化器等

C++20

自C++11以来最大的发行版,引入了许多新的特性,比如:模块(Modules)、协程(Coroutines)、范围(Ranges)、概念(Constraints)等重大特性,还有对已有特性的更新:比如Lambda支持模板、范围for支持初始化等

C++23

明确的对象参数(Deducing this)、if consteval、多维下标运算符、内建衰减复制支持、标记不可达代码(std::unreachable)、平台无关的假设([[assume]])、命名通用字符转义、扩展基于范围的 for 循环中临时变量的生命周期、constexpr 增强、简化的隐式移动、静态运算符 static operator[] 以及类模板参数推导

C++还在不断地向后发展。但是现在公司主流的是用的还是C++98和C++11,等大家以后工作时可以慢慢钻研C++的新特性,现在这需要我们熟练的掌握C++98和C++11这两个标准即可。

我们现在学习阶段大都接触到的也就是这两种标准(C++11和C++98)。

2. 命名空间

2.1 为什么要有命名空间?

请大家看一下下面的代码:

代码语言:javascript代码运行次数:0运行复制
#include<stdio.h>

int rand = 0;
int main()
{
	int rand = 10;
	printf("%d\n",rand);
	return 0;
}

上面的代码会不会报错?相信掌握C语言语法的读者就会说,上面的代码是可以正常编译通过的。没错,上面的代码的确是没有任何问题的。

那如果我将上述的代码做了一点改变,代码还能正常编译过去吗?

代码语言:javascript代码运行次数:0运行复制
#include<stdio.h>
#include<stdlib.h>
int rand = 0;
int main()
{
	int rand = 10;
	printf("%d\n",rand);
	return 0;
}

如果你们自己去测试的话,显然会出现编译错误。

编译错误

这是什么原因呢? 编译器说rand重定义,而且错误是我们在引用stdlib.h的头文件之后才出现的。到这里我们就意识到了有个rand的变量名或者时函数名,而我们知道一个.c/.cpp的源文件在编译阶段的预处理阶段会把头文件的内容给展开,所以就会出现rand重定义了。

这个问题在C语言上只能是要你改变这个变量名了。C++就能够解决这个问题,即使你不更改变量名,编译器也不会报错,这个C++的利器就是命名空间

为了让大家对命名空间的这个新事物引起更高的重视,我来给大家举个生活中实际例子:

比如现在有一个互联网公司,这个公司最近准备研发一个项目,老板就把项目就分配给了一个小组,而小组里面有两人小明和小刚负责分别负责这个项目的两个模块。他们两个写啊写啊,终于有一天他们俩将各自写的项目都提交了上去,编译一下却出现错误,经过检查发现他们两个项目的变量名有很多是重叠了,这个会出现命名冲突的问题。如果他们是用C语言来写的话,那必定有一方得是改变变量命名,那两个人肯定都不愿意改的。如果用C++的命名空间的话,就可以完美避开这个问题了。

好了,在讲完命名空间的重要性之后,我们就得认识一下命名空间的用法以及底层的原理!

2.2 命名空间的语法

代码语言:javascript代码运行次数:0运行复制
namespace 命名空间名
{
	内容
}

下面我来一遍做展示,一遍拓展:

  1. 这个是我们进行正常的命名空间定义:
代码语言:javascript代码运行次数:0运行复制
namespace test
{
	int rand = 10;
	int Add(int x, int y)
	{
		return x+y;
	}

	struct Node
	{
		int data;
		struct Node* next;
	}
}

本文标签: C踏上C学习之旅(一)初识C和命名空间