指標使用應注意的小細節。

指標(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的使用法,然後試試看,尤其是處理中文會出現啥問題。如果園友們已經將此功能完整,歡迎您將原程式碼傳給園主,讓大家分享您的作品,使更多的人受益。謝謝!