注册 | 登录
收藏 | 帮助
热门文章
编辑推荐
相关文章  
模块复用——c++类、dll和com
获取ACCESS2000数据库中的所有表
C++语言常见问题解答(2)
C++语言常见问题解答(3)
C++语言常见问题解答(4)
在c++程序中重启自己的一种方法
您现在的位置: 顶尖设计 >> IT学院 >> 编程开发 >> C >> 文章正文
C++语言常见问题解答(1)
作者:中译者:叶秉哲  来源:永远的UNIX  点击:  更新:2006-12-19
简介:
erized type)? 
Q121:「泛型」(genericity)是什麽? 
 
第20节:程式库 
---------------- 
Q122:怎样拿到 "STL"? 
Q123:怎样 ftp 到 "Numerical Recipes" 附的程式? 
Q124:为什麽我的执行档会这麽大? 
 
第21节:特定系统的细节 
------------------------ 
Q125:GNU C++ (g++) 把小程式造出大大的执行档,为什麽? 
Q126:有 YACC 的 C++ 文法吗? 
Q127:什麽是 C++ 1.2?  2.0?  2.1?  3.0? 
Q128:如果签名编码标准化了,我能否将不同厂商编译器产生的程式码连结起来? 
 
第22节:其他的技术和环境的事项 
-------------------------------- 
⊙22A:其他的技术事项 
Q129:为什麽有 static 资料成员的物件类别产生了 linker 错误? 
Q130:"struct" 和 "class" 关键字差别在哪? 
Q131:为什麽不能以函数的传回值来多载(overload)它? 
Q132:什麽是「持续性」?什麽是「持续性物件」? 
Q133:为什麽浮点数 (floating point) 这麽不精确?为什麽这段程式不会印出 0.43? 
 
⊙22B:其他环境下的琐事 
Q134:有任何 TeX 或 LaTeX 的巨集,能处理 "C++" 的留白效果(spacing)吗? 
Q135:在哪儿可拿到 C++2LaTeX 这个 C++原始码的 LaTeX 美编工具(pretty 
      printer)? 
Q136:该到哪里取得 "tgrind" 这个 C++/C/etc 的原始码美编工具? 
Q137:有给 GNU emacs 编辑器用的 C++-mode 吗?有的话,该怎麽拿? 
Q138:我要到哪儿得到和作业系统相关的 FAQs( 譬如:BC++、DOS、Windows 等等)? 
Q139:为什麽我的 DOS C++ 程式说 "Sorry: floating point code not linked" 
      “抱歉,浮点运算程式码未连结进来”? 
Q140:为什麽当我没执行 BC45 IDE 的话,BC++ 做出来的 Windows 应用程式就不能用? 
 
========================= 
● 1C:术语及常用的缩写 
========================= 
 
这儿是一些此文件所采用的缩写: 
 
    字汇        意义 
    ====        =========== 
    fn          function ,函数(单数型) 
    fns         functions,函数(复数型) 
    param       parameter,参数 
    ptr         pointer,指标,C/C++ 的语法元素,宣告法:  int * p; 
    ref         reference,参考,C++ 的语法元素,宣告法:  int & r; 
    OO          object-oriented,物件导向 
    OOP         object-oriented programming,物件导向程式设计 
    OOPL        object-oriented programming language,物件导向语言 
    method      运作行为,"member function 成员函数" 的另一种说法 
                【译注】"method" 是源自 Smalltalk 的术语,很常用於 OO 界。 
 
 
======================================================= 
■□ 第2节:我该如何参与讨论?(发信之前请务必一读) 
======================================================= 
 
Q1:我该在哪个讨论区中发问? 
 
Comp.lang.c++ 是讨论 C++语言本身最好的地方(譬如:C++ 程式设计、语法、风格 
)。其他讨论区是用来讨论特定的系统(譬如:MS Windows 或是 UNIX),或是其他 
和 C++语言不直接相关的主题(譬如:怎样使用你的编译器)。底下列出一些非常热 
门的讨论区,并从它们的 FAQs 中摘录些片断,应该能让您明了它们最常讨论哪些课 
题。 
 
  comp.os.ms-windows.programmer.tools 
     此区是用来讨论有关 Windows 软体发展系统工具的选择及使用。 
  comp.os.ms-windows.programmer.misc 
     此乃论及其馀 Windows 软体发展之事项。 
  [有个 FAQ 列表,列出所有 comp.os.ms-windows.programmer.* 讨论区] 
     FAQ 5.7.1.  在 DLL 中存取 C++ 的物件类别 
     FAQ 6.1.1.  以 MDI 子视窗做出对话框 [用 OWL] 
     FAQ 6.2.1.  把禁能的选项致能起来 [用 MFC] 
     FAQ 8.1.5.  使用 windows.h 的 STRICT 符号定义 
     FAQ 10.  程式设计参考资料 
 
  comp.os.msdos.programmer 
     许多信件都是关於程式语言产品的(主要是 Borland 和 Microsoft)。 
     FAQ 301. 怎样才能读取字元而不 [等待] Enter 键? 
     FAQ 412. 怎样读取、建立、更改及删除磁片标名? 
     FAQ 504. 怎样设定 COM 埠,以用它来传输资料? 
     FAQ 602. C 程式怎样才能送控制码给印表机? 
     FAQ 606. 怎样才能得知 Microsoft 滑鼠的位置及按钮状态? 
     FAQ 707. 怎样写常驻程式(TSR)工具? 
     FAQ B0.  怎样连系 [Borland, Microsoft] 等公司? 
     [注意:这份 FAQ 不在 rtfm.mit.edu 里;而在 Simtel 
            (譬如 oak.oakland.edu) in /pub/msdos/info/faqp*.zip 以及 Garbo 
            (garbo.uwasa.fi) in /pc/doc-net/faqp*.zip] 
  comp.os.msdos.programmer.turbovision [Borland 的文字模式应用程式骨架] 
 
  comp.unix.programmer 
     FAQ 4.5)  怎样使用 popen() 开启行程以读写之? 
     FAQ 4.6)  怎样在 C 程式里 sleep() 一秒以内? 
 
  comp.unix.solaris (包含 SunOS 4.x 和 Solaris) 
     FAQ 4)  Signal 入门 
     FAQ 5)  等待子行程 Exit 
 
  gnu.g++.help 
     FAQ: 到哪里找 C++ 的 demangler(反签名编码器)? 
     FAQ: 哪里有 Solaris 2.x 版的 gcc/g++ 位元档? 
     FAQ: 有 g++ 2.x 的文件吗? 
  gnu.g++.bug [g++ 的臭□列表 -- 请见 g++ 的文件] 
 
  comp.lang.c 
     FAQ 1.10: 我搞糊涂了。NULL 保证一定是 0,但是 null 指标却不是? 
     FAQ 2.3:  那麽,在 C 里头「指标和阵列等价」是什麽意思? 
     FAQ 4.2:  [为什麽 "printf("%d\n," i++ * i++);" 有问题?] 
     FAQ 7.1:  怎样写一个接收不定数目引数的函数? [stdarg.h 或是 varargs.h] 
     FAQ 10.4: 怎麽宣告一个指向某种函数的指标阵列,而该函数的传回值为: 
               指向另一个传回字元指标的函数? 
 
并请参考看看 comp.graphics、comp.sources.wanted、comp.programming,以及 
comp.object(它的 FAQ 是个很棒的 OOP 入门、术语观念概论文件)。请记住: 
comp.std.c++ 是专门讨论和研议中的 ANSI/ISO C++ 标准方案(下文会提)“直接 
”相关的事项。 
 
同时到上述信区和 comp.lang.c++ 去问同一个问题,几乎是没必要的(你是知道的 
,特定系统信区的读者不用机器语言写程式)。只因你的问题「真的很要紧」,就到 
处发问,是个很坏的习惯。如果你在「正确的」信区没得到回音,且认为你非得在这 
儿发信不可,请至少考虑一下,将这儿的回信重导回原来那个适当的信区。 
 
在任何信区发问之前,你应当先读读它的 FAQ。你想问的可能就在上面,这样就可省 
下你发信的时间,以及全世界数以千计的人类读你的信的时间。回答已经是 FAQ问题 
的人,可能会因为白白浪费时间而烦扰不已;他们也可能会给你错误或不完整的解答 
,因为他们也没看过 FAQ。 
 
「常见问题解答」文件每天 24 小时都可由 anonymous ftp (rtfm.mit.edu 的 
/pub/usenet/comp.what.ever) 或是 e-mail server (寄一则内容为 "help" 的信到 
mail-server@rtfm.mit.edu) 来取得。欲知详情,请见 "Introduction to the 
*.answers newsgroups" 这份文件,它在 news.answers 或 news.announce.newusers 
(这儿还有许多必须一读的文件)中找到。 
 
======================================== 
 
Q2:我该怎麽提出「我的程式有毛病」的问题呢? 
 
底下是一些建议,让 comp.lang.c++ 的读者能帮你解决程式设计的问题。 
 
1. 请读读上一个问题,以确定你的问题是针对 C++语言本身,而和你的程式设计系 
   统(譬如:绘图、印表机、设备……)或是编译环境(譬如:「整合环境挂了」 
   、「怎样消除xxxx警告讯息」、「怎样连结程式库」)完全无关。如果你想知道 
   为什麽你 OWL程式中的虚拟函数 CmOk() 没被呼叫到,你的问题可能比较适合放 
   在 Windows程式设计的信区。如果你能写个独立的小程式,而它会让编译器产生 
   和你那个 OWL程式同样的错误讯息或行为的话,就可以放到 comp.lang.c++ 了, 
   其他系统的 C++程式员可能帮得上忙。 
 
2. 「信件标题」栏位要有意义。像是「C++ 程式」这样的标题太空泛了,「new 一 
   个多维阵列的问题」就很好。不要用一堆惊叹号,穷嚷嚷著「救命啊」,或是开 
   玩笑的用「SEX SEX SEX」这种标题。如果你认为该问题和你的编译器有关,最好 
   在标题栏中道出编译器和版本编号。 
 
3. 列出完整的、可编译得过去的程式码。要从人类的语言叙述里,去除错或是重建 
   回一个程式,是极为困难的事。「完整的程式码」指的是:任何被用到的型别、 
   函数都要宣告出来,被用到的标头档都要 #include 进来……等等。请将程式码 
   裁减到只留必要的部份,我们并不需要那些执行起来(甚至连结时)“有用的” 
   东西,我们只须能重现出你的错误讯息(可能在不同的编译器中)就行了。「可 
   编译得过去」指的是:不要含有一堆未注解掉的 ... 这种删节号,或是各行行首 
   的行号: 
 
        14:     #include  
        15:     class Foo { ... };  // 像这样就是很讨人厌的东西! 
 
   将你的程式组织成线性结构,不要让我们再切割、制造些标头档案。请仔细输入 
   你的程式码--我们通常不容易判断:某个地方只是你的打字错误,抑或它真的 
   就是你的问题所在。尽量改用编辑器的「剪贴」或「插入档案」功能。 
 
4. 列出你用的编译器、编译器版本,以及你使用的系统。我知道我刚刚说过:特定 
   系统的问题要去特定的信区发问,但和编译器有关的资讯,常常对侦查问题有帮 
   助(「喔,我记得 Acme 1.2 在这方面有很多毛病」),这也顺便提醒了那些编 
   译器的用户:小心那些毛病。 
 
5. 把编译器、连结器的选项写出来,以及你用来建程式所用的程式库。 
 
6. 把错误讯息和何处发生错误的资料写出来。像是「虚拟函数不能用了」并没告诉 
   我们这是个编译时段、连结时段还是执行期的问题。如果这问题是执行期发生的 
   ,请把它的行为,和任何相关的系统设定资讯列出来。 
 
7. 在签名档中列出真的能用的 e-mail 地址。如果你信件的 "From:" 一栏有错的话 
   ,请通知你的系统管理者。在它修复前,於你的信件标头中加入 "Reply-To:" 一 
   栏,填上你正确的 e-mail 地址。 
 
8. 请读读这份 FAQ 的其他部份--可能你的问题,或是很相关的问题就在这儿。 
 
   谢谢您,并希望以上的建议能协助您找到问题的解答。 
 
 
=================================== 
■□ 第3节:周遭的、管理上的事项 
=================================== 
 
Q3:什麽是 OOP?什麽是 C++? 
 
物件导向(OO)程式技术,是我们所知发展大型而复杂的软体系统最好的方法。 
 
C++ 是个物件导向的程式语言。C++ 可当成一个物件导向程式语言(OOPL),亦可只 
当成一个“更好的 C 语言”来使用。不过,若你只把它当成“更好的 C”,你就无 
法获得物件导向程式设计的好处。 
 
提一则 OO 的广告词:软体工业刻正无法应付大型而复杂的软体系统需求。但这正是 
肇因於我们的「成果」:我们过去的成功促使大家要求得更多,不幸的是,这份市场 
的渴求却是「结构化」分析(analysis)、设计(design)和程式设计所无法满足的 
。因此,我们才得发展一个更好的典□(paradigm)。 
 
======================================== 
 
Q4:C++ 的优点是什麽? 
 
「C++ 的成长」:C++ 是到目前为止最受欢迎的语言。每 7.5到 9个月 C++的使用者 
都会加倍。「懂 C++」是个很好的求职资格(但你必须把它当成 OOPL,而不只是一 
个更好的 C 来用才行)。 
 
「封装性 encapsulation」:藉由隐藏内部的资料结构,让我们可以改变系统的某部 
份,而不必更动其他部份。我们为软体元件(称之为 class,类别)提供一个安全的 
介面,用户只碰得到这个介面而已;而相对起来比较容易变动的介面「实作」部份, 
就被封装起来(就像被包在胶囊里),以避免用户过於依赖他一时的实作决定。在比 
较简单的 C 里头,可由模组内的静态(static)资料来办到,以避免其他模组存取 
到它。 
 
「多重案例 multiple instances」:典型的 C 语言「封装」方法(刚才有提),做 
不到多重的资料案例(我们很难替模组的 "static" 资料做出多重案例)。如果在 C 
中要做到的话,我们得使用 "struct" 结构(但是它没有「封装性」)。在 C++里, 
我们可用 "class"(物件类别)来做到多重案例与封装性:"public"公共部份包含了 
它的介面(通常这里会有个特别的函数:成员函数),"private" 私有部份包含了它 
的实作细节(通常这儿就是内部资料结构的所在)。 
 
「行内函数呼叫」:在 C 中,可以在 struct 里放个 "void*"(该存取函数 [access 
functions] 会用到指标转型)来达到「封装的 structs」。这样会丧失型别安全性 
,而且会造成过多的函数呼叫,即使你只存取结构内的小小栏位(假如你允许直接存 
取结构内栏位的话,它内部的资料结构就很难再变更了,因为你的程式有太多地方“ 
依赖”它以前的样子)。函数呼叫的额外负担不大,但是会累积起来。C++ 的类别允 
许函数作 "inline" 行内扩展,就有以下好处:□封装的安全性,□多重案例的方便 
性,□直接存取的速度。而且,编译器也会检查行内函数的参数,这就比 C 的 
#define 巨集更好了。 
 
「多载运算子」:C++ 能对物件类别的运算子加以多载(overload),以合乎我们的 
直觉(譬如,"myString + yourString" 可做字串串接,"myDate++"可用来递增日期 
,"z1 * z2" 可将两复数 z1 及 z2 相乘,"a[i]" 可用来存取 "a" 这个连结串列的 
第 i 个元素……等等)。你甚至可以做出个“聪明的指标”(smart pointer),以指 
向磁碟或其他地方去("x = *p" 可 dereference [解参用] 指标,也就可以在磁碟 
中找到 p 所“指到”的地方,并传回其值)。这可让使用者以切近该问题的方式来 
写程式,而非以机器的语言来解题。 
 
  【译注】STL (Standard Template Library) 就大量利用到「聪明的指标」功能。 
 
「继承性 inheritance」:我们还只是在表层而已,事实上,我们还没进入「物件导 
向」的部份呢!假设你有个 Stack 堆叠型态,有 push、pop 运算。若你还想要个 
InvertableStack 型态,它“很像”Stack,只是它还有个 "invert" 运算。以 C 的 
方式,你不是得□修改现存的 Stack模组(如果它在其他地方也用到的话,就麻烦了 
),就是得□把 Stack拷贝到另一个档案,再加以修改之(这会导致过多重复的程式 
码、容易破坏到 InvertableStack 里某些源自 Stack 的小地方,尤有甚者,得维护 
双倍的程式码)。C++提供了更乾净的解决法:继承。你可以说:「InvertableStack 
继承了 Stack的一切,且 InvertableStack又添加了 invert 运算。」这样子就好了 
!Stack本身仍然是封闭的(未被更动到),而 InvertableStack也没重复 push/pop 
等的程式码。 
 
「多型」与「动态系结」:OOP 真正的力量不仅是继承性,还有把 InvertableStack 
当成是一个 Stack来传递的能力。这是安全的,因为(至少在 C++里)此乃「是一个 
……」的关系("is-a" relation),透过公共继承达到的(亦即:InvertableStack 
“是一个”Stack,且它还能自我 invert 反转)。多型(polymorphism)与动态系 
结(dynamic binding)最容易从实例来理解了,所以我提个典型的例子:绘图软体 
得处理圆形、方形、矩形、多边形及直线,这些都是「形状 shape」。大部份绘图软 
体的内部函数都需要个“形状”的参数(相对於某些像是“方形”这种特定的形状) 
,譬如:当我们用滑鼠选取某个图形,它就可能被拖曳放到萤幕某处。多型和动态系 
结让程式能正确运作,即使编译器只知道该参数是个「形状」,而不知它到底是什麽 
形状。我们再假设刚才提到的 "pick_and_drag(Shape*)" 函数於星期二编译好了, 
到了星期三,你打算再加个六边形。听起来很奇怪,但 pick_and_drag() 仍然能够 
处理这个六边形,即使当 pick_and_drag() 编译时六边形还不存在!(若你明了 
C++ 是怎麽做的,它就再也不惊异了--但它仍然是很方便的!) 
 
======================================== 
 
Q5:谁在用 C++? 
 
很多很多的公司及政府部门。相当的多。 
 
统计上来看:当你正在读这份 FAQ文字时,就有 5 个人正成为 C++的程式员。 
 
======================================== 
 
Q6:有任何 C++ 标准化方案在进

上一页  [1] [2] [3] [4] [5] 下一页






  • 上一篇文章:
  • 下一篇文章:
  • 分享此文:该页面添加到 Mister Wong 添加到雅虎Yahoo!收藏 Add to:Del.icio.us Post to Furl Digg this 添加到Google书签 reddit spurl blogmarks 365Key 评论  收藏  分享  打印
     我来说两句
    姓名:       验证码:   
    主页: 
    评分: 1分 2分 3分 4分 5分
    本频道近期热评文章:
      关于我们 | 联系我们 | 站点地图 | 广告投放 | 友情链接 | 在线留言 | 版权申明
    版权所有 © 2004-2007 顶尖设计(bobd.cn)
    未经授权禁止转载,摘编,复制本站内容或建立镜像. 沪ICP备07504942号 
    网络110
    报警服务