引言:

问题:学习过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

什么是命名空间 为什么C++需要使用命名空间相关推荐

  1. 命名空间不能直接包含_php命名空间

    今天,刚好要写开源项目的后台数据了,所以学习了一下php的命名空间,收获多多,所以总结了一下这篇文章,好了,废话不多说,上代码吧 我们该如何命名空间呢? <?php // 使用命名空间的关键字n ...

  2. 未能在全局命名空间中找到类型或命名空间名称“Wuqi”

    下载了AspNetPager控件用以进行分页操作,在项目中放入控件后,运行报错:未能在全局命名空间中找到类型或命名空间名称"Wuqi" . 解决办法:在项目下拉框"引用& ...

  3. 命名空间_python基础 13 类命名空间于对象、实例的命名空间,组合方法

    python基础 13 类命名空间于对象.实例的命名空间,组合方法 1.类命名空间于对象.实例的命名空间 创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性 而类有两 ...

  4. YiShaAdmin_项目的默认 XML 命名空间必须为 MSBuild XML 命名空间。如果项目是用 MSBuild 2003 格式---.Net_C#_若依.Net版Web框架使用及改造001

    下面是错误: C:\Users\Administrator\Desktop\YiShaAdmin\YiSha.Cache\YiSha.Cache.Factory\YiSha.Cache.Factory ...

  5. python 命名空间冲突_通过修改命名空间绕过pb冲突

    背景 在实际工作当中,很多服务框架本身会依赖pb,但是和tf的pb会发生冲突[通常是因为pb比较老或者版本有冲突导致],所以本文介绍如何通过修改名空间的方式来绕过pb冲突. 修改名空间&编译p ...

  6. php 命名空间实现的原理,php命名空间实现的理解

    [前言] 之前测试命名空间,文件头部明明定义了namespace,并且类文件的存放位置与相对路径也一致,但use之后仍提示"找不到类",为什么? [原理分析] 1.根据use的值确 ...

  7. c# 命名空间命名规范_C#命名空间能力问题和解答 套装3

    c# 命名空间命名规范 1) There are following namespaces are given below, which is correct about "using&qu ...

  8. c# 命名空间命名规范_C#命名空间能力问题和解答 套装2

    c# 命名空间命名规范 1) Can we create a nested namespace in C#.NET? Yes No Answer & Explanation Correct a ...

  9. python中的命名空间指什么_python中命名空间

    原文章 由一个例子到python的名字空间 .这篇文章对python的命名空间做出了非常好的介绍,这里是我自己的一些理解. 例子1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...

最新文章

  1. 清华大学精密仪器系:智能传感器太重要了!
  2. Python回顾与整理5:映像和集合类型
  3. Nmap源码分析(脚本引擎)
  4. 【BC】如何将自定义的区域菜单添加到系统默认的菜单中
  5. 检查 Flutter 应用程序是否在 Web 上运行
  6. 快速排序,冒泡排序时间复杂度推导
  7. AFNetwork作用和用法详解
  8. cesium添加填充_Cesium中级教程1 - 空间数据可视化(一)
  9. Github+jsDelivr+PicGo 打造稳定快速、高效免费图床
  10. 004:2的幂次方表示
  11. 拥有自己的Git服务器
  12. Codeforces Round #364 (Div. 1) 700B(树)
  13. java session超时判断_详解SpringBoot中Session超时原理说明
  14. 前端 如何检测到当前的网页已经退出_如何监控网页崩溃?
  15. 娓娓道来图模型、图查询、图计算和图学习知识
  16. 上市集团计算离职率sql案例
  17. mysql error1205 博客_Mysql Error:1205错误诊断
  18. qcqa是什么职位_qc经理是什么职位
  19. 量子加密通信与量子传感技术相关精简介绍
  20. Leetcode P44 java一次遍历

热门文章

  1. eclipselink_EclipseLink MOXy作为JAXB提供者
  2. Java和甜蜜的科学
  3. 从迁移到Java 7的小技巧
  4. OutOfMemoryError:无法创建新的本机线程–问题神秘化
  5. Spring MVC集成测试
  6. Java RESTful API集成测试
  7. vue进行判断使用class_vue判断dom的class
  8. python常用命令格式_python常用命令有哪些
  9. MacOS录制GIF/录屏的工具
  10. 早期计算机的应用主要是( ) (2分),计算机基础第1次作业(含答案)