标题:[讨论]关于头文件.h和名字空间
只看楼主
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
结帖率:66.67%
 问题点数:0 回复次数:8 
[讨论]关于头文件.h和名字空间

讨论关于字符串类型string的使用,我想问的是我用到string类型时,只能如下这样定义头文件(去掉.h),还要加上一行名字空间,而不能用<iostream.h>和<string.h>(加上.h),为什么?

#include<iostream> //如果我包含的是iostream.h则出错,为什么? #include<string> //如果我包含的是string.h则出错,为什么?

using namespace std; //去掉这句更多错,这句代表了新的ANSI标准吗?

void main() { string str; //这里定义的str是任意长吗? cin>>str; cout<<str<<endl; }

[此贴子已经被作者于2004-09-19 11:58:27编辑过]

搜索更多相关主题的帖子: 头文件 名字空间 string 定义 include 
2004-09-19 11:55
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
得分:0 

我的意思是如果要用到string类型,如下这样是出错的,为什么?

#include<iostream.h> //如果我包含的是iostream.h则出错,为什么? #include<string.h> //如果我包含的是string.h则出错,为什么?

//using namespace std; //去掉这句更多错,这句代表了新的ANSI标准吗?

void main() { string str; //这里定义的str是任意长吗? cin>>str; cout<<str<<endl; }

2004-09-19 11:57
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
得分:0 

如果去掉.h,只包含而不加using namespace std一行也出错, 而如果只加了namespce而不去掉.h也出错。为什么?解释一下这两种情况。

2004-09-19 12:04
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
得分:0 
[转帖]

实际上就是告诉编译器,你类型是什么,在哪能找到。 常用的是using namespace std,就是说用C++的标准名字空间。 你也可以引用你自己的名字空间。比如说: import "C:\MyTest\test.tlb" using namespace CMyTest 就可以引用CMyTest内的各个类型名 看C++ prime --------------------------------------------------------------- 声明该文件使用C++标准库 吧! 比如 #include <iostream> using namespace std; void main() { cout << "hello!" << endl; } 如果不用using namespace std;这句,那么 std::cout << "hello!" <<endl; 这是名字空间的问题!具体参看有关书籍吧,新版的C++ 书应该都有介绍的! --------------------------------------------------------------- using 指示符! 这是个名字空间问题,是标准C++引入的新概念! 具体在《C++Primer》第8.6节有详细说明! --------------------------------------------------------------- 因为标准库非常的庞大,所程序员在选择的类的名称或函数名时就很有可能和标准库中的某个名字相同。所以为了避免这种情况所造成的名字冲突,就把标准库中的一切都被放在名字空间std中。但这又会带来了一个新问题。无数原有的C++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间下的。 所以就有了<iostream.h>和<iostream>等等这样的头文件,一个是为了兼容以前的C++代码,一个是为了支持新的标准。 --------------------------------------------------------------- 名字空间,实质上也是为了方便程序在不同平台上正确的运行。 --------------------------------------------------------------- namespace是为了解决C++中的名字冲突而引入的。 什么是名字冲突呢?比如,在文件x.h中有个类MyClass, 在文件y.h中也有个类MyClass,而在文件z.cpp中要同时 引用x.h和y.h文件。显然,按通常的方法是行不能的, 那怎么办呢?引入namespace即可。例如: 在x.h中的内容为 // x.h namespace MyNamespace1 { class MyClass { public: void f(); private: int m; } }; 在y.h中的内容为 // y.h namespace MyNamespace2 { class MyClass { public: void f(); private: int m; } }; 然后在z.cpp中引入x.h和y.h // z.cpp #include "x.h" #include "y.h" void z::f() { //声明一个文件x.h中类MyClass的实例x MyNamespace1::MyClass x; //声明一个文件x.h中类MyClass的实例x MyNamespace2::MyClass y; //调用文件x.h中的函数f x.f(); //调用文件y.h中的函数f y.f(); } 名字空间实质上是一个作用域。 通过上面的一个实例应该知道名字空间的作用了吧。

2004-09-19 12:11
kuangjingbo
Rank: 1
等 级:新手上路
帖 子:312
专家分:0
注 册:2004-4-24
得分:0 

我不知道你用的是什么编译器 ,vc7.0 确实是你这种情况。因为增加了“名字空间”这个东西

vc6.0 不是你说的情况

另外,在vc7.0中 ,输入输出文件的头文件就是iostream ,它根本就没有定义iostream.h这样的头文件

你可以去安装的路径下的include文件夹里看看。既然没有iostream.h , 那么你使用#include iostream.h 当然会出错

iostream的文件不大 ,如下:

// iostream standard header for Microsoft #pragma once #ifndef _IOSTREAM_ #define _IOSTREAM_ #include <istream>

#pragma pack(push,8) #pragma warning(push,3) _STD_BEGIN

// OBJECTS extern _CRTIMP2 istream cin, *_Ptr_cin; extern _CRTIMP2 ostream cout, *_Ptr_cout; extern _CRTIMP2 ostream cerr, *_Ptr_cerr; extern _CRTIMP2 ostream clog, *_Ptr_clog;

// CLASS _Winit class _CRTIMP2 _Winit { public: _Winit(); ~_Winit(); private: static int _Init_cnt; };

// WIDE OBJECTS extern _CRTIMP2 wistream wcin, *_Ptr_wcin; extern _CRTIMP2 wostream wcout, *_Ptr_wcout; extern _CRTIMP2 wostream wcerr, *_Ptr_wcerr; extern _CRTIMP2 wostream wclog, *_Ptr_wclog; _STD_END #pragma warning(pop) #pragma pack(pop)

#endif /* _IOSTREAM_ */

/* * Copyright (c) 1992-2002 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V3.13:0009 */


永不放弃!
2004-09-19 18:26
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
得分:0 

我最近看了些书,原来早期的C++是用.h的,就是说头文件iostream加上.h,而事实上,再最新版本的或最新规范化编程中,一般不加.h,而且更悬念的是,string.h和string竟不是同一文件(其他是同的,例如iostream.h和iostream是一样),string.h头文件包含的是字符串的操作,如strcmp()等,而string包含的却是string新类型,就是说包含string就可以使用string类型来定义字符串而不再需要数组,但是……慢着,就是当不加.h时,却要加上一句“using namespace std;”,为什么?而在C#中,编译器甚至完全抛弃了#include&lt;&gt;,多数功能在using System中已经全部给出。why???
2004-09-22 21:51
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
得分:0 
[原创]讨论string.h和string和std

又再试了一下,上网搜索了一下,没找到关于string.h和string的区别的介绍。 于是惟有自己探讨,先看如下代码,关键在于定义包含文件处。

#include<string> //没有加.h,加了的话就有错误发生 #include<iostream> //没有加.h,加了的话就有错误发生

using namespace std; //如果不加此句,将提示6个错误和1个警告

void main() { string str = "I love Queenie Wen!"; cout<<str<<endl; //包含文件处加了.h的话,发生的错误提示都在这行 }

错误提示如下: binary '<<' : no operator defined which takes a right-hand operand of type 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' (or there is no acceptable conversion)

以上提示大意是说,“<<”符号没有被定义给string类型,到不了string模板的指针allocator。

*小知识:“<<”和“>>”其实就是利用C++的运算符重载功能把输入输出定义为面向所有类型,printf和scanf中要标明输入输出类型,而cout和cin之所以不用,是因为被重载了所有值类型。

然后为什么要加上名字空间std呢?std是从旧类型C++过渡到.NET的产物,在Java中被广泛应用,而对于在过渡之前的旧C++用户会觉得很不惯,而对于新用户习惯了不加.h,而其实是编译提供方便,实际上是要加.h的,毕竟头文件的扩展名就是.h。不加.h的新规范则要附加上一句:

using namespace std; //注意是语句,所以要有“;”号作结束

在C++中新定义的string属于模板类的一种,在string标准库中定义,而string的内部定义就鲜为人们讨论,大家只顾着用,却没研究内部定义,其实string的定义被用名字空间std所包含了,就是说,string类型的使用及其跟随的函数都被定义在namespace std中,至于为什么叫std,或可不可以叫namespace live41,就无从考究,反正想main函数的args[][],是国际默许规则,也可以叫main(char live41[][])之类的作为运行参数变量名字,但既然大家都默许了那个args名字,就用吧。

用#include<iostream.h>和#include<string.h>是旧用户的写法,不过这样就不能使用C++新规定的string类型,而#include<iostream>和#include<string>就可以使用,并且要加上using namespace std;一句标明使用std库中的string定义,漏了说的就是,该std被包含在string中,所以又要加#include<string>,又要加using namespace std一句。

最后要讨论iostream.h和iostream的区别,当使用了#include<string>和std句子时,如果继续用iostream.h就输入输出不了string类型的变量和函数,因为string是新类型,所以要有新的“<<”“>>”重载方案,包含iostream.h的话就缺少了对string类型的支持,就是说iostream.h和iostream的区别大概就在于提供string类型的输入输出符号重载,两者并不是同一个文件。

看完以上,大家还是蒙蒙的吧?我也是,不好意思水平有限,但是我会下去继续找书来探讨。

[此贴子已经被作者于2004-09-23 12:27:19编辑过]

2004-09-23 11:59
ffll518
Rank: 1
等 级:新手上路
帖 子:24
专家分:0
注 册:2004-9-8
得分:0 
这几天看书准备考试中,没上来玩玩,你可以去看看INCLUDE文件夹下的东西就知道了,.h文件是传统C++头文件而不带.h的文件是ANSI/ISO标准的库文件,凡是这个标准的库文件中的类和对象比如iostream类cout、cin等全部定义在std这个名字空间中,所谓名字空间其实就是一个局部域而已,可用类域运算符::来访问的;定义名字空间(例):namespace N{int n;} 那么使用这个名字空间的n时有2种方法,1种是N::n=0;另一种是using namespace N; n=0;这么说是不是能明白点呢?比如你用#include <iostream>的话,那么这个类是定义在std域中的,要么用using namespace std;要么用std::cout或std::cin;至于string.h和string的区别就大了,string是定义在std域中的字符串类,凡是string类对象都可以用重载运算符==,<,>,+等都是成员函数而已;而string.h是传统C的字符串处理函数库,里面可没有什么类之类的东西比如strcpy,strlen,strcmp等C函数全在这个里面,这2个东西是根本上的2回事情,可千万表弄混了哈

2004-09-24 11:10
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
得分:0 

谢谢,你说的我都知道,不过不敢肯定,现在很清楚了。

ANSI = American National Standards Institute 美国国家标准协会

2004-09-24 16:06



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-5457-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.049501 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved