using namespace std详解

来源:互联网 发布:unity3d导航系统 编辑:程序博客网 时间:2024/05/21 10:56
C++ using namespace std 详解

在新的C++标准中,生成新头文件的方法仅仅是将现有C++头文件名中的.h去掉。例如,<iostream.h>变成了<iostream>,<complex.h>变成了<complex>,等等。对于C头文件,采用同样的方法,但在每个名字前还要添加一个c。所以C的<string.h>变成了<cstring>,<stdio.h>变成了<cstdio>,等等。

旧的C++头文件是官方所反对使用的(即,明确列出不再支持),但旧的C头文件则没有(以保持对C的兼容性)。

下面是C++头文件的现状:

l         旧的C++头文件名如<iostream.h>将会继续被支持,尽管它们不在官方标准中。这些头文件的内容不在名字空间std中。

l         新的C++头文件如<iostream>包含的基本功能和对应的旧头文件相同,但头文件的内容在名字空间std中。(在标准化的过程中,库中有些部分的细节被修改了,所以旧头文件和新头文件中的实体不一定完全对应。)

l         标准C头文件如<stdio.h>继续被支持。头文件的内容不在std中。

l         具有C库功能的新C++头文件具有如<cstdio>这样的名字。它们提供的内容和相应的旧C头文件相同,只是内容在std中。

一 :

<iostream>和<iostream.h>是不一样,前者没有后缀,实际上,在你的编译器include文件夹里面可以看到,二者是两个文件,打开文件就会发现,里面的代码是不一样的。

后缀为.h的头文件c++标准已经明确提出不支持了,早些的实现将标准库功能定义在全局空间里,声明在带.h后缀的头文件里,c++标准为了和C区别开,也为了正确使用命名空间,规定头文件不使用后缀.h。

因此,当使用<iostream.h>时,相当于在c中调用库函数,使用的是全局命名空间,也就是早期的c++实现;当使用<iostream>的时候,该头文件没有定义全局命名空间,必须使用namespace std;这样才能正确使用cout。

二:

所谓namespace,是指标识符的各种可见范围。

C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。

由于namespace的概念,使用C++标准程序库的任何标识符时,可以有三种选择:

(oct  八进制     dec  十进制     hex  十六进制)

1、直接指定标识符。例如std::ostream而不是ostream。完整语句如下:

std::cout << std::hex << 3.4 << std::endl;

2、使用using关键字。

using std::cout;

using std::endl;

以上程序可以写成

cout << std::hex << 3.4 << endl;

3、最方便的就是使用using namespace std;

例如:

#include <iostream>

#include <sstream>

#include <string>

using namespace std;

这样命名空间std内定义的所有标识符都有效(曝光)。就好像它们被声明为全局变量一样。那么以上语句可以如下写:

cout << hex << 3.4 << endl;

因为标准库非常的庞大,所程序员在选择的类的名称或函数名时就很有可能和标准库中的某个名字相同。所以为了避免这种情况所造成的名字冲突,就把标准库中的一切都被放在名字空间std中。但这又会带来了一个新问题。无数原有的C++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间下的。

所以就有了<iostream.h>和<iostream>等等这样的头文件,一个是为了兼容以前的C++代码,一个是为了支持新的标准。

命名空间std封装的是标准程序库的名称,标准程序库为了和以前的头文件区别,一般不加".h"

很多初学C++的人,对于C++中的一些基本的但又不常用的概念感到模糊,命名空间(namespace)就是这样一个概念。

C++中采用的是单一的全局变量命名空间。在这单一的空间中,如果有两个变量或函数的名字完全相同,就会出现冲突。当然,你也可以使用不同的名字,但有时我们并不知道另一个变量也使用完全相同的名字;有时为了程序的方便,必需使用同一名字。比如你定义了一个变量string user_name, 有可能在你调用的某个库文件或另外的程序代码中也定义了相同名字的变量,这就会出现冲突。命名空间就是为解决C++中的变量、函数的命名冲突而服务的。解决的办法就是将你的strTemp变量定义在一个不同名字的命名空间中。就好像张家有电视机,李家也有同样型号的电视机,但我们能区分清楚,就是因为他们分属不同的家庭。

例如:

 

#include <iostream>

#include <string>

using namespace std;

 

//using namespace编译指示,使在C++标准类库中定义的名字在本程序中可以使用

//否则,iostream,string 等c++标准类就不可见了,编译就会出错。

 

//两个在不同命名空间中定义的名字相同的变量

 

namespace myown1{

 

string user_name = "myown1";

}

namespace myown2{

 

string user_name = "myown2";

}

 

int main()

{

cout<< "\n"

<< "Hello, "

<< myown1::user_name //用命名空间限制符myown1访问变量user_name

<< "... and goodbye!\n";

 

cout<< "\n"

<< "Hello, "

<< myown2::user_name //用命名空间限制符myown2访问变量user_name

<< "... and goodbye!\n";

 

return 0;

}

 

 

当然,我们也可以使用程序开头的预编译指示来使用命名空间中的名字。使用预编译指示的好处在于在程序中不必显式地使用命名空间限制符来访问变量。以上主程序可修改为:

 

 

int main()

{

using namespace myown1;

cout<< "\n"

<< "Hello, "

<< user_name

<< "... and goodbye!\n";

 

// using namespace myown2;

cout<< "\n"

<< "Hello, "

<< myown2::user_name //用命名空间限制符myown2访问变量user_name

<< "... and goodbye!\n";

 

return 0;

}

 

但第二个变量必需用命名空间限制符来访问,因为此时myown1空间中的变量已经可见,如果不加限制,编译器就会无法识别是那一个命名空间中的变量。这一点一定要注意。 以上只是初学者不清楚的一个概念,在以后的文章中还将继续讨论其它的一些概念。

 

命名空间(名字空间)

  命名空间是C++的一种机制,用来把单个标识符下的大量有逻辑联系的程序实体组合到一起。此标识符作为此组群的名字。命名空间用关键字namespace 来定义:

 

//stl_cpp_6.cpp

#include <iostream>

using namespace std;

namespace printA

{

  print() {cout<<"using namespace printA….."<<endl; };

}

namespace printB

{

  print() {cout<<"using namespace printB….."<<endl; };

}

int main(void)

{

  printA::print();   //测试命名空间printA, ::是作用域解析运算符

  printB::print();

}

命名空间可以嵌套定义:

namespace A

{

  functiong1(){};

  namespace B

  { }

}

  一个namespace是指一个具名的范围(named scope)。namespace被用来将相关的声明划归在一起,将不相关的代码部分隔开。命名空间只是命名了一个特殊的作用域,当程序很大,而且需要多人合作的时候,命名空间就显得特别的重要。比如2个程序员A,B 在同一个程序中定义了函数 pop(),如果没有使用命名空间,则会出错,而且这种错误难以检测出来。为了安全起见,他们可以定义不同的命名空间 A和B,在用的时候可以使用A::pop()和B::pop()来区分。

  在STL中,标准库的全部成员在预先定义的命名空间std中。如果要用类模板vector ,有两种方法:一是在程序的前面添加预处理指令:

 

  #include <vector>

  using namespace std;

第二种方法是:

 

  #include <vector>

  using std::vector;

 

VC6.0中如何调整代码的字体大小?     tools/options/format

 

如何使得VC++6.0时刻显示行号

vc++6.0的右下角是可以显示当前光标的行号列号的,总是觉得不方便。

编程时具有行号对编程过程有很打的帮助作用,特别在学习阶段,能帮助我们提高程序可读性,方便讲解程序.但是如何使得VC中能够具有行号,是值得我们去做的一个问题。

通过VC6LineNumberAddin能够解决这个问题,方法如下。

一、下载该文件。网上很多免费的。

二、解压后把VC6LineNumberAddin.dll拷贝到安装路径内(如:C:\Program Files\Microsoft Visual Studio\COMMON\MSDev98\AddIns)…\COMMON\MSDev98\AddIns内。

三、运行注册表文件,进行注册。

四、打开VC++6.0,进入tools\customize\Add-ins and Macro Files\菜单后的对话框内,在VC6LineNumber Developer Studio Add-in前划上钩。

五、确定后进入编程界面。即可发现,我们的程序具有行号了。

整体的程序界面。

 

返回值的作用

main 函数的返回值用于说明程序的退出状态。如果返回 0,则代表程序正常退出,否则代表程序异常退出。下面我们在 winxp 环境下做一个小实验。首先编译下面的程序:

int main( void )

{

return 0;

}

 然后打开附件里的“命令提示符”,在命令行里运行刚才编译好的可执行文件,然后输入“echo %ERRORLEVEL%”,回车,就可以看到程序的返回值为 0 。假设刚才编译好的文件是 a.exe ,如果输入“a && dir”,则会列出当前目录下的文件夹和文件。但是如果改成“return -1”,或者别的非 0 值,重新编译后输入“a && dir”,则 dir 不会执行。因为 && 的含义是:如果 && 前面的程序正常退出,则继续执行 && 后面的程序,否则不执行。也就是说,利用程序的返回值,我们可以控制要不要执行下一个程序。这就是 int main 的好处。如果你有兴趣,也可以把 main 函数的返回值类型改成非 int 类型(如 float),重新编译后执行“a && dir”,看看会出现什么情况,想想为什么会出现那样的情况。顺便提一下,如果输入 a || dir 的话,则表示如果 a 异常退出,则执行 dir 。

 

 

C++中,<cstring>、<string.h>和<string>的关系,①这几个各在什么时候使用?需不需要命名空间?②什么叫C++标准string类?有多少这样的标准?③什么叫标准类模板库STL?和前面的概念有什么关系?

首先string.h是C的,不是C++的,包括了操作C风格字符串的函数,如strcpy.strcmp,strcat,strlen等。C 语言里没有字符串这个数据类型,有的只是字符指针或字符数组,C风格字符串也就是以'\0'结尾的字符序列。

 

然后是cstring。在C++标准化之前,头文件有各种后缀名,如.h,.hpp,.hxx等,标准化之后规定头文件不带后缀名,同时原来的C标准头文件都在前面加了个"c",于是原来C里的string.h,在C++里就变成了cstring,同样的stdio.h,stdlib.h之类的都变成了cstdio、cstdlib一类。为了兼容C,大部分C++编译器都同时提供了这两个版本的头文件,可以认为string.h和ctring是一回事,你可以看一下你的编译器里include目录下的这两个文件,cstring只是简单的include了string.h而已。

 

所以当你需要使用strcpy.strcmp,strcat,strlen这一类的函数时,在C里include string.h,C++里include cstring或string.h都行。同时,因为C里没有namespace,所以这两个是不使用命名空间的。

 

最后是string,这个是C++的标准字符串库,定义了string这个类型,当你需要使用这个C++的字符串类时,需要包含这个头文件,同时需要使用std命名空间。

 

C++标准string类就是C++标准里定义的字符串类,C++标准是由C++标准委员会制定的,目前只有C++ 98这个标准,新的C++0x标准还在草案中。

 

C++ STL (Standard Template Library,标准模板库)是C++标准的一部分,是一个模板与算法的类集合。它可以使程序员很方便地实现一些标准的数据结构,比如队列、链表以及栈等。

 

 

#include<string>封装的是的是c++的stirng类,并没有strcat之类的函数

<cstring>才有,它包含了原<string.h>的所有函数,不过把他们放到std命名空间里

<cmath>也包含了<math.h>的头文件

0 0
原创粉丝点击