前言

  1. C++是在C的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式等。
  2. C++兼容C的绝大多数语法。
  3. C++补充C语言语法的不足,比如:作用域方面、IO方面、函数方面、指针方面、宏方面等。

一、C++关键字

C++总计63个关键字,C语言32个关键字
在这里插入图片描述


二、命名空间

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

2.1 命名空间的定义

2.1.1 命名空间的一般定义

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

// zty是命名空间的名字,一般开发中是用项目名字做命名空间名。
// 1. 正常的命名空间定义
namespace zty
{
	// 命名空间中可以定义变量/函数/结构体
	int rand = 10;
	int Add(int left, int right)
	{
		return left + right;
	}
	struct Node
	{
		struct Node* next;
		int val;
	};
}
  • 不允许在局部空间中(函数内)定义命名空间,命名空间具有全局属性。
  • 在命名空间中只能进行定义操作,不能进行赋值加减调用函数等运算操作(初始化除外)。
  • 命名空间中可以定义变量、函数、类型等

2.1.2 命名空间支持嵌套定义

//2. 命名空间可以嵌套
// test.cpp
namespace N1
{
	int a;
	int b;
	int Add(int left, int right)
	{
		return left + right;
	}
	namespace N2
	{
		int b;//在N2命名空间中优先作用
		int c = a;//父空间中定义的变量(非同名变量)可以在子空间中直接作用
		int d;
		int Sub(int left, int right)
		{
			return left - right;
		}
	}
	//int e = d;//编译出错,子空间中定义的变量不能在父空间中直接作用
	int e = N2::d;//需要引用对应的命名空间
}
  • 对于嵌套定义的命名空间在使用时类似于使用嵌套定义的结构体,要层层向下调用:N1::N2::sub(10,5);
  • 之前学过的变量作用域在命名空间中同样适用:
    • 允许父子空间定义同名变量,变量在各自定义的空间中起作用。
    • 父空间中定义的变量(非同名变量)可以在子空间中直接作用,但子空间中定义的变量不能在父空间中直接作用。
    • 父空间使用子空间中定义的变量需要引用对应的命名空间,但可以不带父空间名。

2.1.3 同名命名空间

同一个工程中允许存在多个名称相同的命名空间,编译器最后会合并成同一个命名空间。

//3. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
// ps:一个工程中的test.h和上面test.cpp中两个N1会被合并成一个
// test.h
namespace N1
{
	int Mul(int left, int right)
	{
		return left * right;
	}
}
  • 该特性使C++像C语言一样,实现头文件,源文件分文件编写程序。
  • 可以将同一命名空间中的声明和定义分开来写,使得在定义变量及函数的过程中可以直接使用命名空间中的其他变量,无需提前声明或在其定义之后再定义新变量。

2.2 命名空间的使用

命名空间的使用有三种方式:

2.2.1 加命名空间名称及作用域限定符

int main()
{
	printf("%d\n", N::a);
	printf("%d\n", N::b);
	return 0;
}
  • 该方式只对当前变量的作用域有效
  • 冷知识:域名限定符前为空表示忽略局部优先,指定全局域变量。

2.2.2 使用using将命名空间中某个成员引入

using N::b;
int main()
{
	printf("%d\n", N::a);
	printf("%d\n", b);
	return 0;
}
  • using N::b;可以写在源文件的任意位置,函数内外、前后都可以。但一般写在文件头。
  • 引入后的成员从引入位置开始向下具有全局作用域,可以跨函数使用。

2.2.3 使用using namespace 将整个命名空间引入

using namespce N;
int main()
{
	printf("%d\n", a);
	printf("%d\n", b);
	Add(10, 20);
	return 0;
}
  • using namespce N;可以写在源文件的任意位置,函数内外、前后都可以。但一般写在文件头。
  • 引入后的命名空间从引入位置开始向下具有全局作用域,可以跨函数使用。
  • 将整个命名空间引入会使得命名隔离失效,慎用!

2.3 <iostream>头文件为什么没有.h后缀?

早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应头文件即可。而C++将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文件不带.h;旧编译器(vc 6.0)中还支持<iostream.h>格式,后续编译器已不支持,因此推荐使用+std的方式。

详细内容点这里>>>>【头文件有.h与没.h的区别】

2.4 如何使用命名空间更合理呢?

  • 在日常练习中,建议直接using namespace std即可,这样就很方便。
  • using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模大,就很容易出现。所以建议在项目开发中使用std::cout使用时指定命名空间成员,或者使用using std::cout展开常用的库对象/类型等方式。
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐