指标使用应注意的小细节。

指标(Pointer,有些书本会翻译成指位器)是 C/C++ 语言最强而有力之处。少了指标,可能有很多软体的功能都做不出来…

初学指标的运用,比较常犯的错误是,要使用该指标前,没有先初始化。如果您看书看的比较仔细,您会发现,许多书本上都会一再强调,「指标要初始化」。甚至有些书本会比较夸张地说,指标没经过初始化而使用,後果严重,自行负责…

举个例子来说,

double MyWeight = 75.0;
double *dp;
cout << "我的体重:" << *dp << "公斤" << endl;

这个时候,好一点编译器有可能会秀出错误或是警告。当然也有可能编译成功,然後在画面上出现

我的体重@xss~sdsds公斤

出现乱码的原因是,该指标指可以指到记忆体的任何一个位置,而如果改成

double MyWeight = 75.0;
double *dp;
dp = &MyWeight;
cout << "我的体重:" << *dp << "公斤" << endl;

这个时候画面就会出现正确的讯息了。

当然,关於指标的初始化,最好是在宣告的时候就同时初始化,上面的例子,可以根据这个观念再改写成,

double MyWeight = 75.0;
double *dp = &MyWeight; //宣告并且初始化
cout << "我的体重:" << *dp << "公斤" << endl;

总之,使用指标的小细节就是,「指标要初始化」。


应该学C++ Builder好呢?还是Delphi?VB怎麽样…

关於学习电脑语言的问题,实际上困惑了很多想学程式设计的初学者,在Newsgroup 上,这个问题大概每天都会有人问,而也有不少的新人写信来问这个问题…

在说明这个问题之前,最最重要的,要弄清楚学习这些电脑语言的目的。说实在的,电脑其实很笨蛋的,所有要完成的工作都必须你告诉它怎样做,它才会做。

其实各种开发工具都有它们先天上的优点与缺点,这也是目前为止还没有所谓统一的电脑语言出现的原因。早在70、80年代,像是美国国防部、IBM都试图统一电脑语言,这也是我们所知道的Ada与PL/2等语言的问世。即使在90年代,一个新生的语言-Java,也试图使用Virtual Machine的观念,统一所有的平台与作业系统,企图达到Write Once and Run Anywhere。这样的宏伟的企图,不得不令人折服,但是自发表至今,Java似乎只成为Internet上炫炫Applet的做手,像是Corel的以Pure Java开发的Office系列的应用软体,如今也已经…何以故?因为伟大的企图使得原有利益拥有者的利基将丧失无存 。

因此,在学习上述的电脑开发工具之前,我通常会问,你想用它来做什麽?如果纯粹是个人兴趣,想要玩玩这些工具的话,那麽,哪一个都可以。如果想要用它们来完成一些超大型的运算工作,那我会建议使用C++ Builder,或是Delphi,因为VB编译的执行档,效率太差了。如果想要轻松上手,训练程式逻辑的观念,那麽,VB是最佳选择。

甚至有些人问,如果想要写一个留言版之类的Internet应用呢?这时候,上面叁者都做得到,只是会被局限在Windows平台内,而此时的选择就变成了Perl。 目前Internet的伺服器大多都是Unix平台(Linux,FreeBSD也算是),Windows虽然慢慢追上,但仍然相差太远。更何况Perl不仅仅支援Unix,Windows也在支援之内 ,换句话说,Perl在这一类的应用,具有可携性。

回归重点,您想要用它们来做什麽?如果考虑清楚後,这样的学习不仅仅对您个人帮助良多,同时更可以激励学习其他的电脑工具。毕竟,电脑的发展太快了,随时都可能有革命性的技术出现,唯有时时刻刻保持一颗有弹性、柔软的心,才能在这样变化迅速的环境中,如鱼得水。

PS:您或许会觉得很奇怪,为什麽回答中,电脑工具这个字眼用得比电脑语言多。这是因为,基於各原有利益拥有者的背景之下,电脑语言的观念已渐渐消失了。早些时候,学习BASIC语言,您可以用微软的编译器,叫做Quick Basic,也可以用Borland (Inprise) 的编译器,叫做Turbo Basic,甚至是其他厂商的编译器,像是GW Basic,True Basic…然而在资讯领域太过於竞争的今天,每家都只剩下最最主要的产品,像是微软的 Visual Basic, Borland (Inprise) 的 Delphi 等等。这时候,我们几乎已经别无选择的馀地,如果想要使用Pascal的语法,只有Delphi,而Basic的,只有Visual Basic…虽然在C++ 这个领域上,我们还有许多选择,像是C++ Builder、Visual C++、Visual Age、Wacton C++、djgpp…,但会不有一天,沦落到和Basic,Delphi相同的命运呢?

基於以上的理由,这也是我不用电脑语言,而使用电脑工具这个名词的原因。


关於各个开发工具编译出来执行档的效率...

[Part 1]

因为我目前正在用 VB 6.0 设计一个拥有 " 大量回圈,而且每个回圈里面都有大量的运算和判断 " 的程式,因为全部执行完毕必须花费 " 150 ~ 300 小时以上的时间 ",可是因为必须要在 " 5 分钟以内的时间 " 执行完毕,所以我想要请问站长您一些问题!!

1. 有可能把需要 " 150 ~ 300 小时以上的执行时间 " 缩减为只需要 " 5 分钟以内就可以执行完毕 " 吗??

2. 请问用 BC++B 4.0 设计比用 VB 6.0 设计还要再快多少??

3. 请问用 MASM 6.11 设计比用 VB 6.0 设计还要再快多少??

4. 请问用 MASM 6.11 设计比用 BC++B 4.0 设计还要再快多少?? ( 以上所问的问题都是已经把 " 速度最佳化 " 的功能给全部都打开了!! ) ?

[Part 2]

1. 此程式是指在 " P!!! 550 以上 or K7 550 以上、128 MBytes RAM 以上 ( 100 外 频以上!! ) " 需要执行 " 150 ~ 300 小时以上的时间 " !! ( 但是必须 " 缩减为只 需要 " 5 分钟以内就可以执行完毕 ",有可能办得到吗?? )

2. 此程式有 " 大量的复杂的回圈,而且每个回圈里面都有大量的复杂的运算和复杂的 判断 ",而且也有 " 大量的复杂的记忆体存取 ( 因为 " 所有的 " 复杂的运算资料都 存放在记忆体里面,所以必须要不断的存取记忆体!! ) " !!

3. 告诉您一个笑话 ( 不过这是真的!! ) !!我以前所想出来的演算法大概要运算 " 12 ~ 18 个月以上 ",而我经过了多次的想新的演算法,目前的这个演算法算是 " 目前 " 所想得到最快的演算法了 ( 我辛苦研究这个程式从 " 1997/05/01 ~ 现在 " 才想到目 前的这个最新的演算法!! ),因为变成只需要 " 执行 " 150 ~ 300 小时以上的时间 " 就可以执行完毕了 ( 哈! ) !!所以我想目前的瓶颈可能就是卡在 " 编译器 " 了!! 不知道您是不是也觉得是如此呢!?...哈! )

4. 目前的整个程式完全都是在 WIN98 底下使用 VB 6.0 来设计的!!

[Part 1]

关於您的问题,园主实在很难回答,因为牵涉的层面很广泛… 加上您只给了一些资讯,所以很难回答您的问题。 因为运算的时间,除了使用的编译器有影响之外, 您所使用的硬体,您所使用的算法,您对於您所使用的系统 (这包含了所有你所用到的软体组合,像是作业系统,编译器的熟悉度), …

您在留言簿上的问题,我很早就已经看到了,但因为您没有留下任何的资讯, 所以无从回答起…

编译最佳化的功能,其实只能帮你一些忙,如果程式码的品质不够好, 编译器最佳化也无法发挥很大的作用…像是您所提到的那个专案, 跑起来需要150~300小时,用VB6完成的。但是,请问您的机器等级是?? ,记忆体多少,有用到网路吗?诸如此类的问题,其实都是一些必须提供的资讯。

VB很适合用来开发一些软体雏形(prototype),而且用於非大量计算的应用上, 这是Basic语言先天上的优势与劣势,主要是因为它不提供pointer的运算, 因此,如果程式中牵涉到大量记忆体存取的话,它必须自己先拷贝一份相同的 资料,然後再动作。偏偏记忆体拷贝个动作,又是很耗费时间的,这也就说明了 Visual Basic不适合用於大量的运上上了,因为它必须不停拷贝记忆体的相关内容。 如果您有使用Delphi,C++ Builder或是VC++,这些动作都可以用指标取代,甚至直接使用 CPU的暂存器。CPU的暂存器的速度比起记忆体的存取又不知道快了数百倍… 这是其一。

VB编译的程式也可以在Dec Alpha的机器上面跑。请问您的机器是Dec Alpha的吗? 还是您的机器只是Petium-100呢?[当然,您必须有微软VB编译器於Dec Alpha上的版本] 使用组合语言来写这些程式,於执行时的效率在理论上是要快很多,因为它与机器码几乎是 一一对应的。您可以拥有最完整的CPU与硬体控制权,但是发展软体的时间将会很长 ,侦错相当不易。用Visual Basic,则开发的时间可以缩短很多,侦错容易…

或许您的那个回圈,可以使用其他开发工具,像是C++ Builder、Delphi或是VC++ 写成.dll,然後使用Visual Basic来呼叫使用,效率或许会有改善。 您这个问题其实很大,很不好回答。因此只就粗浅的皮毛,略述一二。

[Part 2]

「如果程式中牵涉到大量记忆体存取的话,它必须自己先拷贝一份相同的 资料,然後再动作。偏偏记忆体拷贝个动作,又是很耗费时间的,这也就说明了 Visual Basic不适合用於大量的运算上了,因为它必须不停地拷贝记忆体的相关内容。」

如果换成使用C++或是其他的编译器,速度理论上会快上十倍或是百倍。 建议您用VC++或是C++ Builder或Delphi将那一部份的回圈写成一个.dll, 然後於VB里面使用看看,检查一下效率。 如果还不行,就在使用VC++或是C++ Builder或Delphi内使用内嵌组合语言的方式,尽量使用暂存器(Register), 来提升执行效率。(这种方法我已经用了好多次,最明显地是将 8个小时的执行时间,浓缩成28秒,机器是Petium-133)


请问本园的原程式码之授权内容?

请遵循以下的授权:

    1. 保留原有创作者的姓名与相关的创作资讯。
    2. 如果商业应用,仅散发执行档而没有散布相关原程式码,请於软体的相关说明中注明所使用的原程式码之相关创作者资讯。例如,於Help中的About中增加Special Thanks或是在使用手册中注明。
    3. 如遵循以上内容,可免费使用、散布与修改原程式码。
    4. 如不同意上述内容,请勿下载使用

我可以在本园分享我的创作吗?

非常欢迎各位园友们一起来灌溉这块属於大家的乐园。


…,C++ Builder,Delphi,与Visual Basic的版本为… ,是否所有的版本都可以成功编译?

C++ Builder 4 Enterprise with Patch 2(1999/11/28 Updated) ,Delphi 4 Enterprise with Patch 3 (1999/08/20 Updated),Visual Basic 6 Enterprise with Service Pack 3 (1999/08/20 Updated)。有关资料库的实作,BDE的版本是5.01。

因为没有在其他的版本下测试编译,无法说明这一问题。虽然成功编译是很重要的,而我们却更该重视编译後的执行档是不是正确!这话怎麽说呢?像是以C++ Builder 3开发的PiBan,在C++ Builder 4可以成功编译,但是编译後的执行档有问题-Ini档案的读写就不正确[後来发现,这是因为 C++ Builder 4对於事件的触发顺序改变了。在 C++ Builder 3 ,Form的最先触发的事件是Form的预设建构函式,然後才是OnCreate事件,然而,4版中,最先触发的事件却是OnCreate,然後才是建构函式。这一点改变,造成我对4版的误解,以为VCL的实作上有Bug…大家可以研究AutoPing的原始码,就了解这一个触发顺序改变之後而造成的错误。]。

补充说明一些个人的心得,个人目前拥有两架笔记型电脑,一架工作用,另一架为实验用。工作用(此电脑名之为Power)的环境为Pentium MMX-166,128MB RAM,6.4 GB Hard Disc (1999/08/20 Updated),作业系统为Windows NT 4.0 Service Pack 5(1999/07/13 Updated)与Windows 98;实验用的硬体(此电脑称做Dudu3)则为Pentium 166,32MB RAM,1.08 GB + 2.4GB + 3.2GB + 6.5 GB + 3.2 GB(1999/08/20 Updated)Hard Disc,硬碟模组很方便更换,不同的硬碟都装了很多不同的实验软体,像是Linux、Windows 2000、Visual Studio 6…。此外,Dudu3还用於软体安装的测试与Client/Server架构中的Client端。

电脑的发展速度很快,很惊人,往往新的还学不到十分之一,更新的就出现了。然而这样的「快」也意味着「不稳定」。早在Visual Basic 4的时候,开发了一些商用的软体(当然最早是在Windows 3.1环境下的Visual Basic 3,然而只是学习使用,谈不上开发实用性质的软体),因为Visual Basic 5的出现,其中的一些特点很迷人,比如说编译成机器码,速度可以提升20倍(微软的说辞,的确快一些,但…),可以开发控制项与更完备的物件支援…,园主毫不犹豫升级到Visual Basic 5,接着就是一些灾难性的情节发生了!Windows 的Common Control升级有点错误,要修改一些地方…这些错误,在勤奋的努力下,以一些额外的程式码克服了,然而随之Service Pack 1 出现了,这错误被修正了。随之Service Pack 2 也诞生了,然而更新後,印表出了一些字型不正确的问题,又免不了额外的苦工…,没多久,Service Pack 3 出现在网路上,这个Bug又被微软解决了。我真的很想骂脏话,为什麽这样的情节总是一再地重复呢?相同的列表问题,也出现在从Windows 95更换到Windows NT 4.0之下, 因为有一些印表机的属性设定,在NT下不被支援…

为了能研究相关Client/Server与Multi-tier的课题,多了Power。从这个时候起,为了解决上述令人厌烦的情节,Power用於工作上,讲求稳定;而Dudu3则转换为测试平台。一方面维持工作的稳定,另一方面可了解新技术,跟得上潮流。除非新的技术有令人心动的理由与具备相当的稳定性抑或时势所趋,否则不升级。园主有一个不成文的原则,提供给大家参考:

微软出的新软体,如果到Service Pack 3,则考虑成为工作环境。

Inprise最近的软体品质也…,如果有Patch 1 之後,才考虑升级成工作环境。


为什麽EasyEdit编译後,其中Replace的功能有问题,但是看了原程式码,只是呼叫ReplaceDialog->Execute()…还需要一些相关的处理吗?(1999/06/16)

的确还需要一些相关的处理,如果只使用内建的相关函式,处理中文时,会出现问题。很抱歉,那时因为没有更仔细考虑,因此这项功能并没有实作,只有一个空壳而已。各位不访参考On-Line Help查阅Replace Dialog的使用法,然後试试看,尤其是处理中文会出现啥问题。如果园友们已经将此功能完整,欢迎您将原程式码传给园主,让大家分享您的作品,使更多的人受益。谢谢!