C++入门基础:C++简介,命名空间
既然它们是不同的域,完全可以在各自其中定义相同名字的变量或函数或结构了。举个例子:代码语言:javascriptAI代码解释。
C++的标准化于1989年开始,当时成立了一个ANSI和ISO国际标准化组织的联合标准化委员会。1994年标准化委员会提出了C++标准化的第一个草案。不久,惠普实验室开发了一系列软件,统称为STL(Standard Template Library),联合标准化委员会投票通过了将STL包含在C++标准的提议。但STL对C++的扩展超出了C++最初定义标准范围,虽然在标准中加入STL是个重要的决定,但也因此延缓了C++的标准化进程。 直到1997年11月14日,联合标准化委员会通过了该标准的最终草案。1998年,C++的ANSI/ISO标准被投入使用。
而每隔几年,C++都会迎来一次版本更新,如1998年的C++98、2003年的C++03、2011年的C++11、2014年的C++14……目前2026年的C++26正在制定中。
一句话总结:C++是一门扩展了C语言的语言,它兼容C语言的大部分语法
2. C++参考文档
https://legacy.cplusplus.com/reference https://en.cppreference.com/w/ https://zh.cppreference.com/w/cpp 这三个网站是C++程序设计者最常用的C++参考文档。
第一个我们已经不陌生了,在C语言学习阶段经常去查询库函数:

在这里插入图片描述
然而它并不是C++的官方文档,是“民间大神”建设的科普性网站。在UI和用户访问方面相比官方文档改进了不少。缺点是它太久没有更新,内容很老甚至可能不是正确的了。
第二个网站就是C++的官方文档,是全英文的,也是最推荐大家学习的。第三个网站是官方文档的翻译版。我们鼓励大家还是阅读官方文档,因为作为程序员培养英文文档阅读能力还是很重要的,有一些知识与技术可能并没有汉化,要依靠自己去查询学习。

在这里插入图片描述

在这里插入图片描述
二、namespace命名空间
1. C语言的一个缺陷
还记得我们讲过:作用域是一个程序设计概念。通常来说,针对每一个变量,都有它的可用的范围,这就是作用域。C语言中我们只接触到了全局域、局部域,而在同一个域中不能出现相同名字的变量或函数或类型,否则会编译报错。在大型的项目中,可能要用到成千上万个函数,团队多人协作时经常会有起名冲突的问题,这是C语言无法解决的问题。
2. namespace
所以,C++克服了这一问题,提出了命名空间这一概念。定义命名空间,需要用关键字namespace,后面加自定义空间名字,接上一对{ },{ }中即为命名空间的成员,可以定义变量、函数、类型。
tip:进入C++的学习,记得创建源文件后缀是 .cpp 哦
代码语言:javascript
AI代码解释
namespace test //test是自定义名字
{
int a = 1;
void Swap(int* x, int* y)
{
*x = *x ^ *y;
*y = *x ^ *y;
*x = *x ^ *y;
}
struct st
{
int n;
char m;
};
}
namespace的本质是定义了一个域,和其他局部域、全局域相互独立。既然它们是不同的域,完全可以在各自其中定义相同名字的变量或函数或结构了。举个例子:
代码语言:javascript
AI代码解释
#include"test.h"
int a = 2;
int main()
{
return 0;
}
//如果test.h中有:int a;则程序会报错
//如果test.h中有:namespace test{ int a; }不会报错
//前者程序中的全局域中出现了两次定义a(头文件中一次主函数上面一次),
//后者的全局域和命名空间域各只出现了一次定义a

在这里插入图片描述

在这里插入图片描述
C++中域有全局域、函数局部域、命名空间域、类域。域影响的是编译时语法查找一个变量或函数或类型出处的逻辑,所以在一个域内出现的相同名字会使语法无法判断。有了域隔离,名字冲突就解决了。除此之外,局部域和全局域还会影响变量的生命周期,而命名空间域和类域的变量生命周期默认是整个程序的生命周期。
我们还要知道的是:
- namespace只能定义在全局,不能定义在函数里。
- namespace可以嵌套定义。
- 项目工程中多文件中定义的同名namespace会被认为是一个namespace,会被程序自动合并,不会冲突。
- C++标准库都放在一个叫std(standard)的命名空间中。
代码语言:javascript
AI代码解释
//namespace的嵌套定义
namespace MiHoYo
{
int a = 10;
char c = 'Q';
namespace Honkai_3
{
int a = 1;
char c = 'X';
}
namespace Genshen_Impact
{
int a = 4;
char c = 'J';
}
namespace Honkai_Star_Rail
{
int a = 9;
char c = 'O';
}
}
3. 命名空间的使用
3.1 命名空间成员访问
访问命名空间的操作符是::,使用方式和结构体的. ->很像。 比如,语句test::a,是从命名空间test中找变量a;::a默认是从全局域中找变量a;而a就是先从局部域找a,找不到再从全局域找a。函数或类型也同理 代码示例:
代码语言:javascript
AI代码解释
#include<stdio.h>
namespace test1
{
int a = 1;
namespace test2
{
int a = 2;
}
}
int a = 3;
int main()
{
int a = 4;
printf("%d\n", test1::a); //访问test1的a
printf("%d\n", test1::test2::a); //访问test1中的test2中的a
printf("%d\n", ::a); //默认访问全局域的a
printf("%d\n", a); //访问局部域的a,局部域没有a则访问全局域的a
return 0;
}

在这里插入图片描述
函数也是一样的:
代码语言:javascript
AI代码解释
#include<stdio.h>
namespace test
{
int a = 2;
int b = 8;
int Add(int x, int y)
{
return x + y;
}
}
int main()
{
printf("%d", test::Add(test::a, test::b));
return 0;
}

在这里插入图片描述
3.2 using展开
C++中还有一个关键字using,能将命名空间成员展开,即让这个成员从命名空间中“出来”到全局域中,相当于全局域中再定义了一次,原命名空间仍保留成员。使用方法是using 命名空间名::成员名;,如:
代码语言:javascript
AI代码解释
namespace test
{
int a = 1;
char c = 'P';
}
using test::a; //这一句可以看做int a = 1;
void main()
{
printf("%d ", a);
printf("%d ", test::a);
//两者结果相同
}

在这里插入图片描述但是,展开了a相当于还是在全局域中定义了a,又带来了命名冲突的风险。所以只有项目中经常访问不存在冲突的成员推荐这种方式。
更多推荐



所有评论(0)