什么是命名空间 为什么C++需要使用命名空间

引言:


问题:学习过C,然后再学c++的人可能会这么问,我#include<iostream>之后,不就是把头文件拉进来了吗,而cin cout等函数不就是iostream.h里面的函数吗,我使用cin cout时,编译器为什么会说  “Error 未定义标示符”呢?
解决方法:这样写

#include<iostream>using namespace std;void main(){}


但可能不知道为什么加这句

我刚学C++时也不明白为什么,看课本解释说什么命名空间的,看不明白,只是知道这样写才能通过编译,也没有深究,每次都默默加上去的说。

现在,任然是个菜鸟的说,看了一些资料之后,写了这篇笔记“关于using namespace std;以及为什么有的头文件需要加上.h而有的头文件不需要”,可能不够严谨,欢迎指出错误。


这是个历史问题。


一、从库的概念说起


这得从库的概念说起,你#include进去的就是别人帮你写好的库,你可以直接调用头文件里面封装好的函数或类,比如你用的cin cout等就是c++标准库里面的函数,这样你就不用自己写一个函数cin 来实现输入功能,也不用写函数cout来实现输出功能,直接调用就可以了。除了C++标准库,一些公司封装了一些函数,实现某些强大的功能,然后拿来卖,比如微软的MFC ,Trolltech公司的Qt等,所以c++变得更加强大,不仅可以直接调用标准库,还能调用别的公司封装好的库。


二、命名空间诞生的原因

早期的c++库内容有限,可随着时间的推移,库的功能越来越强大,每个厂商之间可能将库里面的函数或类取了相同的名字,比如说A公司的库就可能定义了一个叫做sum的函数,而B公司也定义一个叫做sum的函数,于是就出现问题了,程序员开发时,如果同时使用了A的库,又使用了B公司的库,那么就可能出现混乱,你调用的sum到底是哪家公司的。最初,人们就想了个办法,厂商将名字取得更长更复杂来避免重复,可这样做却给编写和阅读带来了困难。后来,人们创造了命名空间这个概念(1998年),它能有效地指出某个标示符到底属于哪个库。


三、什么是命名空间

通过使用 namespace xxx;来说明你所用的这个函数或类来自于哪个库或者是自己写的函数。例如,C++标准程序库就把标准库库里面的函数或类的名称放在一个“叫做std的命名空间”,比如cin cout这两个函数的名字就放放在命名空间std里面,你可以通过std::cin  std::cout来说明你这里使用的cin cout是来自标准库里面的函数,而不是自己写了个名字叫做cin的函数,也不是别的厂商的库里面的函数cin,但这样也比较麻烦,每次调用的话就得把cin写成std::cin,如果你想要经常可以在程序的开头使用 using std::cin;来说明以下代码所使用的cin是来自std这个命名空间,也就是标准库里面的函数。若程序需要大量地使用标准库里面的函数,就可以把using namespace std;放在程序的开头,来说明以下代码将使用标准库的函数或类,程序员不能取和标准库里面冲突的函数或类的名称,于是你就能直接使用cin cout而不必用std::cin来说明你这里的cin是std里面的。总之,通过命名空间就能有效的说明某个函数或类到底是调用了属于哪里的库。


四、命名空间的出现导致新版头文件的诞生

可是,这样做带来了一个新的问题,c++发展了那么多年(直到1998年推出命名空间,大约发展了16年),现存的代码已经有一定的量了,你突然给我搞了一个命名空间,以前可没这东西,我以前写的代码就不能再新的编译器下运行了,这可不行。

于是,人们想出了一个办法。为包装了std的那部分标准库构件创建出新头文件名。并且把新的头文件名字取和旧头文件相同,但不加后缀.h。所以<iostream.h>变成了新版头文件<iostream>,<complex.h>变成了<complex>,而新旧头文件的功能基本上相同的(但不完全相同),所以使用<iostream>时,想要调用里面的函数,就得使用类似std::cin的方法来说明cin是使用标准库里面的函数,而不是自己定义或别的厂商的库的函数,当然,如前文所述,也可以在开头使用using namespace std;来说明以下程序将使用标准库的函数。

当使用<iostream.h>时,使用的是全局命名空间,也就是早期的c++实现(c++标准已经明确表示不支持这种用法了,所以理论上来说这种用法是非法的,但编译器厂商有可能还支持这种用法)

当使用<iostream>时,该头文件没有定义全局命名空间,必须使用命名空间 std来说明你所使用的函数或类是来自iostream的

而c++对待C头文件(c++可以使用c的头文件)的方式是继续支持旧的头文件的支持,也既<string.h>这种用法,以保持对C的兼容性。但为了与时俱进(因为命名空间是个好东西呀),任然对应旧版头文件开发了新版的头文件,命名方式是,在每个旧版名字前添加一个c。所以C的头文件<string.h>变成了新版c++的<cstring>,C的头文件<stdio.h>变成了新版c++的<cstdio>。这也是为什么c++代码里面有的头文件加.h,有的不加.h的原因。#include进来可能是(1)、新版C++头文件,如#include<iostream>(2)、新版C语言头文件,如#include<cstring>(3)旧版的C头文件,如#include<string.h> (4)、旧版C++头文件,理论上来C++是不支持这个用法了,但一些编译器厂商任然可以这样使用


五、完结

回到开头的那个问题,#include<iostream>之后,是不能直接调用里面的函数的,因为<iostream>这个头文件属于c++标准库的一部分,既cin这个函数属于标准库的一个函数,如上文所述,它的用法是在函数名字放在了命名空间std中,你得用std::cin来说明一下这里的cin是来自命名空间std里面的,也就是标准库里面的cin函数,而不是别的库的cin函数。这是C++的用法,不要与C混淆。

总结概括:库的爆炸性的发展导致经常出现命名重复,从而提出了命名空间的概念,有效地说明同个名称的函数到底来自哪个库,但这导致过去几年所开发出来的代码可能不能使用,从而C++委员会对应旧版头文件重新开发了新版的头文件,命名方式相同,但不添加后缀.h。委员会对待C语言头文件的方式类似,重新开发了一套头文件,命名方式是在头文件开头加上字母c,并去掉后缀.h.

新版C++对待旧版C++和旧版C语言的方式差别在于,明确提出不再支持C++头文件.h的使用,但任然支持C语言头文件.h的使用。这也是为什么现在的C++代码有的使用了.h,(调用了旧版C语言头文件),也可能不加.h(使用新版头文件)。

 
————————————————
版权声明:本文为CSDN博主「买柴火的小火柴」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u013162593/article/details/22823425

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/341376.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pat 乙级 1023 组个最小数(C++)

题目 给定数字 0-9 各若干个。你可以以任意顺序排列这些数字&#xff0c;但必须全部使用。目标是使得最后得到的数尽可能小&#xff08;注意 0 不能做首位&#xff09;。例如&#xff1a;给定两个 0&#xff0c;两个 1&#xff0c;三个 5&#xff0c;一个 8&#xff0c;我们得…

C++谷歌命名规范

1.文件命名规则 文件名全部小写&#xff0c;可以含下划线或连字符&#xff0c;按项目约定命名,且尽量保证文件名明确。比如&#xff1a;cmd_save_player_info_class.cc &#xff0c;my_use_full_class.cc 定义类的文件名一般是成对出现&#xff0c;如&#xff1a;foo_bar.h f…

pat 乙级 1028 人口普查(C++)

题目 某城镇进行人口普查&#xff0c;得到了全体居民的生日。现请你写个程序&#xff0c;找出镇上最年长和最年轻的人。 这里确保每个输入的日期都是合法的&#xff0c;但不一定是合理的——假设已知镇上没有超过 200 岁的老人&#xff0c;而今天是 2014 年 9 月 6 日&#xf…

c++ 为什么要按它们声明的顺序初始化成员变量?

我今天正在写一些代码&#xff0c;并得到一个奇怪的编译错误&#xff0c;这似乎是由初始化成员变量的顺序不同于他们声明的。 class Test {int a;int b;public:Test() : b(1), a(2) {} };int main() {Test test;return 0; } 然后&#xff0c;如果我编译它与-Werror -Wall&…

如何在Java中使用Lombok删除样板安装程序获取器

你好朋友&#xff0c; 一次又一次反对Java的观点之一是&#xff0c;我们必须写很多样板 我们简单的POJO类的setter和getter形式的代码&#xff0c;不必要地增加了 我们代码的长度。 为了解决这个问题&#xff0c;有一个名为Project Lombok的开源项目可以解决这个问题。 通过…

Python 列表list与数组array的区别

1. 列表list与数组array的定义&#xff1a; 列表是由一系列按特定顺序排列的元素组成&#xff0c;可以将任何东西加入列表中&#xff0c;其中的元素之间没有任何关系&#xff1b; Python中的列表(list)用于顺序存储结构。它可以方便、高效的的添加删除元素&#xff0c;并且列…

Dev-C++使用技巧1(亲测)(超详细)(安装过程、修改语言、新建项目、配置C++ 11、开启警告信息和调试信息)

前言 Dev-C是一款内存占用小&#xff0c;支持C/C&#xff0c;支持调试&#xff0c;可以一键编译、运行的IDE&#xff08;集成开发环境&#xff09;。 下载链接&#xff1a;Dev-C - Download 如果上面那个不行或者下载比较慢&#xff0c;可以点链接: Dev-Cpp 提取码: xaby 。 …

python列表各元素修改为int类型

import numpy as np action np.trunc(action).astype(int).tolist() 函数去掉小数&#xff0c;但元素本身并不是整数。&#xff08; 例1. 或者 2. 没有小数&#xff0c;但也不是整数&#xff09; 要保证元素本身是int类型&#xff0c;则使用astype() &#xff08;得到 [ 1 2…

pat 乙级 1029 旧键盘(C++)

题目 旧键盘上坏了几个键&#xff0c;于是在敲一段文字的时候&#xff0c;对应的字符就不会出现。现在给出应该输入的一段文字、以及实际被输入的文字&#xff0c;请你列出肯定坏掉的那些键。 输入格式&#xff1a; 输入在 2 行中分别给出应该输入的文字、以及实际被输入的文…

1.0jpa 2.0_JPA 2.1类型转换器–持久枚举的更好方法

1.0jpa 2.0可以使用JPA 2.0保留枚举&#xff0c;但是没有很好的方法来实现。 使用Enumerated批注&#xff0c;可以使用EnumType.ORDINAL或EnumType.STRING将枚举值映射到其数据库表示形式。 但是这两种选择都有一些缺点&#xff0c;我们将在本文的第一部分中进行讨论。 在第二部…

从网络虚拟化,看智能网卡发展史

5G的到来无疑将加速网络虚拟化的进程&#xff0c;在电信领域&#xff0c;网络虚拟化不仅在核心网&#xff0c;也在网络的边缘。但是&#xff0c;仅仅通过软件解决方案不能提供足够的网络可靠性和服务质量&#xff0c;而具有高级可编程功能智能网卡&#xff08;Smart NIC&#x…

Dev-C++使用技巧2(亲测)(更改字体和颜色、自动保存、快捷键选项、一键排版)

更改字体和颜色 顶部菜单栏->工具->编辑器选项。 更改字体 当前选项卡->显示&#xff0c;字体word有的基本都有&#xff0c;华文楷体、宋体&#xff0c;幼圆之类。西文字体默认字体Consloas就不错&#xff0c;中文的话幼圆、新宋体都挺不错。 幼圆效果&#xff1…

Java恶意序列化背后的历史和动机

与Java的序列化机制有关的问题已广为人知。 有效的Java 1st Edition &#xff08;第10章&#xff09;和有效的Java 2nd Edition &#xff08;第11章&#xff09;的整个最后一章都专门讨论Java的序列化主题。 Effective Java 3rd Edition &#xff08;第12章&#xff09;的最后一…

深入浅出全面解析RDMA

RDMA(RemoteDirect Memory Access)技术全称远程直接内存访问&#xff0c;就是为了解决网络传输中客户端与服务器端数据处理的延迟而产生的。它将数据直接从一台计算机的内存传输到另一台计算机&#xff0c;无需双方操作系统的介入。这允许高吞吐、低延迟的网络通信&#xff0c;…

pat 乙级 1030 完美数列(C++)

题目 给定一个正整数数列&#xff0c;和正整数 p&#xff0c;设这个数列中的最大值是 M&#xff0c;最小值是 m&#xff0c;如果 M≤mp&#xff0c;则称这个数列是完美数列。 现在给定参数 p 和一些正整数&#xff0c;请你从中选择尽可能多的数构成一个完美数列。 输入格式&…

hypervisor介绍

hypervisor&#xff1a;一种运行在物理服务器和操作系统之间的中间层软件&#xff0c;可以允许多个操作系统和应用共享一套基础物理硬件。可以将hypervisor看做是虚拟环境中的“元”操作系统&#xff0c;可以协调访问服务器上的所有物理设备和虚拟机&#xff0c;所以又称为虚拟…

pat 乙级 1031 查验身份证(C++)

题目 一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下&#xff1a; 首先对前17位数字加权求和&#xff0c;权重分配为&#xff1a;{7&#xff0c;9&#xff0c;10&#xff0c;5&#xff0c;8&#xff0c;4&#xff0c;2&#xff0…

Selenium WebDriver中的TestNG侦听器及示例

Java提供了不同的接口&#xff0c;使您可以修改TestNG行为。 这些接口在Selenium WebDriver中进一步称为TestNG侦听器。 TestNG Listeners还允许您根据项目要求自定义测试日志或报告。 Selenium WebDriver中的TestNG侦听器是侦听某些事件并跟踪测试执行情况的模块&#xff0c;…

pat 乙级 1032 挖掘机技术哪家强(C++)

题目 为了用事实说明挖掘机技术到底哪家强&#xff0c;PAT 组织了一场挖掘机技能大赛。现请你根据比赛结果统计出技术最强的那个学校。 输入格式&#xff1a; 输入在第 1 行给出不超过 105 的正整数 N&#xff0c;即参赛人数。随后 N 行&#xff0c;每行给出一位参赛者的信息…

Ubantu键盘快捷键

Ubuntu系统 长按"Win"键可打开快捷键提示界面