1、如果用VC開發程式,常見這麼幾個錯誤,C2001,C2005,這些錯誤的原因是什麼。
答:在學習VC++的過程中,遇到的C2001錯誤的錯誤訊息主要為:unresolved external symbol(不確定的外部“符號”)。如果串連程式不能在所有的庫和目標檔案內找到所引用的函數、變數或標籤,將產生此錯誤訊息。
一般來說,發生該錯誤的原因有兩個:一是所引用的函數、變數不存在、拼字不正確或者使用錯誤;其次可能使用了不同版本的串連庫。
編程中也經常能遇到C2005錯誤,即重複定義錯誤,其實LNK2005錯誤並不是一個很難解決的錯誤。
2、請說明虛函數的本質和實現機制。
答:虛函數的本質是通過基類訪問衍生類別定義的函數。虛函數只能藉助於指標或者引用來達到多態效果。
3、分別說出描述點對象、大小對象和矩形對象的類名稱。
答:CPoint類,CSize類和CRect類。
4、非同步socket編程中,send不出資料的原因是什麼,你是怎麼處理的?
答:非同步socket編程中,send不出資料的原因共有兩個,分別是:TCP下串連斷開了和該socket處在阻塞狀態(也就是說在發送資料中)。處理的辦法就是記錄下該SOCKET的狀態,當狀態為阻塞的時間,放入緩衝,當該SOCKET再次可寫時,發送。
5、描述並比較以下對象:事件,信標,臨界區,互斥對象。
答:這些對象都是用於線程同步的對象。
臨界區:一種保證在某一時刻只有一個線程能訪問資料的簡便辦法。它只可以在同一進程內部使用。主要API函數有,產生臨界區:InitializeCriticalSection,刪除臨界區:DeleteCriticalSection,進入臨界區:EnterCriticalSection,退出臨界區:Le***eCriticalSection。
互斥對象:互斥對象跟臨界區相似,但它不僅僅能夠在同一應用程式不同 線程中實現資源的安全共用,而且可以在不同應用程式的線程之間實現對資源的安全共用,當然下面兩者也有這個特點。主要API函數有,建立互斥量: CreateMutex,開啟一個存在的互斥量: OpenMutex,釋放互斥量的使用權:ReleaseMutex,關閉互斥量: CloseHandle。
信標:使用訊號量(信標)最重要用途是:訊號允許多個線程同時使用共用資源,它指出了同時訪問共用資源的線程最大數目。它的API函數和使用方法都與互斥對象相似,如建立號誌:CreateSemaphore,傳入的參數可以指定號誌的初始值。
事件:用來通知其他進程/線程某件操作已經完成。API函數有建立,開啟事件對象等,特殊點的是可以用函數SetEvent人工設定事件為有無訊號狀態,因此建立事件對象時可以有兩種方式,一種為自動重設,一種為人工重設。只有人工重設方式建立的事件對象才能正確使用函數SetEvent。
6、非同步IO和同步IO有什麼區別?
答:非同步IO當函數返回時不一定就完成了IO操作,而同步IO已經完成了。所以非同步IO需要有一個事件,當IO完成時會設定此事件,調用者在事件上等待。
7、分別描述類CDatabase和類CRecordset的用途。
答:CDatabase類用於建立與資料來源的串連,CRecordset類功能強大,可以將它看做資料來源的一個記錄集,其中封裝了對記錄集的各種操作,如:滾動,修改,增加,刪除,查詢等。
8、cdecl、stdcall、fastcall是什嗎?哪種可以實現個數不定的入口參數,為什嗎?
答:三者都是函數調用的約定。
(1)fastcall:採用寄存器傳遞參數,特點就是快了。
(2)cdecl:cdeclare的縮寫,是C和C++程式的預設調用方式,規則是,按從右至左的順序壓參數入棧,由調用者把參數彈出棧,對於傳送參數的記憶體棧是由調用者來維護的,正因為如此,只有這種調用方式可實現個數不定的入口參數。
(3)stdcall:是Pascal程式的預設調用方式,規則是,按從右至左的順序壓參數入棧,被調用的函數在返回前清理傳送參數的記憶體棧。 上兩者的主要區別是前者由調用者清理棧,後者由被調用的函清理棧。當然函數名的修飾部分也是不同的。
9、如何查出記憶體流失和非法操作的BUG(在Release版本下)?
答:使用map檔案。
10、程式中的局部變數、全域變數和動態申請資料具體存在於什麼位置?
答:程式的局部變數存在於堆棧中,全域變數存在於靜態區中,動態申請資料存在於堆中。
11、new delete 與malloc free的聯絡與區別?
答:new delete 與malloc free都是在堆(heap)上進行動態記憶體操作。用malloc函數需要指定記憶體配置的位元組數並且不能初始化對象,new 會自動調用對象的建構函式。delete會調用對象的destructor,而free不會調用對象的destructor。
12、描述記憶體配置方式以及它們的區別?
答:(1)從靜態儲存地區分配。記憶體在程式編譯的時候就已經分配好,這塊記憶體在程式的整個運行期間都存在。例如全域變數,static變數。
(2)在棧上建立。在執行函數時,函數內局部變數的儲存單元都可以在棧上建立,函數執行結束時這些儲存單元自動被釋放。棧記憶體配置運算內建於處理器的指令集。
(3)從堆上分配,亦稱動態記憶體分配。程式在啟動並執行時候用malloc或new 申請任意多少的記憶體,程式員自己負責在何時用free或delete釋放記憶體。動態記憶體的生存期由程式員決定,使用非常靈活,但問題也最多。
13、指標和引用有什麼區別?
答:(1)引用在建立的同時必須初始化,即引用到一個有效對象;而指標在定義的時候不必初始化,可以在定義後面的任何地方重新賦值。
(2)不存在NULL引用,引用必須與合法的儲存單元關聯;而指標則可以是NULL。
(3)引用一旦被初始化為指向一個對象,它就不能被改變為另一個對象的引用;而指標在任何時候都可以改變為指向另一個對象.給引用賦值並不是改變它和原始對象的綁定關係。
(4)引用的建立和銷毀並不會調用類的拷貝建構函式。
(5)語言層面,引用的用法和對象一樣;在二進位層面,引用一般都是通過指標來實現的,只不過編譯器幫我們完成了轉換。
14、有一段文本,統計其中的單詞數。例如:As a technology , "HailStorm"is so new that it is still only known by its code name.(注意:單詞間的間隔不一定是一個空格。)
答:假設該文本已存入text這個數組裡,可執行程式代碼如下:
void main(){
char text[1000]={"As a technology,'HailStorm'is so new
that it is still only known by its code name."};
int i=0,count=0;
bool flag=true;
while (text&&i<1000){
if (text==' '){
flag=true;
}else if (flag==true && ((text>='a'&&text<='z')
||(text>='A'&&text<='Z'))){?
count++;flag=false;
}
i++;
}
cout<<count;
}