程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> MFC的一些實用的基礎知識

MFC的一些實用的基礎知識

編輯:關於C語言

一、_T()函數

_T("")是一個宏,他的作用是讓你的程序支持Unicode編碼。因為Windows使用兩種字符集ANSI和UNICODE,前者就是通常使用的單字節方式,但這種方式處理象中文這樣的雙字節字符不方便,容易出現半個漢字的情況。而後者是雙字節方式,方便處理雙字節字符。

Windows NT的所有與字符有關的函數都提供兩種方式的版本,而Windows 9x只支持ANSI方式。如果你編譯一個程序為ANSI方式,_T實際不起任何作用。而如果編譯一個程序為UNICODE方式,則編譯器會把"Hello"字符串以UNICODE方式保存。_T和_L的區別在於,_L不管你是以什麼方式編譯,一律以UNICODE方式保存。

  • LPSTR:32bit指針指向一個字符串,每個字符占1字節。
  • LPCSTR:32-bit指針指向一個常字符串,每個字符占1字節。
  • LPCTSTR:32-bit指針指向一個常字符串,每字符可能占1字節或2字節,取決於Unicode是否定義。
  • LPTSTR:32-bit指針每字符可能占1字節或2字節,取決於Unicode是否定義。

L是表示字符串資源為Unicode的。比如 wchar_t Str[] = L"Hello World!"; 這個就是雙子節存儲字符了。

_T是一個適配的宏。當 #ifdef _UNICODE 的時候 ,_T就是L。沒有#ifdef _UNICODE的時候,_T就是ANSI的。

比如:

LPTSTR lpStr = new TCHAR[32];
TCHAR* szBuf = _T("Hello");

以上兩句使得無論是在UNICODE編譯條件下都是正確編譯的。而且MS推薦你使用相匹配的字符串函數。比如處理LPTSTR或者LPCTSTR 的時候,不要用strlen,而是要用_tcslen。否則在UNICODE的編譯條件下,strlen不能處理 wchar_t*的字符串。

T是非常有意思的一個符號(TCHAR、LPCTSTR、LPTSTR、_T()、_TEXT()...),它表示使用一種中間類型,既不明確表示使用 MBCS,也不明確表示使用 UNICODE。那到底使用哪種字符集?編譯的時候才決定。

將char字符串轉換成Unicode字符串。 T是個宏,不是函數。在需要雙字節的函數,或COM裡需要雙字節的串。為了國際兼容。其實很簡單。Visual C++裡邊定義字符串的時候,用_T來保證兼容性,VC支持ascii和unicode兩種字符類型,用_T可以保證從ascii編碼類型轉換到unicode編碼類型的時候,程序不需要修改。

如果將來你不打算升級到unicode,那麼也不需要_T,_t("hello world") 在ansi的環境下,它是ansi的,如果在unicode下,那麼它將自動解釋為雙字節字符串,既unicode編碼。這樣做的好處,不管是ansi環境,還是unicode環境,都適用。

在vc++中的字符串_T("ABC")和一個普通的字符串“ABC”有什麼區別?_T("ABC")表示如果定義了unicode,它表示 L"ABC",每個字符為16位,寬字符字符串。if not UNICODE,它就是ascii的"ABC",每個字符為8位。"ABC"就是指ascii字符串"ABC"。相當於:

#ifdef _UNICODE
#define _T("ABC") L"ABC"
#else
#define _T("ABC") "ABC"
#endif

_T("ABC")中的一個字符和漢字一樣,占兩個字節,而在"ABC"中,英文字符占一個字節,漢字占兩個字節。

二、堆和棧

1、“堆”和“棧”在C++中主要是指存放數據或者說是變量、對象的在內存中的區域,如同現實中美國和中國的區別,表面上是在內存中的位置不同,但是分配內存的方式卻大不相同,如同美國和中國雖然表面上都是國家,但是社會制度、各種福利各種機構都不同,一句話就是內存中的不同區域。

2、C++中“堆”:在一個程序中堆是一片內存,不是有堆內存之說,一般都是程序員手動分配,在C++中則是一般用new操作符(如果不使用C的malloc系列,好像只能用new)分配的內存,同樣也只能程序員手動釋放,不然會有內存洩露。當然了給什麼分配內存,那只能給變量、類對象分配,所以存放的也是類對象和變量。

3、C++中“棧”:是程序自動分配的內存,比如調用某個函數,傳遞參數時(值傳遞),那麼這個參數的值是在“棧”內存上分配的,當這個函數退出後占用的“棧”內存也就自己釋放了。

三、Windows Socket

Socket的實現方法:

Socket是連接應用程序與網絡驅動程序的橋梁。它在應用程序中創建,通過綁定操作與驅動程序建立關系。此後,應用程序送給Socket數據,由Socket交給驅動程序,驅動程序再把數據向網絡上發送出去。計算機從網絡上收到與該Socket綁定的IP地址和端口號相關的數據後,由驅動程序交給Socket,應用程序便可從該Socket中提取接收到的數據。網絡應用程序就是這樣運用Socket進行數據的發送與接收的。

ISO/OSI七層參考模型(ISO:國際標准化組織 OSI:Open System Interconnection):

  • 物理層:提供二進制傳輸,確定在通信信道上如何傳輸比特流。
  • 數據鏈路層:提供介質訪問,加強物理層的傳輸功能,建立一條無差錯的傳輸線路。
  • 網絡層:提供IP尋址和路由。因為在網絡上數據可以經由多條線路到達目的地,網絡層負責找出最佳的傳輸路線。
  • 傳輸層:為源端主機到目的端主機提供可靠的數據傳輸服務,隔離網絡的上下層協議,使得網絡應用與下層協議無關。
  • 會話層:在兩個相互通信的應用進程之間建立、組織和協調其相互之間的通信。
  • 表示層:處理被傳送數據的表示問題,即信息的語法和語義。

對等層通信的實質:對等層實體之間虛擬通信。下層向上層提供服務,實際通信在最底層完成。

各層所使用的協議:

  • 應用層:遠程登錄協議Telnet、文件傳輸協議FTP、超文本傳輸協議HTTP、域名服務DNS、簡單郵件傳輸協議SMTP、郵局協議POP3。
  • 傳輸層:傳輸控制協議TCP、用戶數據報協議UDP。
  • 網絡層:網際協議IP、Internet互聯網控制報文協議ICMP、Internet組管理協議IGMP。

TCP/IP模型:應用層、傳輸層、網絡層、網絡接口層。

TCP/IP模型與OSI模型對照如下:

  • 應用層:應用層、表示層、會話層。
  • 傳輸層:傳輸層。
  • 網絡層:網絡層。
  • 網絡接口層:數據鏈路層、物理層。

端口:一種抽象的軟件結構(包括一些數據結構和I/O緩沖區)。

套接字的類型:

  • 流式套接字(SOCK_STREAM),基於TCP協議實現。
  • 數據報套接字(SOCK_DGRAM),UDP協議實現。
  • 原始套接字(SOCK_RAW)

Windows Socket “TCP”網絡編程實例,一些開發步驟如下。
“TCP”服務器端:

  1. 加載套接字庫。
  2. 創建套接字。
  3. 綁定地址信息。
  4. 綁定套接字。
  5. 監聽套接字。
  6. “Accept”等待用戶請求。
  7. “send”發送數據。
  8. "recv"接收數據。
  9. 關閉“使用中的套接字”,繼續循環等待。

“TCP”客戶端:

  1. 加載套接字庫。
  2. 創建套接字。
  3. 綁定地址信息。
  4. 綁定套接字。
  5. 發出請求。
  6. 接收數據。
  7. 發送數據。
  8. 關閉套接字。
  9. “WSACleanup”終止“套接字庫”的使用。(服務器端一直循環運行,所有沒有)。

對於UDP通信,不需要建立連接,直接進行收/發就可以了。

四、多線程

1、程序和進程

程序是計算機指令的集合,它以文件的形式存儲在磁盤上。而進程是正在運行的程序的實例。比如,我們編譯生成的“exe”文件是一個可執行程序,存儲在磁盤上就是程序。點擊運行後,就啟動了該程序的一個實例,我們稱之為進程。一個程序可以有多個進程,也就是一個程序可以產生多個實例。

2、進程和線程

進程從來不執行任何東西,它是線程的容器,真正完成代碼執行的是線程。單個進程可能包含若干個線程,但至少包含一個主線程。

3、進程的地址空間

系統賦予每個進程獨立的虛擬地址空間。對於32位操作系統,運行32位的進程,這個地址空間是4G。因為對於32位指針來說,它的尋址的范圍是2的32次方,即4G。這就是為什麼32位操作系統,內存條一般不超過4G的原因。

4、虛擬內存。

在磁盤上有一個“pagefile.sys”文件,它是頁文件,頁文件透明的為應用程序增加了內存,這一部分就是虛擬內存。

5、線程。

  • 線程的內核對象:操作系統用來存放線程統計信息的小型的數據結構。
  • 線程棧:它用於維護線程在執行代碼是所需要的所有函數參數和局部變量。

同一個進程的不同線程運行在同一個進程環境下,它們共享資源,所以可以非常容易的實現相互之間的通信。線程運行在操作系統為其分配的CPU時間片上,對於單核CPU,就要多個線程來回切換。多核CPU就可以實現多個線程的並發執行。采用多線程而不是多進程,是因為線程只有一個內核對象和一個棧,占用內存少。而對於進程每一個都要分配4GB的虛擬地址空間,占用資源多。而且進程切換需要交換整個地址空間。線程之間的切換只是執行環境的改變。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved