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

C++入門學習筆記

編輯:關於C++

這些是我剛學習C++的筆記,拿出來與大家分享,希望大家更容易入門!

1、 運算符<<(送出)用作輸出運算符;cout是標准輸出流。運算符>>(取入)用作輸入運算;cin是標准的輸入流。

2、 輸出:一個輸出表達式的結果本身還可以用於進一步的輸出。

void h2(int i)

{

Cout<<”the value of I is”<

3、 輸入:Void h3(int i)

{

Cin>>x;

Getline(cin,str);

}4、 迭代器是一種對象,它能夠用來遍歷標准模板庫容器中的部分或全部元素,每個迭代器對象代表容器中的確定的地址。迭代器修改了常規指針接口,所謂迭代器是一種概念上的抽像:那些行為上像迭代器的東西都可以叫做迭代器。然而迭代器有很多不同的能力,他可以把抽象的容器和同用的算法有機的結合起來。迭代器提供一些基本操作符:*、++、==、!=、=。這些操作和c/c++操作array元素時的指針接口一致。不同之處在於迭代器是個所謂的復雜指針。具有遍歷復雜數據結構的能力。其下層運行機制取決於其所遍歷的數據結構。因此每一種容器型別都必須提供自己的迭代器。事實上每一種容器都將其迭代器以嵌套的方式定義域內部。因此各種迭代器的接口相同,型號卻不同。這直接導出了泛型程序設計概念:所有操作行為都是用相同接口雖然他們的型別不同。功能迭代器使開發人員能夠在類或結構中支持foreach迭代,而不必整個實現IEnumerable或者IEnumerator接口。只需提供一個迭代器,即可遍歷類中的數據結構。當編譯器檢測到迭代器時,將自動生成IEnumerable接口或者IEnumerator接口的Current,MoveNext和Dispose方法。特點1.迭代器是可以返回相同類型值的有序序列的一段代碼;2.迭代器可用作方法、運算符或get訪問器的代碼體;3.迭代器代碼使用yieldreturn語句依次返回每個元素,yield break將終止迭代;4.可以在類中實現多個迭代器,每個迭代器都必須像任何類成員一樣有惟一的名稱,並且可以在foreach語句中被客戶端,代碼調用如下所示:foreach(int x in SimpleClass.Iterator2){};5.迭代器的返回類型必須為IEnumerable和IEnumerator中的任意一種;6.迭代器是產生值的有序序列的一個語句塊,不同於有一個 或多個yield語句存在的常規語句塊;7.迭代器不是一種成員,它只是實現函數成員的方式,理解這一點是很重要的,一個通過迭代器實現的成員,可以被其他可能或不可能通過迭代器實現的成員覆蓋和重載;8.迭代器塊在C#語法中不是獨特的元素,它們在幾個方面受到限制,並且主要作用在函數成員聲明的語義上,它們在語法上只是語句塊而已;9.yield關鍵字用於指定返回的值。到達yieldreturn語句時,會保存當前位置。下次調用迭代器時將從此位置重新開始執行。 迭代器對集合類特別有用,它提供一種簡單的方法來迭代不常用的數據結構(如二進制樹)。簡介迭代器是一種檢查容器內元素並遍歷元素的數據類型。 5、 枚舉(enum)枚舉在C/C++/c#中,是一個被命名的整型常數的集合, 枚舉在日常生活中很常見。例如表示星期的SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY,SATURDAY, 就是一個枚舉。枚舉的說明與結構和聯合相似, 其形式為:enum 枚舉名{

標識符[=整型常數],

標識符[=整型常數],

...

標識符[=整型常數]

} 枚舉變量;如果枚舉沒有初始化, 即省掉”=整型常數”時, 則從第一個標識符開始, 順次賦給標識符0, 1, 2, …。但當枚舉中的某個成員賦值後, 其後的成員按依次加1的規則確定其值。例如下列枚舉說明後, x1, x2, x3, x4的值分別為0, 1, 2, 3。enum Num{x1, x2, x3, x4}x;當定義改變成:enum Num

{

x1,

x2=0,

x3=50,

x4

}x;則x1=0, x2=0, x3=50, x4=51注意:1. 枚舉中每個成員(標識符)結束符是”,”, 不是”;”, 最後一個成員可省略“,”。2. 初始化時可以賦負數, 以後的標識符仍依次加1。3. 枚舉變量只能取枚舉說明結構中的某個標識符常量。例如:enum Num

{

x1=5,

x2,

x3,

x4

};

enum Num x=x3;此時, 枚舉變量x實際上是7。枚舉類型變量的賦值和使用枚舉類型在使用中有以下規定:1.枚舉值是常量,不是變量。不能在程序中用賦值語句再對它賦值。例如對枚舉weekday的元素再作以下賦值: sun=5;mon=2;sun=mon; 都是錯誤的。2. 枚舉元素本身由系統定義了一個表示序號的數值,從0 開始順序定義為0,1,2…。如在weekday中,sun值為0,mon值為1, …,sat值為6。main(){

enum weekday

{ sun,mon,tue,wed,thu,fri,sat } a,b,c;

a=sun;

b=mon;

c=tue;

printf("%d,%d,%d",a,b,c);

}只能把枚舉值賦予枚舉變量,不能把元素的數值直接賦予枚舉變量。如: a=sun;b=mon; 是正確的。而: a=0;b=1; 是錯誤的。如一定要把數值賦予枚舉變量,則必須用強制類型轉換,如: a=(enum weekday)2;其意義是將順序號為2的枚舉元素賦予枚舉變量a,相當於: a=tue; 還應該說明的是枚舉元素不是字符常量也不是字符串常量, 使用時不要加單、雙引號。main(){

enum body

{ a,b,c,d } month[31],j;

int i;

j=a;

for(i=1;i<=30;i++){

month[i]=j;

j++;

if (j>d) j=a;

}

for(i=1;i<=30;i++){

switch(month[i])

{

case a:printf(" %2d %c\t",i,'a'); break;

case b:printf(" %2d %c\t",i,'b'); break;

case c:printf(" %2d %c\t",i,'c'); break;

case d:printf(" %2d %c\t",i,'d'); break;

default:break;

}

}

printf("\n");

}10個數字,任意取出不相等的5個數字,

誰還記得這個算法的公式????????

用javascript有什麼好的計算方法??

m n*(n-1)*(n-2)*...*(n-m+1) n!

C = --------------------------------------------- = --------------------------

n m*(m-1)*(m-2)*...*3*2*1 m!*(n-m)!這個是公式,但是對枚舉作用不大,還是要遍歷循環才行.這就需要一個好的算法6、 typedeftypedef為C語言的關鍵字,作用是為一種數據類型定義一個新名字。這裡的數據類型包括內部數據類型(int,char等)和自定義的數據類型(struct等)。在編程中使用typedef目的一般有兩個,一個是給變量一個易記且意義明確的新名字,另一個是簡化一些比較復雜的類型聲明。 7、 大小C++對象的大小事用char的大小的倍數表示的。按照定義char的大小為1,。一個對象或類型的大小可以用sizeof運算符得到。類型 大小Char bool 1

Short,wchar_t 2

Int,long,float 4

Float,long double 88、 顯式類轉換顯示類型轉換只是得到了一個所需類型的中間變量,原來變量的類型並不發生改變。標准C++中主要有4中顯式類轉換類型運算reinterpret_cast,static_cast,const_cast,dynamic_cast.1. reinterpret_cast語法:returnvalue=reinterpret_cast(casting value);這個操作符修改了操作數類型,但僅僅是重新解釋了對象的比特模型而沒有進行二進制轉換。從語法上看,這個操作符僅用於指針類型的轉換(返回值是指針)。它用來將一個類型指針轉換為另一個類型指針,它只需在編譯時重新解釋指針的類型。這個操作符基本不考慮轉換類型之間是否是相關的。reinterpret_cast常用的場景如下:1)普通指針轉換,T*—>U*—>T*,保證T*經過一些列轉換值不變比如將不同類型的指針存在一個容器裡,vector可以存int*,char*,string*等各種指針,只要有別的方式確定某個void*當初的類型是T*,標准保證reinterpret_cast(v[i])可以得到當初的值。2)自己做memory allocator,可以將T*轉換為U*,這個時候可能要注意字節對其的問題。2、static_cast語法:T static_cast (expression);該運算符把expression轉換成type-id類型,但沒有運行時類型檢查來保證轉換的安全性。static_cast是最經常用到的轉換操作符,它最經常的一個應用就是將隱式轉換變成顯示轉換,以消除編譯器可能產生的warning,同reinterpret_cast不同,采用static_cast轉換的兩個類型之間一般有某種相關性。static_cast主要應用場景如下:1)用於類層次結構中基類和派生類之間指針或引用的轉換。這個轉換中,將派生類轉成基類是安全的,將基類轉成派生類時由於沒有進行動態類型檢查,所以是不安全的。2)用於基本數據之間的轉換。如把int轉成char,int轉成num等。3)把空指針轉換成目標類型的空指針。4)把任何類型的表達式轉換成void類型。3、dynamic_cast語法:dynamic_cast < type-id > ( expression )該運算符把expression轉換成type-id類型的對象。Type-id必須是類的指針、類的引用或者void *;dynamic_cast的轉換是在運行時進行的,它的一個好處是會在運行是做類型檢查,如果對象的類型不是期望的類型,它會在指針轉換的時候返回NULL,並在引用轉換的時候拋出一個std::bad_cast異常。dynamic_cast一般只在繼承類對象的指針之間或引用之間進行類型轉換。如果沒有繼承關系,則被轉化的類具有虛函數對象的指針進行轉換。4.const_castconst_cast< type-id > (exdivssion)這個運算符可以用來去除一個對象的const或volatile屬性。type-id必須是一個指針或者引用。- 9、&—–取地址符運算例如: int e[3]={1,2,3};

Int *p;

p=&e[2];

則:

*p=2;

*(p+1)=3;

*(p-1)=1;10、C++語言中的基本數據類型及其范圍 11、類類描述了一類食物,以及食物所應具有的屬性,是一種用戶自定義的數據類型。聲明一個類時,以class關鍵字開始,接著是類的名字,其語法結構為: Class <類名稱>

{

private:

[<私有數據和函數>]

public:

[<公有數據和函數>]

}類表示了一組相似的對象,是創建對象的有效模板,用它可以產生多個對象。類所代表的是一個抽象的概念或事物,在客觀世界中世紀存在的是類的實例,即對象。類時具有相同屬性和服務的一組對象的集合,它為屬於該類的全部對象提供了一個統一的抽象描述,其內部包括屬性和服務兩個主要部分。類包含以下3種類型:- private:私有類型包含數據和函數,在private關鍵字後面聲明。如果省略private關鍵字,則必須緊跟在類名的後面聲明。在類中聲明的數據和函數如果不特別指明,都被視為私有類型。私有類型的數據值允許類本身聲明的函數對其進行存取,而類的外部的任何函數都不能訪問。- public:公有類型public關鍵字後面聲明,他們是類與外部的接口,任何外部函數都可以訪問公有類的數據和函數。- protect:保護類型用於類的繼承,當類的成員被聲明為protect時,從類的外部就不能對其進行訪問。類時面向對象程序最基本的單元。在設計面向對象程序時,首先要以類的方式設計實際待解決的問題,也就是將問題索要處理的數據定義成類的私有或公有類型數據,同時將處理問題的方法定義成類的公有或私有成員函數。11、對象對象時系統中用來描述客觀事物的一個實體,它是構成系統的一個基本單位,有一組屬性和對這組屬性進行操作的一組服務組成。屬性和服務是構成對象的兩個基本要素,其定義是:屬性是用來描述對象靜態特征的一個數據項;服務是用來描述對象動態特征的一個操作序列。對象是類的實例,可以聲明類時直接定義對象。此外,還可以在聲明類之後再單獨聲明類對象。 Class example

{

Int I;

Public;

Float f;

Void fun();

};

Example A;對象聲明後即可使用,使用方法如下:對象名.成員函數名和對象名,數據成員名例,可以按一下方式調用類example中的成員函數fun();A.fun();12、類和類之間的關系1.關聯關系關聯關系表示兩個類之間存在某種語義上的聯系,即與該關聯鏈接的類的對象之間具有一定的語義鏈接關系,該關系表達了類之間的一種相關性。2.依賴關系依賴關系描述的是兩個類之間的語義上的連接關系,它是一種Use-A關系。假設兩個元素A與B,如果修改元素A的定義可能會一起對另一個元素B的定義的修改,則稱元素B依賴於A。3.聚合關系聚合關系是一種Has-A關系,它體現的是類之間的一種整體與部分的關系。4.泛化關系泛化關系是一種Is-A關系,它描述的是類之間“一般”與“特殊”的關系。具有共同特性的元素可以抽象為一般類,並通過增加其內涵,進一步抽象成特殊類。改關系可以將類組成一種有層次,有分類的結構。13、多態性多態性是指類中具有相似功能的不同函數使用同一個名稱實現。多態性的實現與聯編有關。將一個函數的調用與其相應的函數體代碼相鏈接的過程,成為函數聯編。靜態聯編,動態聯編編譯時的多態性是通過靜態聯編來實現的。靜態聯編是指在調用同名函數時,編譯器將根據調用時所使用的實際參數個數、類型的不同確定應該調用哪一個函數的實現,它是在程序編譯階段就確定下來的多態性。靜態聯編通過使用重載機制來獲得,重載機制包括函數重載和運算符重載。14、形參和實參形參:全稱為“形式參數”是在定義函數名和函數體的時候使用的參數,目的是用來接收調用該函數時傳遞的參數。形參的作用是實現主調函數與被調函數之間的聯系,通常將函數所處理的數據,影響函數功能的因素或者函數處理的結果作為形參。沒有形參的函數在形參表的位置應該寫void.main 函數也可以有形參和返回值,其形參也稱為命令行參數,由操作系統在啟動程序時初始化,其返回值傳遞給操作系統。實參:可以是常量、變量、表達式、函數等, 無論實參是何種類型的量,在進行函數調用時,它們都必須具有確定的值, 以便把這些值傳送給形參。 因此應預先用賦值,輸入等辦法使實參獲得確定值。實參和形參的區別:空白或占位符1.函數的形參列於函數聲明中,在函數定義的函數體內使用。當函數調用時,形參(任何種類的)是一類將被填充的空白或是占位符。用來填充形參2.實參是用來填充形參的。當函數被調用時,實參列在函數名後面的括號裡。執行函數調用時,實參被傳遞給形參。傳值調用和引用調用3.傳值調用和引用調用指的是用於參數傳遞過程中的一種機制。傳值調用中,只使用了實參的值。傳值調用機制裡,形參是一個局部變量,其初始值為相應實參的值。在引用調用機制裡,將實參的地址傳遞給形參,從表面上看是以實參變量取代形參,因此任何發生在形參上的改變實際上都發生在實參變量上。15、運算符重載運算符重載本質上就是函數的重載,是函數重載的特殊形式(函數名為運算符號)。C++語言中允許程序員重新定義運算符的語義,這一機制稱作運算符重載。16、正則表達式正則表達式又稱正規表達式,常規表示法,計算機科學的一個概念。正則表達式使用單個字符串來描述。匹配一系列符合某個句法規則的字符串。在很多文本編輯器裡,正則表達式常用來檢索、替換那些符合摸個模式的文本。許多程序設計語言都支持利用正則表達式進行字符串操作。例如,在Perl中就內建了一個功能強大的正則表達式引擎。正則表達式這個概念最初是由Unix中的工具軟件(例如sed和grep)普及開的。正則表達式通常縮寫成“regex”,單數有regexp、regex,復數有regexps、regexes、regexen。正則表達式是對字符串操作的一種邏輯公式,就是用事先定義好的一些特定字符、及這些特定字符的組合,組成一個“規則字符串”,這個“規則字符串”用來表達對字符串的一種過濾邏輯。給定一個正則表達式和另一個字符串,我們可以達到如下的目的: 給定的字符串是否符合正則表達式的過濾邏輯(稱作“匹配”); 可以通過正則表達式,從字符串中獲取我們想要的特定部分。正則表達式的特點是: 靈活性、邏輯性和功能性非常的強; 可以迅速地用極簡單的方式達到字符串的復雜控制。 對於剛接觸的人來說,比較晦澀難懂。由於正則表達式主要應用對象是文本,因此它在各種文本編輯器場合都有應用,小到著名編輯器EditPlus,大到Microsoft Word、Visual Studio等大型編輯器,都可以使用正則表達式來處理文本內容。17、MFCMFC應用程序有自己特殊的運行機制,一般包括以下5步:調用CWinApp的構造函數。 程序入口函數WinMain接收控制。 WinMain調用應用程序類的InitInstance函數。 WinMain進入消息循環。 WinMain退出,程序終止。1、 應用程序類CTestApp從MFC的CWinApp類派生,對應的源文件Test.h和Test.cpp,為應用程序的入口,負責應用程序對象的定義與創建、程序的啟動、命令行參數處理、主框架窗口的創建、文檔模板的創建、文件菜單的處理、About對話框的創建和顯示等。2、 主框架窗口類CmainFrame從MFC的CFrameWnd或CMDIFrameWnd派生,對應的源文件為MainFrm.h和MainFrm.cpp。為應用程序的界面,包含菜單欄、工具欄和狀態欄,負責子框架窗口或視圖類的創建。3、 字框架窗口類CchildFrame從MFC的CMDIChildWnd類派生,只有MDI程序才有,對應的源文件為ChildFram.h和ChildFrm.cpp,包含子框架窗口的標題條和邊框,負責視圖類的創建。 4、 文檔類CtestDoc從MFC的CDocument類派生,對應的源文件為TestDoc.h和TestDoc.cpp,負責文件讀寫和數據處理。5、 視圖類CTestView一般從MFC的CView類派生,也可以沖CScrollView等其他MFC視圖類派生,對應的源文件TestView.h和TestView.cpp。對應於框架窗口的客戶區,負責數據的顯示、圖形的繪制和用戶的交互等。18、map的用法1、Map的簡介Map是一類關聯式容器。它的特點是增加和刪除節點對迭代器的影響很小,除了那個操作節點,對其他的節點都沒有什麼影響。對於迭代器來說,可以修改實值,而不能修改key。2、map的功能自動建立Key - value的對應。key 和 value可以是任意你需要的類型。根據key值快速查找記錄,查找的復雜度基本是Log(N),如果有1000個記錄,最多查找10次,1,000,000個記錄,最多查找20次。 快速插入Key - Value 記錄。 快速刪除記錄 根據Key 修改value記錄。 遍歷所有記錄。3、使用map使用map得包含map類所在的頭文件 #include//STL頭文件沒有擴展名.hMap對象是模板類,需要關鍵字和存儲對象兩個模板參數,Std::mappersonal;這樣就定義了一個用int作為索引,並擁有相關聯的指向string的指針;為了使用方便,可以對模板類進行一下類型定義。Typedef mapUDT_MAP_INT_CSTRING;

UDT_MAP_INT_CSTRING enumMap;4、在map中插入元素改變map中的條目非常簡單,因為map類已經對[]操作符進行了重載enumMap[1] = "One";

enumMap[2] = "Two";

.....這樣非常直觀,但存在一個性能的問題。插入2時,先在enumMap中查找主鍵為2的項,沒發現,然後將一個新的對象插入enumMap,鍵是2,值是一個空字符串,插入完成後,將字符串賦為”Two”; 該方法會將每個值都賦為缺省值,然後再賦為顯示的值,如果元素是類對象,則開銷比較大。我們可以用以下方法來避免開銷:enumMap.insert(map :: value_type(2, "Two"))19、刪除文件到底如何查找文件呢?我們需要一個結構體和幾個大家可能不太熟悉的函數。這些函數和結構體在的頭文件中,結構體為struct _finddata_t ,函數為_findfirst、_findnext和_fineclose。具體如何使用,我會慢慢講來~首先講這個結構體吧~ struct _finddata_t ,這個結構體是用來存儲文件各種信息的。說實話,這個結構體的具體定義代碼,我沒有找到,不過還好,文檔裡面在_find裡有比較詳細的成員變量介紹。我基本上就把文檔翻譯過來講吧:unsigned atrrib: 文件屬性的存儲位置。它存儲一個unsigned單元,用於表示文件的屬性。文件屬性是用位表示的,主要有以下一些:_A_ARCH(存檔)、 _A_HIDDEN(隱藏)、_A_NORMAL(正常)、_A_RDONLY(只讀)、_A_SUBDIR(文件夾)、_A_SYSTEM(系統)。這些都是在中定義的宏,可以直接使用,而本身的意義其實是一個無符號整型(只不過這個整型應該是2的幾次冪,從而保證只有一位為 1,而其他位為0)。既然是位表示,那麼當一個文件有多個屬性時,它往往是通過位或的方式,來得到幾個屬性的綜合。例如只讀+隱藏+系統屬性,應該為:_A_HIDDEN | _A_RDONLY | _A_SYSTEM 。time_t time_create: 這裡的time_t是一個變量類型(長整型?相當於long int?),用來存儲時間的,我們暫時不用理它,只要知道,這個time_create變量是用來存儲文件創建時間的就可以了。time_t time_access: 文件最後一次被訪問的時間。time_t time_write: 文件最後一次被修改的時間。_fsize_t size: 文件的大小。這裡的_fsize_t應該可以相當於unsigned整型,表示文件的字節數。char name [_MAX_FNAME ]:文件的文件名。這裡的_MAX_FNAME是一個常量宏,它在頭文件中被定義,表示的是文件名的最大長度。以此,我們可以推測出,struct _finddata_t ,大概的定義如下: struct _finddata_t

{

unsigned attrib;

time_t time_create;

time_t time_access;

time_t time_write;

_fsize_t size;

char name[_MAX_FNAME];

}; 前面也說了,這個結構體是用來存儲文件信息的,那麼如何把一個硬盤文件的文件信息“存到”這個結構體所表示的內存空間裡去呢?這就要靠_findfirst、_findnext和_fineclose三個函數的搭配使用了。

首先還是對這三個函數一一介紹一番吧……

long _findfirst( char *filespec, struct _finddata_t *fileinfo );

返回值: 如果查找成功的話,將返回一個long型的唯一的查找用的句柄(就是一個唯一編號)。這個句柄將在_findnext函數中被使用。若失敗,則返回-1。

參數:

filespec:標明文件的字符串,可支持通配符。比如:*.c,則表示當前文件夾下的所有後綴為C的文件。

fileinfo :這裡就是用來存放文件信息的結構體的指針。這個結構體必須在調用此函數前聲明,不過不用初始化,只要分配了內存空間就可以了。函數成功後,函數會把找到的文件的信息放入這個結構體中。

int _findnext( long handle, struct _finddata_t *fileinfo );

返回值: 若成功返回0,否則返回-1。

參數:

handle:即由_findfirst函數返回回來的句柄。

fileinfo:文件信息結構體的指針。找到文件後,函數將該文件信息放入此結構體中。

int _findclose( long handle );

返回值: 成功返回0,失敗返回-1。

參數:

handle :_findfirst函數返回回來的句柄。 大家看到這裡,估計都能猜到個大概了吧?先用_findfirst查找第一個文件,若成功則用返回的句柄調用_findnext函數查找其他的文件,當查找完畢後用,用_findclose函數結束查找。恩,對,這就是正確思路。下面我們就按照這樣的思路來編寫一個查找C:/WINDOWS文件夾下的所有 exe可執行文件的程序。

#include

#include

const char *to_search="C://WINDOWS//*.exe"; //欲查找的文件,支持通配符

int main()

{

long handle; //用於查找的句柄

struct _finddata_t fileinfo; //文件信息的結構體

handle=_findfirst(to_search,&fileinfo); //第一次查找

if(-1==handle)return -1;

printf("%s/n",fileinfo.name); //打印出找到的文件的文件名

while(!_findnext(handle,&fileinfo)) //循環查找其他符合的文件,知道找不到其他的為止

{

printf("%s/n",fileinfo.name);

}

_findclose(handle); //別忘了關閉句柄

system("pause");

return 0;

} 當然,這個文件的查找是在指定的路徑中進行,如何遍歷硬盤,在整個硬盤中查找文件呢?大家可以在網絡上搜索文件遞歸遍歷等方法,這裡不再做進一步介紹。

細心的朋友可能會注意到我在程序的末尾用了一個system函數。這個與程序本身並沒有影響,和以前介紹給大家的使用getchar()函數的作用相同,只是為了暫停一下,讓我們能看到命令提示符上輸出的結果而已。不過system函數本身是一個非常強大的函數。大家可以查查MSDN看看~ 簡單來說,它是一個C語言與操作系統的相互平台,可以在程序裡通過這個函數,向操作系統傳遞command命令。這個簡單的函數會在下一篇的文章中大放異彩,大家拭目以待吧~~

20判斷文件類型 for example:

printf("File type: ");

switch (sb.st_mode & S_IFMT) {

case S_IFBLK: printf("block device\n"); break;

case S_IFCHR: printf("character device\n"); break;

case S_IFDIR: printf("directory\n"); break;

case S_IFIFO: printf("FIFO/pipe\n"); break;

case S_IFLNK: printf("symlink\n"); break;

case S_IFREG: printf("regular file\n"); break;

case S_IFSOCK: printf("socket\n"); break;

default: printf("unknown?\n"); break;

}

#include 主要是對磁盤文件路徑進行操作的函數

#include 目錄遍歷

#include 主要是輸入輸出的函數

#include 主要是字符串函數 例如:strcpy

#include 基本系統數據類型 win32 api21、遍歷文件夾 C++下遍歷文件夾編寫程序遍歷文件夾及其子文件夾下所有文件,並輸出到標准輸出流或者文件流。1. 先考慮在單層目錄下,遍歷所有文件。以C:\WINDOWS為例:用到數據結構_finddata_t,文件信息結構體的指針。struct _finddata_t

{

unsigned attrib; //文件屬性

time_t time_create; //文件創建時間

time_t time_access; //文件上一次訪問時間

time_t time_write; //文件上一次修改時間

_fsize_t size; //文件字節數

char name[_MAX_FNAME]; //文件名

}; 文件屬性是無符號整數,取值為相應的宏:_A_ARCH(存檔),_A_SUBDIR(文件夾),_A_HIDDEN(隱藏),_A_SYSTEM(系統),_A_NORMAL(正常),_A_RDONLY(只讀)。容易看出,通過這個結構體,我們可以得到關於該文件的很多信息。結合以下函數,我們可以將文件信息存儲到這個結構體中://按FileName命名規則匹配當前目錄第一個文件

_findfirst(_In_ const char * FileName, _Out_ struct _finddata64i32_t * _FindData);

//按FileName命名規則匹配當前目錄下一個文件

_findnext(_In_ intptr_t _FindHandle, _Out_ struct _finddata64i32_t * _FindData);

//關閉_findfirst返回的文件句柄

_findclose(_In_ intptr_t _FindHandle);

_findfirst 函數返回的是匹配到文件的句柄,數據類型為long。遍歷過程可以指定文件類型,這通過FileName的賦值來實現,例如要遍歷C:\WINDOWS下的所有.exe文件

bool transfer(string fileName = "C:\\Windows\\*.exe", int exeNum = 0)

{

_finddata_t fileInfo;

long handle = _findfirst(fileName.c_str(), &fileInfo);

if (handle == -1L)

{

cerr << "failed to transfer files" << endl;

return false;

}

do

{

exeNum ++;

cout << fileInfo.name LRESULT Dlg::OnNotifyIcon(WPARAM wParam, LPARAM lParam){在最後加上return TRUE;}3.將afx_msg void OnNotifyIcon(WPARAM wParam, LPARAM lParam)->該成afx_msg LRESULT OnNotifyIcon(WPARAM wParam, LPARAM lParam);編譯下就成功了23、樹形控件 樹形控件在Windows系統中很常見,樹形視圖中以分層結構顯示數據,每層的縮進不同,層次越低縮進越多。屬性控件的節點一般都由標簽和圖標兩部分組成,圖標用來抽象的描述數據,能夠使樹形控件的層次關系更加清晰。樹形控件插入新的樹節點時需要制定新節點與已有節點的關系。TVN_SELCHANGING和TVN_SELCHANGED:在用戶改變了對樹節點的選擇時,控件會發送這兩個消息。消息會附帶一個指向NMTREEVIEW結構的指針,程序可從該結構中獲得必要的信息。兩個消息都會在該結構的itemOld成員中包含原來的選擇項信息,在itemNew成員中包含新選擇項的信息,在action成員中表明是用戶的什麼行為觸發了該通知消息(若是TVC_BYKEYBOARD則表明是鍵盤,若是TVC_BYMOUSE則表明是鼠標,若是TVC_UNKNOWN則表示未知)。兩個消息的不同之處在於,如果TVN_SELCHANGING的消息處理函數返回TRUE,那麼就阻止選擇的改變,如果返回FALSE,則允許改變。

TVN_KEYDOWN:該消息表明了一個鍵盤事件。消息會附帶一個指向NMTVKEYDOWN結構的指針,通過該結構程序可以獲得按鍵的信息。

TVN_BEGINLABELEDIT和TVN_ENDLABELEDIT:分別在用戶開始編輯和結束編輯節點的標簽時發送。消息會附帶一個指向NMTVDISPINFO結構的指針,程序可從該結構中獲得必要的信息。在前者的消息處理函數中,可以調用GetEditControl()成員函數返回一個指向用於編輯標題的編輯框的指針。如果處理函數返回FALSE,則允許編輯,如果返回TRUE,則禁止編輯。在後者的消息處理函數中,NMTVDISPINFO結構中的item.pszText指向編輯後的新標題,如果pszText為NULL,那麼說明用戶放棄了編輯,否則,程序應負責更新節點的標簽,這可以由SetItem()或SetItemText()函數來完成。樹形控件的創建也是有兩種方式,一種是在對話框模板中直接拖入Tree Control控件創建,另一種就是通過CTreeCtrl類的Create成員函數創建。下面主要講後者。CTreeCtrl類的Create成員函數的原型如下: virtual BOOL Create(

DWORD dwStyle,

const RECT& rect,

CWnd* pParentWnd,

UINT nID

); 此函數的原型與前面講到的所有控件類的Create函數都類似。dwStyle指定樹形控件風格的組合,rect指定樹形控件窗口的位置和大小,pParentWnd為指向樹形控件父窗口的指針,nID指定樹形控件的ID。

CTreeCtrl類的主要成員函數CImageList* SetImageList(CImageList * pImageList,int nImageListType);如果樹節點需要顯示圖標時,則必須先創建一個CImageList類的對象,並為其添加多個圖像組成一個圖像序列,然後調用SetImageList函數為樹形控件設置圖像序列,在用InsertItem插入節點時傳入所需圖像在圖像序列中的索引即可。後面的例子中會演示。參數pImageList為指向圖像序列類CImageList的對象的指針,若為NULL則刪除樹形控件的所有圖像。參數nImageListType指定圖像序列的類型,可以是TVSIL_NORMAL(普通圖像序列)或TVSIL_STATE(狀態圖像序列,用圖像表示節點的狀態)。UINT GetCount( ) const;獲取樹形控件中節點的數量。DWORD_PTR GetItemData(HTREEITEM hItem) const;獲取樹形控件中某個指定節點的附加32位數據。參數hItem為指定的樹節點的句柄。BOOL SetItemData(HTREEITEM hItem,DWORD_PTR dwData);為樹形控件中某個指定節點設置附加的32位數據。參數hItem同上,dwData為要設置的32位數據。CString GetItemText(HTREEITEM hItem) const;獲取樹形控件中某個指定節點的標簽文本。參數hItem同上。返回值是包含標簽文本的字符串。BOOL SetItemText(HTREEITEM hItem,LPCTSTR lpszItem);為樹形控件中某個指定節點設置標簽文本。參數hItem同上,lpszItem為包含標簽文本的字符串的指針。HTREEITEM GetNextSiblingItem(HTREEITEM hItem) const;獲取樹形控件中某個指定節點的下一個兄弟節點。參數hItem同上。返回值是下一個兄弟節點的句柄。HTREEITEM GetPrevSiblingItem(HTREEITEM hItem) const;獲取樹形控件中某個指定節點的上一個兄弟節點。參數hItem同上。返回值是上一個兄弟節點的句柄。HTREEITEM GetParentItem(HTREEITEM hItem) const;獲取樹形控件中某個指定節點的父節點。參數hItem同上。返回值是父節點的句柄。HTREEITEM GetRootItem( ) const;獲取樹形控件根節點的句柄。HTREEITEM GetSelectedItem( ) const;獲取樹形控件當前選中節點的句柄。BOOL DeleteAllItems( );刪除樹形控件中的所有節點。刪除成功則返回TRUE,否則返回FALSE。BOOL DeleteItem(HTREEITEM hItem);刪除樹形控件中的某個節點。參數hItem為要刪除的節點的句柄。刪除成功則返回TRUE,否則返回FALSE。HTREEITEM InsertItem(LPCTSTR lpszItem,int nImage,int nSelectedImage,HTREEITEM hParent = TVI_ROOT,HTREEITEM hInsertAfter = TVI_LAST);在樹形控件中插入一個新節點。參數lpszItem為新節點的標簽文本字符串的指針,參數nImage為新節點的圖標在樹形控件圖像序列中的索引,參數nSelectedImage為新節點被選中時的圖標在圖像序列中的索引,參數hParent為插入節點的父節點的句柄,參數hInsertAfter為新節點的前一個節點的句柄,即新節點將被插入到hInsertAfter節點之後。BOOL SelectItem(HTREEITEM hItem);選中指定的樹節點。參數hItem為要選擇的節點的句柄。若成功則返回TRUE,否則返回FALSE。24、列表視圖控件 列表視圖控件能夠把熱河字符串內容以列表的方式顯示出來,這種顯示方式的特點是整潔、直觀、在實際應用中能為用戶帶來方便。列表視圖控件是對列表框控件的改進和延伸。列表視圖控件的列表項一般有圖標和標簽兩部分。圖標是對列表項的圖形描述,標簽是文字描述。當然列表項可以只包含圖標也可以只包含標簽。列表視圖控件有4中風格:Icon,Small Icon,List和Report。列表視圖控件的創建MFC同樣為列表視圖控件的操作提供了CListCtrl類。如果我們不想在對話框模板中直接拖入List Control來使用列表視圖控件,而是希望動態創建它,則要用到CListCtrl類的成員函數Create函數,原型如下:virtual BOOL Create(

DWORD dwStyle,

const RECT& rect,

CWnd* pParentWnd,

UINT nID

); 參數rect為列表視圖控件的位置和尺寸,pParentWnd為指向父窗口的指針,nID指定列表視圖控件的ID,最復雜的一個參數同樣還是dwStyle,它用於設定列表視圖控件的風格,可以是以下風格的組合:

風格 含義

LVS_ALIGNLEFT 顯示格式是大圖標或小圖標時,標簽放在圖標的左邊

LVS_ALIGNTOP 顯示格式是大圖標或小圖標時,標題放在圖標的上邊

LVS_AUTOARRANGE 顯示格式是大圖標或小圖標時,自動排列控件中的列表項

LVS_EDITLABELS 用戶可以修改標簽文本

LVS_ICON 指定大圖標顯示格式

LVS_LIST 指定列表顯示格式

LVS_NOCOLUMNHEADER 在報表格式中不顯示列的表頭

LVS_NOLABELWRAP 顯示格式是大圖標時,使標簽文本單行顯示。默認是多行顯示

LVS_NOSCROLL 列表視圖控件無滾動條,此風格不能與LVS_LIST或LVS_REPORT組合使用

LVS_NOSORTHEADER 報表格式的列表視圖控件的表頭不能作為排序按鈕使用

LVS_OWNERDRAWFIXED 由控件的擁有者負責繪制表項

LVS_REPORT 指定報表顯示格式

LVS_SHAREIMAGELISTS 使列表視圖共享圖像序列

LVS_SHOWSELALWAYS 即使控件失去輸入焦點,仍顯示出項的選擇狀態

LVS_SINGLESEL 指定只能有一個列表項被選中。默認時可以多項選擇

LVS_SMALLICON 指定小圖標顯示格式

LVS_SORTASCENDING 按升序排列列表項

LVS_SORTDESCENDING 按降序排列列表項 與前面的控件一樣,除了以上風格一般我們還要為列表視圖控件設置WS_CHILD和WS_VISIBLE風格。對於直接在對話框模板中創建的列表視圖控件,其屬性頁中的屬性與上述風格是對應的,例如,屬性Alignment默認為Left,也就等價於指定了LVS_ALIGNLEFT風格。

CListCtrl類的主要成員函數

CListCtrl類有很多成員函數,雞啄米這裡就為大家介紹幾個常用的主要成員函數。

UINT GetSelectedCount( ) const;

該函數返回列表視圖控件中被選擇列表項的數量。

POSITION GetFirstSelectedItemPosition( ) const;

獲取列表視圖控件中第一個被選擇項的位置。返回的POSITION值可以用來迭代來獲取其他選擇項,可以當作參數傳入下面的GetNextSelectedItem函數來獲得選擇項的索引。如果沒有被選擇項則返回NULL。

int GetNextSelectedItem(POSITION& pos) const;

該函數獲取由pos指定的列表項的索引,然後將pos設置為下一個位置的POSITION值。參數pos為之前調用GetNextSelectedItem或GetFirstSelectedItemPosition得到的POSITION值的引用。返回值就是pos指定列表項的索引。

int GetItemCount( ) const;

獲取列表視圖控件中列表項的數量。

int InsertColumn(int nCol,const LVCOLUMN* pColumn );

int InsertColumn(int nCol,LPCTSTR lpszColumnHeading,int nFormat = LVCFMT_LEFT,int nWidth = -1,int nSubItem = -1 );

這兩個函數用於在報表式列表視圖控件中插入列。第一個函數中,nCol參數為插入列的索引,pColumn參數指向LVCOLUMN結構,其中包含了插入列的屬性。第二個函數中,nCol參數也是插入列的索引,lpszColumnHeading參數為列標題字符串,nFormat參數為列中文本的對齊方式,可以是LVCFMT_LEFT、LVCFMT_RIGHT或LVCFMT_CENTER,nWidth參數為列寬,nSubItem為插入列對應列表子項的索引。兩個函數在成功時都返回新列的索引,失敗都返回-1。

BOOL DeleteColumn(int nCol);

該函數用於刪除列表視圖控件中的某列。參數nCol為刪除列的索引。刪除成功則返回TRUE,失敗返回FALSE。

int InsertItem(int nItem,LPCTSTR lpszItem);

向列表視圖控件中插入新的列表項。參數nItem為要插入項的索引,參數lpszItem為要插入項的標簽字符串。如果插入成功則返回新列表項的索引,否則返回-1。

BOOL DeleteItem(int nItem);

從列表視圖控件中刪除某個列表項。參數nItem指定了要刪除的列表項的索引。刪除成功則返回TRUE,否則返回FALSE。

CString GetItemText(int nItem,int nSubItem) const;

獲取指定列表項或列表子項的顯示文本。參數nItem指定了列表項的索引,參數nSubItem指定了列表子項的索引。

BOOL SetItemText(int nItem,int nSubItem,LPCTSTR lpszText);

設置指定列表項或列表子項的顯示文本。參數nItem和nSubItem同GetItemText。參數lpszText為要設置的顯示文本字符串。如果設置成功則返回TRUE,否則返回FALSE。

DWORD_PTR GetItemData(int nItem) const;

該函數用於獲取指定列表項的附加32位數據。參數nItem為列表項的索引。返回值就是由nItem指定列表項的附加32位數據。

BOOL SetItemData(int nItem,DWORD_PTR dwData);

該函數用於為指定列表項設置附加32位是數據。參數nItem為列表項的索引,參數dwData為列表項的附加32位數據。

25、CString類 CString類作為MFC的常用類,只要是從事MFC開發,基本都會遇到使用CString類的場合。因為字符串的使用比較普遍,而CString類又提供了對字符串的便捷操作,所以它給MFC開發人員帶來了高的開發效率。使用VS2010的話,可能會見到CStringT,實際上它是一個操作可變長度字符串的模板類。CStringT模板類有三個實例:CString、CStringA和CStringW,它們分別提供對TCHAR、char和wchar_t字符類型的字符串的操作。char類型定義的是Ansi字符,wchar_t類型定義的是Unicode字符,而TCHAR取決於MFC工程的屬性對話框中的Configuration Properties->General->Character Set屬性,如果此屬性為Use Multi-Byte Character Set,則TCHAR類型定義的是Ansi字符,而如果為Use Unicode Character Set,則TCHAR類型定義的是Unicode字符。CString類又很多構造函數:CString(const CString&tringSrc);將一個已經存在的CString對象stringSrc的內容拷貝到該CString對象。例如:1. CString str1(_T("panda")); // 將常量字符串拷貝到str1

2. CString str2(str1); // 將str1的內容拷貝到str2

CString(LPCTSTR lpch, int nLength);

將字符串lpch中的前nLength個字符拷貝到該CString對象。例如:CString str(_T(“panda”),3); // 構造的字符串對象內容為”pan” CString(TCHAR ch, int nLength = 1);使用此函數構造的CString對象中將含有nLength個重復的ch字符。例如:CString str(_T(‘p’),3); // str為”ppp” CString類的大小寫轉換及順序轉換函數CString& MakeLower();將字符串中的所有大寫字符轉換為小寫字符。CString& MakeUpper();將字符串中的所有小寫字符轉換為大寫字符。CString& MakeReverse();將字符串中所有字符的順序顛倒。例如: CString str(_T(“JiZhuoMi”)); str.MakeLower(); // str為”jizhuomi” str.MakeUpper(); // str為”JIZHUOMI” str.MakeReverse(); // str為”IMOUHZIJ”CString對象的連接多個CString對象的連接可以通過重載運算符+、+=實現。例如:C++代碼 CString str(_T(“panda”)); // str內容為”panda” str = _T(“kongfun”) + str + _T(“.”); // str為”kongfunpanda.” str += _T(“net”); // str為”kongfunpanda.net”CString對象的比較CString對象的比較可以通過==、!=、<、>、<=、>=等重載運算符實現,也可以使用Compare和CompareNoCase成員函數實現。int Compare(PCXSTR psz) const;將該CString對象與psz字符串比較,如果相等則返回0,如果小於psz則返回值小於0,如果大於psz則返回值大於0。int CompareNoCase(PCXSTR psz) const throw();此函數與Compare功能類似,只是不區分大小寫。例如:C++代碼 CString str1 = _T(“JiZhuoMi”); CString str2 = _T(“jizhuomi”); if (str1 == str2) { // 因為str1、str2不相等,所以不執行下面的代碼 … } if (0 == str1.CompareNoCase(str2)) { // 因為不區分大小寫比較時,CompareNoCase函數返回0,所以執行下面的代碼 … }CString對象字符串的提取操作CString Left(int nCount) const;提取該字符串左邊nCount個字符的子字符串,並返回一個包含這個子字符串的拷貝的CString對象。CString Right(int nCount) const;提取該字符串右邊nCount個字符的子字符串,並返回一個包含這個子字符串的拷貝的CString對象。CString Mid(int iFirst,int nCount) const;提取該字符串中以索引iFirst位置開始的nCount個字符組成的子字符串,並返回一個包含這個子字符串的拷貝的CString對象。CString Mid(int iFirst) const;提取該字符串中以索引iFirst位置開始直至字符串結尾的子字符串,並返回一個包含這個子字符串的拷貝的CString對象。例如:C++代碼 CString str1 = _T(“kongfunpanda”); CString str2 = str1.Left(3); // str2為”kon” str2 = str1.Right(2); // str2為”da” str2 = str1.Mid(1,3); // str2為”ong” str2 = str1.Mid(5); // str2為”unpanda”CString對象字符串的查找操作int Find(PCXSTR pszSub,int iStart=0) const throw( );int Find(XCHAR ch,int iStart=0) const throw( );在CString對象字符串的iStart索引位置開始,查找子字符串pszSub或字符ch第一次出現的位置,如果沒有找到則返回-1。int FindOneOf(PCXSTR pszCharSet) const throw( );查找pszCharSet字符串中的任意字符,返回第一次出現的位置,找不到則返回-1。int ReverseFind(XCHAR ch) const throw();從字符串末尾開始查找指定的字符ch,返回其位置,找不到則返回-1。這裡要注意,盡管是從後向前查找,但是位置的索引還是要從開始算起。C++代碼 CString str = _T(“panda”); int nIndex1 = str.Find(_T(“an”)); // nIndex1的值為1 int nIndex2 = str.FindOneOf(_T(“nad”)); // nIndex2的值為1 int nIndex3 = str.ReverseFind(_T(‘d’)); // nIndex3的值為3CString類對象字符串的替換與刪除int Replace(PCXSTR pszOld,PCXSTR pszNew);用字符串pszNew替換CString對象中的子字符串pszOld,返回替換的字符個數。int Replace(XCHAR chOld,XCHAR chNew);用字符chNew替換CString對象中的字符chOld,返回替換的字符個數。int Delete(int iIndex,int nCount = 1);從字符串中刪除iIndex位置開始的nCount個字符,返回刪除操作後的字符串的長度。int Remove(XCHAR chRemove);刪除字符串中的所有由chRemove指定的字符,返回刪除的字符個數。例如:C++代碼 CString str = _T(“panda”); int n1 = str.Replace(_T(‘a’), _T(‘b’)); // str為”pbndb”,n1為2 int n2 = str.Delete(1,2); // str為”pdb”,n2為3 int n3 = str.Remove(_T(‘d’)); // str為”pb”,n3為1CString類的格式化字符串方法使用CString類的Format成員函數可以將int、short、long、float、double等數據類型格式化為字符串對象。void __cdecl Format(PCXSTR pszFormat,[, argument]…);參數pszFormat為格式控制字符串;參數argument可選,為要格式化的數據,一般每個argument在pszFormat中都有對應的表示其類型的子字符串,int型的argument對應的應該是”%d”,float型的應對應”%f”,等等。例如:C++代碼 CString str; int a = 1; float b = 2.3f; str.Format(_T(“a=%d,b=%f”), a, b); // str為”a=1,b=2.300000”26、C++_MFC如何遍歷整個目錄樹查找文件  在應用程序的開發過程中,會遇到如何查找某一文件以確定此文件路徑的問題。利用CFileFind類可以比較方便地在當前目錄下進行文件查找,但卻不能對其子目錄中的文件進行搜尋。而實際應用中往往需要對某一整個目錄樹,甚至是整個C盤或D盤驅動器進行文件搜尋。通過實踐,我們在Visual C++ 6.0中編程實現了如何遍歷任意目錄樹,以查找某一特定的文件。  在下面的具體陳述中可以看到,在確定要查找的文件名和要進行搜索的目錄的名稱後,將調用函數Search_Directory進行文件的查找。首先依次查找當前目錄下的每一個實體(文件或是子目錄),如果是某一子目錄,則進入該子目錄並遞歸調用函數Search_Dirctory進行查找,查找完畢之後, 再返回上一級目錄;如果不是子目錄而是某一文件,則判斷其是否就是我們要查找的文件,如果是則輸出其完整的文件路徑。這樣,通過Search_Directory函數的反復遞歸調用,就可以實現對整個目錄,包括子目錄的遍歷搜索。下面將舉例詳細講述如何在VC++中編程實現在整個目錄樹中的文件查找。  1. 在Visual C++ 6.0中用默認方式創建了一基於對話框的應用程序Search。在主窗口對話框上放置一命令按鈕,其Caption為“Search File”,ID為ID_BUTTON_SEARCH。單擊此按鈕將完成文件的查找工作。  2. 利用ClassWizard為“Search File”按鈕的BN_CLICKED 事件添加處理函數OnButtonSearch,代碼如下:#include 〈direct.h〉#include 〈io.h〉void CSearchDlg::OnButtonSearch(){// TODO: Add your control notification handler code herechar szFilename[80];// 字符串 szFilename 表示要查找的文件名strcpy(szFilename,”Mytext.txt”);_chdir(“d:\”); // 進入要查找的路徑(也可為某一具體的目錄)// 查找文件, 如果查到則顯示文件的路徑全名Search_Directory(szFilename);// 為CSearchDlg類的一成員函數MessageBox(″查找文件完畢!″);// 顯示查找完畢的信息}  3. 在CSearchDlg類中增加成員函數Search_Directory,它將完成具體的文件查找工作,代碼如下:void CSearchDlg::Search_Directory(char* szFilename)

{

long handle;

struct _finddata_t filestruct;

//表示文件(或目錄)的信息

char path_search[_MAX_PATH];

//表示查找到的路徑結果

// 開始查找工作, 找到當前目錄下的第一個實體(文件或子目錄),

// "*"表示查找任何的文件或子目錄, filestruct為查找結果

handle = _findfirst("*", &filestruct);

// 如果handle為-1, 表示當前目錄為空, 則結束查找而返回

if((handle == -1)) return;

// 檢查找到的第一個實體是否是一個目錄(filestruct.name為其名稱)

if( ::GetFileAttributes(filestruct.name) & FILE_ATTRIBUTE_DIRECTORY )

{

// 如果是目錄, 則進入該目錄並遞歸調用函數Search_Dirctory進行查找,

// 注意: 如果目錄名的首字符為'.'(即為"."或".."), 則不用進行查找

if( filestruct.name[0] != '.' )

{

_chdir(filestruct.name);

Search_Directory(szFilename);

// 查找完畢之後, 返回上一級目錄

_chdir("..");

}

}

else // 如果第一個實體不是目錄, 則檢查是否是要查找的文件

{

// stricmp對兩字符串進行小寫形式的對比, 返回為0表示完全一致

if( !stricmp(filestruct.name, szFilename) )

{

// 先獲得當前工作目錄的全路徑

_getcwd(path_search,_MAX_PATH);

// 再獲得文件的完整的路徑名(包含文件的名稱)

strcat(path_search,"\\");

strcat(path_search,filestruct.name);

MessageBox(path_search); //輸出顯示

}

}

// 繼續對當前目錄中的下一個子目錄或文件進行與上面同樣的查找

while(!(_findnext(handle,&filestruct)))

{

if( ::GetFileAttributes(filestruct.name) & FILE_ATTRIBUTE_DIRECTORY )

{

if(*filestruct.name != '.')

{

_chdir(filestruct.name);

Search_Directory(szFilename);

_chdir("..");

}

}

else

{

if(!stricmp(filestruct.name,szFilename))

{

_getcwd(path_search,_MAX_PATH);

strcat(path_search,"\\");

strcat(path_search,filestruct.name);

MessageBox(path_search);

}

}

}

_findclose(handle);

// 最後結束整個查找工作

}  這樣我們就可以對整個目錄進行遍歷搜索,查找某一特定的文件,並輸出顯示其完整的文件路徑。以上的程序在Visual C++ 6.0中已調試通過。27、兩種方法實現MFC 對話框最大化時控件也隨比例最大化或者還原 方法一:單個控件ID操作第一步、在對話框類中(.h文件)定義如下變量和函數定義如下幾個變量:[cpp] view plaincopy

1. void ReSize(int nID);

2. BOOL change_flag;

3. float m_Multiple_height;

4. float m_Multiple_width;

[cpp] view plaincopy

1. afx_msg void OnSize(UINT nType, int cx, int cy); 第二步、在OnInitDialog()中 計算出當前對話框的大小與最大化後大小[cpp] view plaincopy

1. CRect rect;

2. ::GetWindowRect(m_hWnd,rect);//這裡m_hWnd為窗口句柄,如果不存在此變量則在該行代碼前加一句:HWND h_Wnd=GetSafeHwnd( );

3. ScreenToClient(rect);

4. LONG m_nDlgWidth = rect.right - rect.left;

5. LONG m_nDlgHeight = rect.bottom - rect.top;

6. //Calc 分辨率

7. LONG m_nWidth = GetSystemMetrics(SM_CXSCREEN);

8. LONG m_nHeight = GetSystemMetrics(SM_CYSCREEN);

9. //計算放大倍數(要用float值,否則誤差很大)

10. m_Multiple_width = float(m_nWidth)/float(m_nDlgWidth);

11. m_Multiple_height = float(m_nHeight)/float(m_nDlgHeight);

12. change_flag = TRUE;//用來判斷OnSize執行時,OninitDialg是否已經執行了 第三步、給對話框添加 WM_SIZE消息[cpp] view plaincopy

1. //給對話框添加 VM_SIZE消息

2. void CStuDemoDlg::OnSize(UINT nType, int cx, int cy)

3. {

4. CDialog::OnSize(nType, cx, cy);

5.

6. // TODO: Add your message handler code here

7. if (change_flag)//如果OninitDlg已經調用完畢

8. {

9. ReSize(IDC_STATIC_1);

10. ReSize(IDC_STATIC_2);

11. ReSize(IDC_EDIT11);//

12. ReSize(IDC_EDIT12);//

13. ReSize(IDC_LIST_SHOW);//LIST

14. ReSize(IDC_BUTTON_ADD);

15. ReSize(IDC_BUTTON_DEL);

16. ReSize(IDOK);

17. ReSize(IDCANCEL);

18. //恢復放大倍數,並保存 (確保還原時候能夠還原到原來的大小)

19. m_Multiple_width = float(1)/m_Multiple_width;

20. m_Multiple_height = float(1)/m_Multiple_height;

21. }

22. } 第四步、刷新控件:根據比例計算控件縮放的大小,然後movewindow 到新矩形上[cpp] view plaincopy

1. void CStuDemoDlg::ReSize(int nID)

2. {

3. CRect Rect;

4. GetDlgItem(nID)->GetWindowRect(Rect);

5. ScreenToClient(Rect);

6. //計算控件左上角點

7. CPoint OldTLPoint,TLPoint;

8. OldTLPoint = Rect.TopLeft();

9. TLPoint.x = long(OldTLPoint.x *m_Multiple_width);

10. TLPoint.y = long(OldTLPoint.y * m_Multiple_height );

11. //計算控件右下角點

12. CPoint OldBRPoint,BRPoint; OldBRPoint = Rect.BottomRight();

13. BRPoint.x = long(OldBRPoint.x *m_Multiple_width);

14. BRPoint.y = long(OldBRPoint.y * m_Multiple_height );

15. //移動控件到新矩形

16. Rect.SetRect(TLPoint,BRPoint);

17. GetDlgItem(nID)->MoveWindow(Rect,TRUE);

18. } 方法二:集體控件操作第一步、在對話框類中(.h文件)定義如下變量和函數[cpp] view plaincopy

1. void ReSize();

2. POINT old;

[cpp] view plaincopy

1. afx_msg void OnSize(UINT nType, int cx, int cy); 第二步、在OnInitDialog()中 計算出原始對話框的大小[cpp] view plaincopy

1. CRect rect;

2. GetClientRect(&rect); //取客戶區大小

3. old.x=rect.right-rect.left;

4. old.y=rect.bottom-rect.top; 第三步、添加 WM_SIZE消息[cpp] view plaincopy

1. void CStuDemoDlg::OnSize(UINT nType, int cx, int cy)

2. {

3. CDialog::OnSize(nType, cx, cy);

4. // TODO: Add your message handler code here

5. if (nType==SIZE_RESTORED||nType==SIZE_MAXIMIZED)

6. {

7. ReSize();

8. }

9. } 第四步、刷新控件函數[cpp] view plaincopy

1. void CStuDemoDlg::ReSize()

2. {

3. float fsp[2];

4. POINT Newp; //獲取現在對話框的大小

5. CRect recta;

6. GetClientRect(&recta); //取客戶區大小

7. Newp.x=recta.right-recta.left;

8. Newp.y=recta.bottom-recta.top;

9. fsp[0]=(float)Newp.x/old.x;

10. fsp[1]=(float)Newp.y/old.y;

11. CRect Rect;

12. int woc;

13. CPoint OldTLPoint,TLPoint; //左上角

14. CPoint OldBRPoint,BRPoint; //右下角

15. HWND hwndChild=::GetWindow(m_hWnd,GW_CHILD); //列出所有控件

16. while(hwndChild)

17. {

18. woc=::GetDlgCtrlID(hwndChild);//取得ID

19. GetDlgItem(woc)->GetWindowRect(Rect);

20. ScreenToClient(Rect);

21. OldTLPoint = Rect.TopLeft();

22. TLPoint.x = long(OldTLPoint.x*fsp[0]);

23. TLPoint.y = long(OldTLPoint.y*fsp[1]);

24. OldBRPoint = Rect.BottomRight();

25. BRPoint.x = long(OldBRPoint.x *fsp[0]);

26. BRPoint.y = long(OldBRPoint.y *fsp[1]);

27. Rect.SetRect(TLPoint,BRPoint);

28. GetDlgItem(woc)->MoveWindow(Rect,TRUE);

29. hwndChild=::GetWindow(hwndChild, GW_HWNDNEXT);

30. }

31. old=Newp;

32. } 總結:就個人而言,本人還是比較傾向第二種方法,畢竟可以少操作控件ID,否則少了一個布局都會發生變化。版權聲明:本文為博主原創文章,未經博主允許不得轉載。28、1.#include #include

void SearchFile(const char* FileName, const char* Path, TStrings* Strings)

{

char *Name;

char File[512];

struct ffblk blk;

strcpy(File, Path);

Name = File+strlen(File);

if (*(Name-1)!='\\') *Name++ = '\\';

strcpy(Name, "*.*");

if (findfirst(File,&blk,FA_RDONLY|

FA_HIDDEN|FA_SYSTEM|FA_DIREC))

return;

do {

strcpy(Name, blk.ff_name);

if (blk.ff_attrib&FA_DIREC) {

if (*Name != '.')

SearchFile(FileName, File, Strings);

}

else if(strcmpi(Name,FileName))

Strings->Add(File);

}while(findnext(&blk)==0);

findclose(&blk); /* 有些編譯器沒有findclose,這行去掉 */

}

TStringList* SearchFile(const char* FileName)

{

char buf[128];

TStringList* Strings;

Strings = new TStringList;

GetLogicalDriveStrings(128, buf);

for(char* s=buf; *s!=0; s+=strlen(s)+1) {

SearchFile(FileName, s, Strings);

}

return Strings;

} 我原來寫過的一個程序中的代碼: void __fastcall SearchTxtDocFile::Execute()

{

DWORD AllDrives=GetLogicalDrives();

if (AllDrives==0)

return;

AnsiString Dir;

char d;

for(int i=2; i<26; i++)

{

if (AllDrives & (1<先取的所有盤,然後遍歷

- 剛學BCB時寫過,你在#codego.net#的軟件裡找“文件遍歷”,有源碼

- 29、C++內存分配函數Malloca/alloca:

1、在調用alloca的函數返回的時候,它分配的內存會自動釋放。也就是說,用alloca分配的內存在棧上。所以釋放不需要用戶使用free。

2、alloca不具可移植性,而且在沒有傳統堆棧的機器上很難實現。當它的返回值直接傳入另一個函數時會帶來問題,因為他分配在棧上。

總結:由於這些原因,alloca不宜使用在必須廣泛移植的程序中,不管它可能多麼有用。

Realloca:

重新分配內存並返回void類型,如果沒有足夠的內存擴展內存塊,則原來的指向的內存指針無變化,並返回NULL;如果重新分配大小設為0,而釋放原來的內存塊,並返回NULL。

Calloc:

分配指定數目的元素,每個元素的大小由size指定,並將其初始化為0,calloc調用malloc使用C++_set_new_mode函數來設置新的處理方式,默認情況下,malloc失敗時不調用分配內存的處理程序例程。

Malloc:

從堆上分配指定大小的字節數並返回void類型,如分配失敗則返回NULL,malloc分配的字節數可能比指定的字節要多,這是由內存對奇方式決定的,malloc實際上調用了HeapAlloc函數,因此malloc分配的內存也不能跨進程調用。

New:

分配內存的對象或數組類型的對象和返回一個適當類型,並調用對象的構造函數及在delete時調用對象的析構函數。其實現基於malloc調用。

下面是windows系統提供的API函數:

1、VirtualAlloc/VirtualAllocaEx

在虛擬地址空間中保留或提交內存,每次操作大小為Page頁大小的整數倍,因此需要自己計算內存分配算法,在沒有使用MEM_RESET的情況下會初始化內存塊(0),VirtualAllocEx還可以在其他進程中的保留內存操作,並使用其對於的VirtualFree/VirtualFreeEx釋放內存。

2.HeapAlloc/HeapFree

在指定的Heap中分配內存,heap應該由CreateHeap或GetProcessHeap返回,分配的內存不能移動,CreateHeap創建的堆只能在調用的進程中使用,因此如需跨進程滴啊用不能使用此種分配方式,由HeapFree釋放。

3、GlobalAlloc/GlobalFree

從全局堆分配指定字節的內存,分配的內存可跨進程訪問,並使用8字節對齊方式,有GloabalFree釋放,在使用GlobalAlloc分配的內存塊時需調用GlobalLock和GlobalUnlock函數。

PS:為了更好的理解內存分配,我們可以了解一下內存分區。

1)、棧區(stack)— 由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似於數據結構中的棧。

2)、堆區(heap) — 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收 。

3)、全局區(靜態區)(static)—,全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域, 未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。 - 程序結束後有系統釋放。注意:全局區又可分為未初始化全局區:.bss段和初始化全局區:.data段。

4)、常量區—常量字符串就是放在這裡的。 程序結束後由系統釋放

5)、代碼區—存放函數體的二進制代碼。

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