- Visual C++程序設計與項目實踐
- 安金梁 范秀平主編
- 2027字
- 2018-12-27 18:49:09
1.5 Visual C++ 6.0編寫的程序轉化到Visual C++ 2008中的方法
由于VC++6.0版本的廣泛使用,使得以前很多優秀的代碼都是使用VC++6.0編寫的;同時,VC++2008相對于對VC++6.0做了很大的改進,應用程序的安全性和效率有了很大的提高。為了同時有效地利用VC++6.0眾多優秀的源代碼和VC++2008編譯環境的重大改進,介紹VC++6.0到VC++2008的轉換方法顯得特別重要。
由于本節內容有一定難度,初學者可以跳過本節,等學完本書全部內容再學習本節。也可以先讀一遍本節,帶著問題去讀本書下面的章節。
1.5.1 多字節字符集和Unicode字符集
在計算機中字符通常并不是保存為圖像,每個字符都是使用一個編碼來表示的,而每個字符究竟使用哪個編碼代表,要取決于使用哪個字符集(charset)。
在最初的時候,Internet上只有一種字符集——ANSI的ASCII字符集,它使用7b來表示一個字符,總共表示128個字符,其中包括了英文字母、數字、標點符號等常用字符。之后,又進行擴展,使用8b表示一個字符,可以表示256個字符,主要在原來的7b字符集的基礎上加入了一些特殊符號例如制表符。
后來,由于各國語言的加入,ASCII已經不能滿足信息交流的需要,因此,為了能夠表示其他國家的文字,各國在ASCII的基礎上制定了自己的字符集,這些從ANSI標準派生的字符集被習慣的統稱為ANSI字符集,它們正式的名稱應該是MBCS(Multi-Byte Chactacter System,即多字節字符系統)。由于每種語言都制定了自己的字符集,導致最后存在的各種字符集實在太多,在國際交流中要經常轉換字符集非常不便。因此,提出了Unicode字符集,它固定使用16b(兩個字節、一個字)來表示一個字符,總共可以表示65536個字符。將世界上幾乎所有語言的常用字符收錄其中,方便了信息交流。標準的Unicode稱為UTF-16。后來為了雙字節的Unicode能夠在現存的處理單字節的系統上正確傳輸,出現了UTF-8,使用類似MBCS的方式對Unicode進行編碼。
在Visual Studio 2005以前版本的Visual Studio默認使用多字節字符集,而Visual Studio 2005、Visual Studio 2008默認使用Unicode字符集。如果您的代碼必須要借助以前版本的VC++編寫的代碼,可以采用兩種方法將VC++6.0中的代碼加入到VC++2008中:
1. 將VC++6.0中的ANSI字符和字符串換成Unicode形式,并使用相應的字符和字符串操作方法。對于初學者來說該方法難度較大。
2. 設置VC++2008參數,將應用程序工程的屬性從“使用Unicode字符集”改為“使用多字節字符集”。該方法使用起來非常簡單。
將應用程序工程的屬性從“使用Unicode字符集”改為“使用多字節字符集”的方法是:假如我們對VC++2008中創建的工程“ProgramChapt0102”進行方法2的設置,我們只需在菜單“項目”中鼠標左擊選擇“ProgramChapt0102屬性”菜單項,就會彈出如圖1-8所示的窗口。在“配置屬性”的“常規”項中,將“字符集”改為“使用多字節字符集”即可。

圖1-10 VC++2008中使用多字節字符集的設置方法
1.5.2 安全函數
首先舉個例子,在VC++6.0中編譯下面的語句:

圖1-11 strcpy示例代碼
結果是沒有錯誤和警告。
但是在Visual C++ 2008中編譯上面的語句,就會出現如圖1-12所示的警告:

圖1-12 Visual C++ 2008中關于安全函數的警告
在Visual C++ 2008中,CRL(C Runtime Library)中的一組函數已不再建議使用,而應使用新提供的安全版本。大多數這些不建議使用的函數如果使用不當,將會導致緩沖區溢出或其他安全問題,這些函數如:strcpy、strcat等等。這些函數新的安全版本都在函數名后加了一個_s后綴,以方便識別,如strcpy_s、wcscpy_s、mbscpy_s、calloc_s和strcat_s等。
去除圖1-12所示的警告的方法有兩種:
1. 繼續使用老版本、非安全的函數,在預編譯頭文件stdafx.h里(注意:一定要在沒有include任何頭文件之前)定義下面的宏:
#define _CRT_SECURE_NO_DEPRECATE
或者
#pragma warning(disable:4996)
2. 使用新的安全函數代替舊的不安全的函數。
我們不建議使用方法1,因為非安全函數的不當使用會導致緩沖區溢出或其他安全問題,而這些安全問題很可能會使應用程序崩潰。比如我們將圖1-11中的代碼改為圖1-13所示,即buf2的大小改為4個字節,而buf1占用的內存大小為6個字節(5個字符加上一個"\0"結尾標志),此時buf2的空間小于buf1的空間。在Visual C++6.0下編譯時不會出錯,但是在Release狀態下運行時會使程序崩潰,如圖1-15所示。

圖1-13 strcpy函數緩沖區溢出錯誤示例代碼

圖1-14 strcpy_s函數緩沖區溢出錯誤示例代碼

圖1-15 strcpy緩沖區溢出錯誤造成Visual C++6.0程序崩潰
但如果我們使用Visual C++ 2008編譯如圖1-14所示的代碼,在"Release"方式下編譯,就會出現如圖1-16所示的警告:

圖1-16 strcpy_s函數緩沖區溢出時Visual C++ 2008編譯器發出警告信息
從上面分析可以看到,使用安全函數是Visual C++ 2008相對于Visual C++6.0的一個巨大的改進。
1.5.3 Visual C++ 2008相對于VC++6.0的其他改進
Visual C++ 2008相對于VC++6.0還有其他方面的改進,在使用Visual C++ 2008進行編程時,也要留意這些變化。對初學者來說,主要有以下方面需要注意:
1. 參數的有效性
Visual C++ 2008在C運行時庫中加入了一些代碼,以檢查參數的有效性。例如:如果傳遞的目標緩沖區大小不足以strcpy使用,此時則會調用一個非法參數處理程序。
2. 迭代器越界
迭代器因為安全的原因進行了相應的更新,如果迭代器越界,則相應會調用一個非法參數處理程序。
3. time_t類型
time_t類型通常用于顯示從1970年開始以來的秒數。直到Visual C++ 7.1(即Visual C++ .NET 2003),time_t類型都被定義為一個long,而到了Visual C++ 2005和Visual C++ 2008中,已被定義為一個64位類型,可用于顯示一直到3000年的時間了。
4. 范圍限制規則
在for循環聲明中,默認情況下不強制執行范圍限制規則。在之前的版本中,for循環中變量的生命期將會延續到循環之外,為與標準兼容,for循環中定義的變量,現在只限定在for循環內使用。
- 計算機網絡
- 移動UI設計(微課版)
- Java高并發核心編程(卷2):多線程、鎖、JMM、JUC、高并發設計模式
- 基于免疫進化的算法及應用研究
- Learning Neo4j 3.x(Second Edition)
- Kotlin Standard Library Cookbook
- C++ 從入門到項目實踐(超值版)
- Learning SciPy for Numerical and Scientific Computing(Second Edition)
- Hands-On JavaScript for Python Developers
- C++語言程序設計
- Scala編程實戰
- Web Developer's Reference Guide
- Shopify Application Development
- 實戰Python網絡爬蟲
- Java多線程并發體系實戰(微課視頻版)