15天學(xué)習(xí)C語言Windows程序設(shè)計_第1頁
15天學(xué)習(xí)C語言Windows程序設(shè)計_第2頁
15天學(xué)習(xí)C語言Windows程序設(shè)計_第3頁
15天學(xué)習(xí)C語言Windows程序設(shè)計_第4頁
已閱讀5頁,還剩116頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

目錄TOC\o"1-5"\h\z\o"CurrentDocument"C語言Windows程序設(shè)計->第一天->第一個Windows程序 -2-\o"CurrentDocument"C語言Windows程序設(shè)計ー>第二天一〉A(chǔ)SCII與Unicode -6-\o"CurrentDocument"C語言Windows程序設(shè)計ー〉第二天一〉寬字符和C語言 -7 -C語言Windows程序設(shè)計-〉第三天-〉Windows版printf -10-\o"CurrentDocument"C語言Windows程序設(shè)計ー〉第三天一〉屬于自己的窗口 -12\o"CurrentDocument"C語言Windows程序設(shè)計ー〉第四天-〉詳解我的窗口(上) -16\o"CurrentDocument"C語言Windows程序設(shè)計-〉第四天-〉詳解我的窗口(中) -20-\o"CurrentDocument"C語言Windows程序設(shè)計-〉第四天-〉詳解我的窗口(下) -24-\o"CurrentDocument"C語言Windows程序設(shè)計-〉第五天-〉回顧與反思 -28-\o"CurrentDocument"C語言Windows程序設(shè)計-〉第六天-〉GDI與設(shè)備環(huán)境 -29-\o"CurrentDocument"C語言Windows程序設(shè)計-〉第七天-〉TextOut與系統(tǒng)字體 -32-\o"CurrentDocument"C語言Windows程序設(shè)計-〉第ハ天-〉滾動條 -38-\o"CurrentDocument"C語言Windows程序設(shè)計-〉第九天-〉GDI繪圖基礎(chǔ) -57-\o"CurrentDocument"C語言Windows程序設(shè)計-〉第十天-〉響應(yīng)鍵盤事件 -67-\o"CurrentDocument"C語言Windows程序設(shè)計-〉第十一天-〉使用鼠標(biāo) -73-\o"CurrentDocument"C語言Windows程序設(shè)計-〉第十二天-〉使用計時器 -80-\o"CurrentDocument"C語言Windows程序設(shè)計-〉第十三天-〉按鈕類控件 -88-\o"CurrentDocument"C語言Windows程序設(shè)計-〉第十四天-〉窗口、編輯框樣式 -98-\o"CurrentDocument"C語言Windows程序設(shè)計-〉第十五天-〉文本輸入框 -99-\o"CurrentDocument"C語言Windows程序設(shè)計ー實戰(zhàn):png圖片的解析與顯示 -110-C語言Windows程序設(shè)計ー>第一天一〉第一個Windows程序在《Windows程序設(shè)計》(第五版)第一章的起步中,作者介紹了學(xué)習(xí)Windows程序設(shè)計的一些基本要求:.能夠從用戶角度熟練的使用Windows;.懂得如何使用C語言;.安裝好了Windows的開發(fā)環(huán)境.看起來要求并不算高(怎么樣?一起來嘗試下?)。筆者在這里決定使用VisualC++6.0作為開發(fā)環(huán)境,雖說在VisualStudio這個大家族中,VC++6早已被長江后浪推前浪,把VC++6推成了一個將近淘汰的環(huán)境,但是作者的機器實在是有點不夠給カ,啟動VS2010時相對比較慢???、之,既然CharlesPetzold也假定我會用VisualC++6.0?那么我就用VC++6好了。,介紹Windows*Windows的歷史;是的,你不用驚訝,Windows在這里就是指的微軟(Microsoft)的那個操作系統(tǒng),Windows的歷史如果要詳細(xì)介紹的話,我覺得可能要單開個隨筆分類オ行,所以這里就簡略的介紹ド,不過我還是建議你去搜索引擎查找ド關(guān)于Windows的歷史(如果你認(rèn)為有必要的話)。1>.1985年11月,Windows1.0正式推出;IBM與Microsoft共同開發(fā),基于DOS系統(tǒng),通過DOS來進行文件操作,當(dāng)然,2.0、3.0也都是基于DOS的,直到Windows2000的發(fā)布,Windows才徹底的擺脫了DOS,成為真正獨立的操作系統(tǒng)。2>.1987年11月,Windows2.0推向市場;相對于1.0,2.0在界面上做了些改動,采用了重疊窗口。3>.1990年5月,Windows3.0推向市場;支持Intel286、386、486微處理器的16位保護模式。4>.1993年7月,Windows'T投放市場;Windows家族中第一個支持Intel386、486、奔騰微處理器32位模式的版本。5>.1995年8月,Windows95發(fā)布;一個混合的16位/32位Windows系統(tǒng)。6.>1998靠6月,Windows98進ス市場;基于Windows95編寫,對Windows95的改進。書的作者就將Windows介紹到這里(沒辦法,人家這本書就是1998年寫好的),后來的Windows就更猛了,橫掃桌面,Windows2000/2003/XP/Vista/2008/7/8...t都懂得。?Windows的イえ點:更加人性化?操作更簡單?一定還有其他的優(yōu)點。?工作原理的中心思想:"動態(tài)鏈接"概念即為Windows工作原理的中心思想,通過調(diào)用Windows自帶的函數(shù)來實現(xiàn)在屏幕上顯示文本與圖形。函數(shù)通過動態(tài)鏈接庫實現(xiàn),.dll以及.exe的文件,在Windows98中,這些文件在、Windows\Systeml目錄下,NT的在、WinNT\System或\WinNT\System32,NT以上放在、Windows、System32。?關(guān)于Windows編程?WindowsAPI:API,ApplicationProgrammingInterface,應(yīng)用程序編程接口,WindowsAPI實際上也就是Windows提供的ー些函數(shù),通過對這些函數(shù)的調(diào)用完成應(yīng)用程序的開發(fā)。*API文檔:這份文檔里介紹了Windows提供的已公開的所有API,你可以下載份離線的,或者去MSDN在線圖書館(MSDXLibraryOnline)查閱這份文檔.上午的隨筆暫時寫到這里,感覺寫的有點短,其實書上寫了很多,仔細(xì)品味了好兒遍,越品味越有種找不到重點的感覺,要是比著書上的句子抄,這博文豈不是太無味了,我想,這些Windows的背景知識對編程影響或許也不是很大,所以在這里就不啰嗦這些了。ド午學(xué)習(xí)"你的第一個Windows程序”。

?我的第一個Windows程序,Hello,world!在CharlesPelzold的書中,作者首先回顧了下C語言在控制臺下通過標(biāo)準(zhǔn)輸入輸出函數(shù)輸岀"Hello,world!”的程序,代碼如下:#include<stdio.h>intmain(){printf("Hello,world!\n");return0;}同樣,CharlesPetzold也給出了Windows版的"Hello,world!"(其實他給出的是Hello,windows98!),代碼如下:#include<windows.h>intWINAPIWinMain(HINSTANCEhlnstance,HINSTANCEhPrevInstance,PSTRszCmdLine,intiCmdShow)(MessageBox(NULL,TEXT("Hello,world!"),TEXT("MessageBox"),0);return0;§Hellolorld.c ヨ,mD:\Project\UinC\HenoIorld\HelloVorld.ctinclude<windows.h>intWINAPIUinMain(HINSTANCEhlnstance,HINSTANCEhPreuInstance,PSTRszCndline,intiCndShow)MessageBox(NULL,TEXT("Hello,world!"),TEXT("MessageBox"),0);return0;通過VisualC++6.0的"文件"一>"新建"一>"工程",選擇"Win32Application"創(chuàng)建ー個空的項目,再在這個項目中新建一個"文件",文件類型為"C++SourceFile",文件以.c為擴展名,將上面的代碼敲入或者復(fù)制粘貼到這個文件內(nèi)容中,經(jīng)過編譯運行就可以得到ー個對話框了,趕緊截圖留念吧!在這個對話框中,有標(biāo)題欄,標(biāo)題欄的內(nèi)容是"MessageBox",對話框的內(nèi)容為“Hello,world!",還有一個"確定"按鈕,而且,沒有那個黑框框窗口,一切看起來都是那么美好,來ー起看看這段Windows版的Hello,world!吧!?Windows版的Hello,world!代碼注釋?*第一行#include<windows.h>稍微有點C語音基礎(chǔ)的都能明白,這是要包含"windows.h"這個頭文件,也就說明,在下面的代碼中,要用到這個頭文件,如果我們將#includeくwindows.h>這句去掉再進行編譯看看會有什么情況:Compiling...HelioWorld,cd:\project\lwinc\helloworld\helloworld.c(3):errorC2061:syntaxerror:identifierWinMaind:\project\lwinc\helloworld\helloworld.c(3):errorC2059:syntaxerror:d:\project\lwinc\helloworld\helloworld.c⑶:errorC2146:

syntaxerror:missing')'beforeidentifier,hlnstance'd:\project\lwinc\helloworld\helloworld.c(3):errorC2061:syntaxerror:identifier'hlnstance'd:\project\lwinc\helloworld\helloworld.c(3):errorC2059:syntaxerror:",(d:\project\lwinc\helloworld\helloworld.c(3):errorC2059:syntaxerror:執(zhí)行cl.exe時出錯.意料之內(nèi)的,報錯了,第一條就是標(biāo)識符"WinMain”錯誤,具體的細(xì)節(jié)暫時就不深究了,繼續(xù)向ド看。?關(guān)于windows,h頭文件:在windowsメ這個頭文件中,實際上ー經(jīng)包含了若干的其他相關(guān)的頭文件,用書上的話說,windows」是個非常重要的包含文件,其中包含的其他比較重耍的頭文件有:WINDEF.H 基本數(shù)據(jù)類型定義WINNT.H 支持Unicode的類型定義WINBASE.H 內(nèi)核函數(shù)WINUSER.H 用戶界面函數(shù)WINGDI.H 圖像設(shè)備接口函數(shù)不過我還是好奇windows』到底包含了那些頭文件,找到VC6的安裝目錄,打開Include文件夾,找到WINDOWS.H并打開,雖說看不太懂,但找#include關(guān)鍵詞還是無壓カ的.除去上面的5個還有:■WINRESRC.H■EXCPT.H■STDARG.H■WINNLS.H■WINCON.H■WINVER.H■WINREG.H■WINNETWK.H■CDERR.H■DDE.H■DDEML.H■DLGS.H■LZEXPAND.H■MMSYSTEM.H■NB30.H■RPC.H■SHELLAPI.HBWINPERF.H■WINSOCK2.II■MSWSOCK.H■WINSOCK.H■WINCRYPT.HHCOMMDLG.H■WINSPOOL.H■OLE.H■OLE2.H■WINWLM.H■WINSVC.H■MCX.H■IMM.H?程序的入口在Win32控制臺程序(Win32ConsoleApplication)中,應(yīng)用程序的入口為main。函數(shù),windows程序的程序入口和Win32控制臺程序的入口類似,%WinMain()函數(shù).程序的入口函數(shù)在WINBASE.H作出了聲明,聲明如下:intWINAPIWinMain(HINSTANCEhlnstance,HINSTANCEhPrevInstance,LPSTR IpCmdLine,int nShowCmd);其中由聲明可以看出,WinMain函數(shù)的返回值被定義為int型;WINAPI為WinMain函數(shù)的調(diào)用規(guī)則,在WINDEF.H對"WINAPI”作出了如下宏定義:ttdefineWINAPI__stdcall說明,WinMain函數(shù)的調(diào)用規(guī)則為"stdcall"方式,對于"—stdcal1”調(diào)用規(guī)則,現(xiàn)在暫時先不去深究,知道有這么回事就行,以后會詳細(xì)了解到的,現(xiàn)在如果深究"stdcall”就偏離了這篇博文的主題。?WinMain函數(shù)的參數(shù):1>.WinMain的窮?個參數(shù)HINSTANCEhlnstance,用書上的解釋為"實例句柄”,由于第一次接觸C語言Windows程序設(shè)計,対這個句柄的概念也不是很了解,去百科了下,句柄的解釋為"一個句柄是指使用的ー個唯一的整數(shù)值,即ー個四字節(jié)長的數(shù)值,來標(biāo)志應(yīng)用程序中的不同對象和同類對象中的不同的實例,諸如,ー個窗口,按鈕,圖標(biāo),滾動條,輸出設(shè)備,控件或者文件等。”——引用自百度百科ー〉句柄。筆者是這樣對句柄進行理解的,在ー個應(yīng)用程序中,通常創(chuàng)建了很多的窗口、按鈕、標(biāo)簽,或者使用了一個文件等,在程序的任何地方,只要能夠獲得這個被稱為句柄的東西,就能夠找到該控件或者窗口在內(nèi)存中的位置,從而對其進行操作。感覺有點像帶參數(shù)的main函數(shù),只是這里的主函數(shù)參數(shù)為一個句柄。2>.WinMain函數(shù)的第二個參數(shù),同樣是個實例句柄,但書上又進?步解釋說在32位的

Windows程序設(shè)計中,WinMain函數(shù)的實例句柄概念已不再采用,因此WinMain的第二個參數(shù)通常總是NULL筆者的見解:感覺馬上就要暈了,疑問ー:"因此WinMain的第二個參數(shù)通??偸荖ULL”,那么第一個呢?WinMain的第一個參數(shù)會不會也可以是NULL呢?疑問二:WinMain函數(shù)的參數(shù)從何而來?是操作系統(tǒng)么?帶著疑問繼續(xù)向下看。3>.WinMain的第三個參數(shù)是用來運行程序的命令行,PSTR:用來指向ー個字符串的指針類型,szCmdLine,sz:表示以〇結(jié)尾的字符串;目的是通過命令行方式運行程序并向主函數(shù)中傳入?yún)?shù),應(yīng)該就像給main函數(shù)傳入?yún)?shù)一樣;4>.WinMain的第四個參數(shù)是ー個int型參數(shù),用來指明程序(窗口)最初如何被顯示,例如最小化?最大化?全屏?筆者的見解:應(yīng)該很有用,經(jīng)常見ー些游戲ー啟動就是全屏的,但是這個參數(shù)也是操作系統(tǒng)傳給程序的么?因為從平時運行Windows程序時都是直接雙擊,并沒有通過命令行給它傳入?yún)?shù),在編程時應(yīng)該對程序啟動時的顯示方式有交代オ對,這樣系統(tǒng)再運行時再把這個交代的參數(shù)傳入給程序告訴程序啟動時應(yīng)該如何顯示.(在"筆者的見解"部分的觀點均為筆者個人的見解,如果有誤肯定指正,我會及時更正,避免誤導(dǎo)其他讀者。)?WinMain函數(shù)函數(shù)體的MessageBox函數(shù):intMessageBox(HWNDhWnd,LPCTSTRIpText,LPCTSTRIpCaption,UINTuTypeMessageBoxO,名如其"人",不用猜也知道這個就是顯示一個對話框的函數(shù),打開API文檔,MSDNLibrary通過索引找到MessageBox函數(shù),發(fā)現(xiàn)其聲明如下://intMessageBox(HWNDhWnd,LPCTSTRIpText,LPCTSTRIpCaption,UINTuType//addressoftextinmessagebox,ー個文本(字符串)的指針//addressoftitleofmessagebox,標(biāo)題字符雷的指針//styleofmessagebox,對話框的風(fēng)格在上面示例中對MessageBox函數(shù)的調(diào)用如ド:MessageBox(NULL,TEXT("Hello,world!"),TEXT("MessageBox"),0);第一個參數(shù)窗口的句柄的實參為NULL,意思為不屬于任何窗口.第二個參數(shù)為對話框的內(nèi)容。第三個參數(shù)為對話框的標(biāo)題,但是這兩個參數(shù)都使用了一個TEXT。的函數(shù),書上講使用TEXTO的目的是將這些字符串打包到TEXT宏代碼里面,筆者嘗試了不用這個TEXT。函數(shù)而直接像這樣:MessageBox(NULL,"Hello,world!","MessageBox",0);調(diào)用并沒有出現(xiàn)警告或者報錯信息,具體使用TEXT。函數(shù)的詳細(xì)原因還不太清楚,暫時先在這里畫個圈。第四個參數(shù)為對話框的風(fēng)格,ー些以MB開頭的ー些常量的組合,可以使用0R(|)運算進行組合,這些常量定義在W1NUSER.H中,例如常用的有:〉對話框按鈕類型:#defineMBOK#defineMBOKCANCELftdefineMBABORTRETRYIGNOREttdefineMBYESNOCANCEL卄パハヂ;ncMDVPCMnOxOOOOOOOOL0x0000000IL0x00000002L0x00000003L0x00000005L〃僅有一個"確定"按鈕〃"確定"+"取消"〃"終止"+"重試"+"忽略"〃"是"+"否"+"取消"http://"且"4."本"〃"重試"+"取消む#defineMB_RETRYCANCEL2〉.對話框中的圖標(biāo)類型:#defineMBICONHAND0x00000010L〃?個紅X的錯誤/停止圖標(biāo)#defineMBICONQUESTION0x000000201//?個問號的詢問圖標(biāo)#defineMBICONEXCLAMATION0x00000030L〃ー個黃色感嘆號的警告圖標(biāo)#defineMB_ICONASTERISK0x00000040L〃ー個帶有i的信息提示圖標(biāo)同時,在這些圖標(biāo)中有的還可以用其他名稱代替,這些別名在WINUSER.H的定義如下ttdefineMBICONWARNINGMBICONEXCLAMATION〃警告

MBICONHANDMBICONASTERISKMB_ICONHAND〃錯誤〃信息〃停止ftdefineMBICONERRORftdefineMBICONINFORMATMBICONHANDMBICONASTERISKMB_ICONHAND〃錯誤〃信息〃停止#defineMB_ICONSTOP下午的學(xué)習(xí)暫時就到這里,在學(xué)習(xí)的過程中出現(xiàn)了幾個疑問,在這里對疑問進行ド總結(jié):疑問在書中介紹WinMain函數(shù)的參數(shù)時講到"因此WinMain的第二個參數(shù)通常總是NULL",那么第?個呢?WinMain的第一個參數(shù)也可以是NULし嗎?疑問二:WinMain函數(shù)的參數(shù)從何而來?是操作系統(tǒng)么?疑問三:使用TEXT()函數(shù)的作用是什么呢?C語言Windows程序設(shè)計ー>第二天一>ASCII與Unicodeー、ascii1>.關(guān)于ASCHASCI1(AmericanStandardCodeforInformationInterchange,美國信息互換標(biāo)準(zhǔn)代碼)ASCIIー共包含128個字符,包括:33個控制符號,1個空格,32個符號,10個數(shù)字,26個小寫字母和26個大寫字母。每個ASCII字符采用7位二進制編碼的方式。ASCII的優(yōu)點:十分可靠,普遍扎根在我們的鍵盤、顯示器、系統(tǒng)硬件、打印機、操作系統(tǒng)等,用途十分廣泛。ASCII的缺點:ASCII,美國信息互換標(biāo)準(zhǔn)代碼,美國原生,不能滿足其他國家文字的需求,例如,中國的漢字?英國的英鎊符號(£)?等,這些在ASCII都是找不到的。2>.對ASCH的擴展由于ASC?不能很好的滿足其他國家文字的需求,所以人們迫切希望能對ASCH進行改進。①.國際化標(biāo)準(zhǔn)組織的擴展方案1967年,國際化標(biāo)準(zhǔn)組織(ISO,InternationalOrganizationforStandardization)推薦了ASCH的ー個變種,改動內(nèi)容包括:從ASCII中,拿出0x40('@'),、0x5B('[')、0x5C(‘ヽ’)、0x5D(']')、0x5E('~')、0x60(''')、0x7B('{')、0x7C(';')、0x7D('}')、0x7E('ヽ')這10個符號保留給各個國家單獨使用。這顯然不是解決ASCII國際化的好方法,首先,其他國家將這些保留字符重新定義為自己國家需要的字符后,那么國際上的?致性將不能得到保證,此外,10個保留字符遠遠不能滿足美國的東方的ー些國家使用的象形文字需求,比如我們中國的漢字。.IBM公司的擴展方案IBM公司采用了使用8位二進制編碼方式來表示ASCH,使用ー個字節(jié)來儲存字符,這樣,相對于7位的ASCII就可以多出128個額外字符空位來補充ASCII。IBM對ASCII的主要擴展為:補充了一些重音字符、小寫希臘字母、塊圖字符和線圖字符。同時,還將一些補充的字符分配到ASCII的ー些不必要的控制字符上。(注:在操作系統(tǒng)還是字符模式的年代,塊圖字符和線圖字符常用來被應(yīng)用軟件裝飾自己的程序顯示).微軟公司的擴展方案1985年11月,Windows1.0發(fā)布,微軟采用了自己定義的ー套字符集,這套字符集被稱為"ANSI字符集”,是基于ANS!和ISO標(biāo)準(zhǔn)的ー個草案。在MS-DOS3.3時代(1987年4月),微軟為了使不同國家的計算機都能正常的顯示字符,微軟采用了代碼頁概念,不同國家的字符被規(guī)定在不同的代碼頁上,例如代碼頁第437頁為美國英語,850頁為拉丁語ー1。用戶只要將代碼頁設(shè)置到自己所在的國家就能正常的進行エ作,但是如果用戶嘗試著將自己的文檔拿到與另外一個使用不同代碼頁的用戶的計算機上進行修改時,自己的文檔的某些字符將會顯示成其他字符,這還算好,有解決方案,應(yīng)用軟件可以通過將代碼頁信息儲存到文件中,使用時再進行一些代碼頁的轉(zhuǎn)換。但在后來,隨著代碼頁數(shù)量的劇增,Windows版本的不斷升級,代碼頁的混淆問題開始日益凸顯,DS-DOS的代碼頁和Windows的代碼頁以及其他Windows版本的系統(tǒng)發(fā)生了不兼容,例如MS-DOS代碼頁第855頁西里爾語在Windows中的1251頁西里爾語或者Macintosh的第10007頁西里爾語還都不ー樣。微軟為了解決東方?些國家使用的象形文字問題,使用了雙字節(jié)字符集,這些字符集同樣在不同的代碼頁,代碼頁936(簡體中文)、949(韓文)、950(繁體中文)以及932(11文)。微軟的這個雙字節(jié)字符集和你象形的可能有所不同,在這個雙字節(jié)字符集中,前128個字符仍然是ASCII。字節(jié)),較高的128個擴展字符以跟隨第二個字節(jié)的方式用來表示象形文字(這兩個字節(jié)被稱為前導(dǎo)字節(jié)和尾隨字節(jié))。所以在這個代碼頁中,有一個字節(jié)的字符,還有2個字節(jié)的字符,這就導(dǎo)致了兩個嚴(yán)重的問題:1>,在一段字符串中,字符串的長度不能根據(jù)字節(jié)的個數(shù)確定,耍想確定字符串的長度必須檢査每個字節(jié)是不是雙字節(jié)字符的前導(dǎo)字節(jié)。2>,通過任意指向字符串中的ー個指針,無法知道前ー個字符的地址,通常要回到字符串的開始,一直解析到指針?biāo)诘奈恢谩6?、Unicode對ASCII擴展的過程中,沒有能夠找到ー個徹底解決世界上所有書面文字的表示方法,很顯然,1個字節(jié),256個字符是無法表示世界上所有的書面文字的,因此,Unicode誕生了。Unicode使用16位(2字節(jié))的二進制編碼方式來表示字符,我們知道,16位最多能夠表示65536個字符,65536個字符對于世界上的所有書面文字以及ー些特殊符號來說已經(jīng)足夠用了。在Unicode中,不同國家使用不同的代碼段,例如,0x0530-0x058F為亞美尼亞語(Armenian)、0x0600-0x06FF為阿拉伯文(Arabic)、OxOEOO-0x0E7F為泰文(Thai)、0x2700-0x27BF為印刷符號(Dingbats)、0x4E00-0x9FBF為中文。Unicode的優(yōu)點:只有一個字符集,避免了二義性,能夠滿足跨語言、跨平臺進行文本轉(zhuǎn)換、處理的要求。Unicode的缺點:Unicode字符的字符串比ASCII字符串占用的內(nèi)存大兩倍。(筆者認(rèn)為,隨著計算機性能的不斷提髙,內(nèi)存和外存容量的不斷增加,Unicode這?缺點可以慢慢忽略)。C語言Windows程序設(shè)計ー>第二天一>寬字符和C語言ー、回顧C語言中的char數(shù)據(jù)類型1>,在C語言中,首先我們來聲明一個字符型變量:charc;我們也可以在聲明時對其進行初始化:charc='A';這時,字符型變量c就會被值0x41進行初始化,0x41也就是ASCII碼中的‘A'字符;2>.我們還可以定義一個指向ー個字符型數(shù)據(jù)的指針,例如:char*p;同樣我們再讓指針p初始化時指向一個字符串:char*p="Hello,world!”;

3>,我們再聲明一個字符數(shù)組:chara[10];也可以在聲明時對其進行初始化:chara[10]="Hello";或者:chara[]="Hello";通過對C語言的學(xué)習(xí)我們可以知道,char型變量為1個字節(jié),因此,在charc='A'中,變量c的大小即為1字節(jié);在32位的操作系統(tǒng)中,ー個指針型的變量需要4字節(jié)的存儲空間,因此在第二個示例中,char*p="Hello,world!";所需的存儲空間為:4字節(jié)指針變量所需的空間+字符串"HeiIo,world!"的12個字節(jié)另外再加上一個字節(jié)用來表示字符串結(jié)束的0。對于ー個字符數(shù)組chara[10];編譯器則會自動保留10個字節(jié)的儲存空間,對于charaロ="Hello";這種聲明方式,編譯器會根據(jù)"Hello"字符串的長度(5個字符+?個結(jié)尾〇)來決定初始化時的數(shù)組大小。通過學(xué)習(xí)Unico加編碼方式,可以知道,ー個Unicode字符占用2個字節(jié)的儲存空間,如果我們想用C語言中原有的數(shù)據(jù)類型表示Unicode的2字節(jié)編碼類型,char是不行的,char的儲存空間為ー個字節(jié),在32位的環(huán)境下,int占4個字節(jié),而我們僅僅需要的是2字節(jié),并且是無符號型數(shù)據(jù),因此,我們可以使用unsignedshortint型數(shù)據(jù)表示一個2字節(jié)的字符,unsignedshortint為2字節(jié),正好符合2字節(jié)的要求,當(dāng)然,我們也可以將unsignedshortint簡寫為unsignedshort〇在C語言中的寬字符正是基于short型數(shù)據(jù)的,這ーー數(shù)據(jù)類型在頭文件WCHAR.H中的定義為:typedefunsignedshortwchar_t;所以C語言中的寬字符wchar_t數(shù)據(jù)類型與一個無符號短整形unsignedshortー樣,都是16位寬。如果我們用寬字符wchajt數(shù)據(jù)類型定義ー個變量并且初始化,如下:wchar_tc='A';那么寬字符wchajt變量c的值為0x0041,學(xué)過匯編的朋友應(yīng)該知道,如果使用16位的CPU儲存ー個字,將使用兩個存儲單元,在這兩個存儲單元中,低位字節(jié)放在低地址單元中,高位字節(jié)則放在高地址單元中,所以,在這里,處理器依然將從低位內(nèi)存單元即低位字節(jié)開始處理字符,‘A’在內(nèi)存中的順序即為0x41->0x00?當(dāng)我們想使用寬字符表示一個字符串,我們還要通知編譯器這個字符串將使用寬字符存儲,我們用大寫的字母'L'(表示長整形)來將這ー消息告訴編譯器,例如:wchar_t*p=L"Hello";那么這個字符串"Hello”將會使用12個字節(jié)來儲存,這12個字節(jié)存儲單元的內(nèi)容為:"Hello"這5個字符占10個字節(jié),另外加上表示結(jié)束的〇占兩個字節(jié)。三、有關(guān)寬字符的函數(shù)在C語言的學(xué)習(xí)中,字符串處理函數(shù)我們經(jīng)常使用,比如:unsignedintstrlen(char*s);//求字符串的長度char*strcat(char*dest,char*src):〃將src所指字符串連接到dest結(jié)尾處intstrcmp(char*sl,char*s2)J〃將李符串sl-與s2比較char*strcpy(char*dest,char*src):〃將src所指字符串復(fù)制到dest結(jié)尾處這些函數(shù)極大的方便了我們對字符串的處理,遺憾的是,在寬字符類型的字符串中,這些函數(shù)將不再適用,例如我們使用strlen求?個寬字符字符串的長度,代碼如下:

ttinclude<stdio.h>ftinclude<string.h>intmainO(wchar_t*p=L*Hello*;printf("%d\n",strlen(p));return0;)運行后顯示的結(jié)果為1,很顯然,它沒有求出正確的長度,這是因為,寬字符字符串"Hello”在一段內(nèi)存中存儲的值如下:480065006C006C006F002100這是因為當(dāng)strlen找到該字符串的第一個〇時就認(rèn)為該字符串已經(jīng)結(jié)束了,所以得到的長度為1,strlen統(tǒng)計到的這ー個字符即為0x48表示的‘H'.幸運的是,雖然這些字符串處理函數(shù)不支持對寬字符的處理,但是我們可以使用為寬字符處理準(zhǔn)備的函數(shù),C語言中每個字符串處理函數(shù)對應(yīng)的都有其寬字符版本的字符串處理函數(shù),這些函數(shù)定義在STRING.H頭文件和WCHAR.H中,例如strlen函數(shù)響應(yīng)的寬字符版本為wcslen,wcslen函數(shù)在STRING.H的聲明如下:size_twcslen(constwchar_t*);size,為無符號整形unsignedint的別名,STRING.H在頭文件的定義如下:typedefunsignedintsize_t;我們嘗試使用寬字符處理函數(shù)wcslen()求寬字符字符串的長度:^include<stdio.h>#include<string.h>intmain()(wchar_t*p=L"Hello";printf("%d\n",wcslen(p));return0;)編譯運行后的結(jié)果顯示為5,是正確的,同樣,在寬字符中常用的字符串處理函數(shù)如下:函數(shù)名函數(shù)原型函數(shù)功能返回值wchw_t*vcsc?tG?ch?r_t?sl,const?chw_t*s2);挎立所指的字符串連接到S1后面T所指李存串的自地址?exchrwchw_t**cschr(const t??,wcKw_tc);在與后串申找到諄苻第一次出現(xiàn)的位置著找到,則返回該學(xué)存的地址否則返回皿vcscmpintvcscap(constwch?r_t**1,constwch?r_t*s2).讓宇苻第,1與字苻陽?2進行比較?1<?2,返回負(fù)數(shù).3=?2,詆回O.sl>s2,返回E款wcscpywch?r_t*wcscpy(wchar_l?sl.const?char_t*s2);將s2所指字符串復(fù)的田的結(jié)尾處si所キ?字符曲首地址wcsltnsix?_twcslen(constwch?r_t*s).求,所?時;5s的K度過回有效字后的個效wcsstr?ch?r_t?wcsstr(constwch?r_t constwch?r_t?s2):粒土字苻啣2在字存事う中第一次出麗位為若桃到,則返回該位置a地址,否!理返回皿四、遺留問題:關(guān)于TEXT。昨天在學(xué)習(xí)過程中有個遺留問題:MessageBox(NULL,TEXTCHello,world!0,TEXT("MessageBox"),〇);使用TEXT()的作用是什么呢?在今天的學(xué)習(xí)中終于找到了答案。

在定義wchar_t寛ア符類型的字符串時,我們需要在字符串前面加上個大寫字母‘L’來告訴編譯器這是ー個wchajt寛字符型的字符串,而TEXT()正是為了解決在定義如何不加前面的’ビ的。當(dāng)我們使用寬字符時,打開TCHAR.H這個頭文件向下查找,會看到:ftdefine_T(x)L##x這句宏定義,在ANSIC標(biāo)準(zhǔn)的預(yù)處理中,符號"##"被解釋為"令牌粘貼”,作用是使得字母'ピ與宏參數(shù)連接在ー起,假如參數(shù)x為"Heilo”,那么經(jīng)過L##x處理后"Hello"就變成了L"Hello"?這看起來和TEXT。沒什么關(guān)系,繼續(xù)向下查找T(x)’會看到:#define_T(x) _T(x)#define二TEXT(x) _T(x)這兩行宏定義,到這里仍然沒有看到TEXT。,有了這個思路,筆者就嘗試著找到TEXT。宏,經(jīng)過搜索引擎的幫助,終于找到TEXT宏是定義在WINNT.H頭文件中,找到了相關(guān)的定義如下:#defineTEXT(quote)L##quote//rwinnt〃與一#defineTEXT(quote)_TEXT(quote)//rwinnt當(dāng)使用wchajt類型的寬字符時,使用"令牌粘貼",這樣,使用TEXT宏時就避免了在字符串前面加上一個大寫字母‘L’了。C語言Windows程序設(shè)計ー>第三天一〉Windows版printf在Windows中使用printfー、可變參函數(shù)在Windows程序設(shè)計中,由于Windows不存在標(biāo)準(zhǔn)輸入輸出的概念,這就意味著以前我們學(xué)習(xí)的printf函數(shù)將不再適用,我們知道,C語言標(biāo)準(zhǔn)輸入輸出函數(shù)printf一個常用的功能就是輸出格式化后的文字,例如:intiAge=18;printf(z,Hello,Iam%dyearsold.\n",iAge);是的,printf函數(shù)的使用確實十分方便,今天我們要做的就是完成一個Windows版的printfo關(guān)于sprintf:看ー個C語言的函數(shù),sprintf這個函數(shù)在stdio.h頭文件中有聲明,sprintf函數(shù)的主要功能是把格式化的數(shù)據(jù)寫入某個字符串中,函數(shù)的原型如下:intsprintf(char*buffer,constchar*format,[argument]…);sprintf的第一個參數(shù)為字符緩沖區(qū),后面的參數(shù)就像printfー樣,是ー個格式化字符串,函數(shù)的返回值為緩沖區(qū)buffer內(nèi)的有效字符串長度,我們嘗試使用一下:^include<stdio.h>intmain()(charszBuffer[50]; 〃定義緩沖區(qū)大小為50字節(jié)sprintf(szBuffer,"today:%d-%d-%d”,2012,10,8);//將今天的日期格式化輸出到緩沖區(qū)puts(szBuffer);〃輸出緩沖區(qū)szBuffer中的字符

return0;現(xiàn)在我們已經(jīng)能看到Windows版的printf的影子了,在Windows版的printf中,我們可以使用MessageBox函數(shù)來替代C語言的標(biāo)準(zhǔn)輸入輸出函數(shù)puts,但是在這之前我們還有一個重要的問題要解決。sprintf的安全版當(dāng)我們使用sprintf時,我們需要首先定義ー個緩沖區(qū),這個緩沖區(qū)我們必須定義的足夠大以至于能容納我們格式化輸出的字符串,如果超過了這個長度,程序?qū)鲥e,這樣是不安全的,這里,使用一snprinlf()函數(shù)來解決這個問題,一snprintf的原型為:int_snprintf(char*szBuffer,size_tsize,constchar*format,...);_snprintf相對于sprintf函數(shù)多出了個參數(shù),size_tsize.這個參數(shù)的功能是:當(dāng)格式化后的字符串長度〈size,則將此字符串全部復(fù)制到szBuffer中,并給其后添加一個字符串結(jié)束符('、0');當(dāng)格式化后的字符串長度>=size,則僅復(fù)制(size-1)個字符到緩沖區(qū)szBuffer內(nèi),并在其后添加一個字符串結(jié)束符('、〇')。我們自己的可變參函數(shù)sprintf有個變形函數(shù),叫vsprintf,首先看下這個函數(shù)的原型:intvsprintf(char*szBuffer,constchar*format,valistparam);vsprintf的前兩個參數(shù)與sprintf相同,第三個參數(shù)是ー個valist宏,valist宏就是解決C語言變參問題的。va_list宏的用法:我們將用到va」ist的以下幾個成員:va_listxva_startxva_end;在些宏在STDARG.H頭文件中有定義,打開STDARG.H可以看到,其中有句:typedefchar*valist;從這句我們可以看出,va」ist其實就是char?型類型,ー個字符型指針;再來看看vastart宏:va_start(va_listap,char*format);format為函數(shù)的參數(shù),可以用來指明參數(shù)的類型可以看出,ap為valist類型,也就是可變參數(shù)列表;通過vastart后,就能使得變參列表與format中的類型ーー對應(yīng)起來;va_end的作用是銷毀釋放一個va_list型的參數(shù)列表,例如:valistapvaend(ap);下面我們就可以實現(xiàn)我們自己的變參了,代碼如下:#include<stdio.h>#include<stdarg.h>intmySprintf(char*szBuffer,constchar*szFormat,...)(intiLength; 〃存儲字符串的長度信息valistpArgs; 〃聲明一個valist型變量vastart(pArgs,szFormat);〃讓pArgs指向變參iLength=vsprintf(szBuffer,szFormat,pArgs);〃輸出到緩沖區(qū)szBuffer中va_end(pArgs); 〃釋放pArgs

returniLength; 〃返回字符串長度)intmain(

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論