c部分::::::::::::::::::::::::::::::::::: 27、 關鍵字volatile有什么含意? 並給出三個不同的例 子。 【參考答案】一個定義為volatile的變量是說這變量可 能會被意想不到地改變,這樣,編譯器就不會去假設 這個變量的值了。精確地說就是,優化器在用到這個 變量時必須每次都小心地重新讀取這個變量的值,而 不是使用保存在寄存器里的備份。下面是volatile變量 的幾個例子: 1). 並行設備的硬件寄存器(如:狀態寄存器) 2). 一個中斷服務子程序中會訪問到的非自動變量 (Non-automatic variables) 3). 多線程應用中被幾個任務共享的變量 31、const 有什么用途?(請至少說明兩種) 【標准答案】: (1)可以定義 const 常量 (2)const 可以修飾函數的參數、返回值,甚至函數 的定義體。被 const 修飾的東西都受到強制保 32、 static有什么用途?(請至少說明兩種) 【標准答案】 1.限制變量的作用域(static全局變量); 2.設置變量的存儲域(static局部變量)。 34、如何引用一個已經定義過的全局變量? 【標准答案】可以用引用頭文件的方式,也可以用 extern關鍵字,如果用引用頭文件方式來引用某個在 頭文件中聲明的全局變理,假定你將那個變量寫錯了 ,那么在編譯期間會報錯,如果你用extern方式引用 時,假定你犯了同樣的錯誤,那么在編譯期間不會報 錯,而在連接期間報錯。 35、全局變量可不可以定義在可被多個.C文件包含的 頭文件中?為什么? 【標准答案】可以,在不同的C文件中以static形式來聲 明同名全局變量。可以在不同的C文件中聲明同名的全 局變量,前提是其中只能有一個C文件中對此變量賦初 值,此時連接不會出錯。 37、 Heap與stack的差別。 【標准答案】Heap是堆,stack是棧。 Stack的空間由操作系統自動分配/釋放,Heap上的空 間手動分配/釋放。 Stack空間有限,Heap是很大的自由存儲區 C中的malloc函數分配的內存空間即在堆上,C++中對 應的是new操作符。 程序在編譯期對變量和函數分配內存都在棧上進行,且 程序運行過程中函數調用時參數的傳遞也在棧上進行。 1).全局全局變量本身就是靜態存儲方式, 靜態全局變量當然也是靜態存儲方式。但是他們的作用域,非靜態全局 變量的作用域是整個源程序(多個源文件可以共同使用); 而靜態全局變量則限制了其作用域, 即只在定義該變量的源文件內有效, 在同一源程序的其它源文件中不能使用它。 2).static函數(也叫內部函數) 只能被本文件中的函數調用,而不能被同一程序其它文件中的函數調用。區別於一般的非靜態函數(外部函數) static在c里面可以用來修飾變量,也可以用來修飾函數。 先看用來修飾變量的時候。變量在c里面可分為存在全局數據區、棧和堆里。其實我們平時所說的堆棧是棧而不包含對,不要弄混。 程序的局部變量存在於棧(stack)中,全局 變量存在於靜態數據區 中,動態申請數據存在於堆( heap)中。 49、什么是預編譯,何時需要預編譯: 【標准答案】1、總是使用不經常改動的大型代碼體 。 2、程序由多個模塊組成,所有模塊都使用一組標准 的包含文件和相同的編譯選項。在這種情況下,可以 將所有包含文件預編譯為一個預編譯頭。 72、 中斷是嵌入式系統中重要的組成部分,這導致了很多編譯開發商提 供一種擴展—讓標准C支持中斷。具代表事實是,產生了一個新的關鍵字 __interrupt。下面的代碼就使用了__interrupt關鍵字去定義了一個中斷服 務子程序(ISR),請評論一下這段代碼的。 __interrupt double compute_area (double radius) { double area = PI * radius * radius; printf(" Area = %f", area); return area; } 【參考答案】這個函數有太多的錯誤了,以至讓人不知從何說起了: 1). ISR 不能返回一個值。如果你不懂這個,那么你不會被雇用的。 2). ISR 不能傳遞參數。如果你沒有看到這一點,你被雇用的機會等同第 一項。 3). 在許多的處理器/編譯器中,浮點一般都是不可重入的。有些處理器/編 譯器需要讓額處的寄存器入棧,有些處理器/編譯器就是不允許在ISR中做 浮點運算。此外,ISR應該是短而有效率的,在ISR中做浮點運算是不明 智的。 4). 與第三點一脈相承,printf()經常有重入和性能上的問題。如果你丟掉 了第三和第四點,我不會太為難你的。不用說,如果你能得到后兩點,那 么你的被雇用前景越來越光明了。 83、請編寫一個 C 函數,該函數在給定的內存區域搜 索給定的字符,並返回該字符所在位置索引值。 【參考答案】 int search(char *cpSource, int n, char ch) //起始地址,搜索長度,目標字符 { int i; for(i=0; i<n && *(cpSource+i) != ch; ++i); return i; } 91、寫一個內存拷貝函數,不用任何庫函數.就是前些時 候本版討論的那個問題。 【參考答案】 void* memcpy(void* pvTo, const void* pvFrom, size_t size) { assert((pvTo != NULL) && (pvFrom != NULL)); byte* pbTo = pvTo; byte* pbFrom = pbFrom; while (size-- > 0) { *pbTo++ = *pbFrom++; } return pvTo; } 93、取一個整數a從右端開始的4~7位。 【參考答案】 main() { unsigned a,b,c,d; scanf("%o",&a); b=a>>4; c=~(~0<<4); d=b&c; printf("%o\n%o\n",a,d); } c++ 部分:::::::::::::::::::::::; 11、引用與指針有什么區別? 【參考答案】 1) 引用必須被初始化,指針不必。 2) 引用初始化以后不能被改變,指針可以改變所指的 對象。 3) 不存在指向空值的引用,但是存在指向空值的指針 。 14、函數assert的用法? 【參考答案】斷言assert是僅在debug版本起作用的宏 ,用於檢查“不應該“發生的情況。程序員可以把assert 看成一個在任何系統狀態下都可以安全使用的無害測 試手段。 17、有了 malloc/free 為什么還要 new/delete ? 【參考答案】malloc 與 free 是 C++/C 語言的標准庫 函數,new/delete 是 C++的運算符。它們都可用於申 請動態內存和釋放內存。 對於非內部數據類型的對象 而言,光用 maloc/free 無法滿足動態對象的要求。對 象在創建的同時要自動執行構造函數,對象在消亡之 前要自動執行析構函數。由於malloc/free 是庫函數而 不是運算符,不在編譯器控制權限之內,不能夠把執 行構造函數和析構函數的任務強加於 malloc/free。 因 此 C++語言需要一個能完成動態內存分配和初始化工 作的運算符 new,以及一個能完成清理與釋放內存工 作的運算符 delete。注意 new/delete 不是庫函數。 19、C++是不是類型安全的? 【參考答案】不是。兩個不同類型的指針之間可以強制 轉換(用reinterpret cast)。 21、用C++寫個程序,如何判斷一個操作系統是16位 還是32位的? 【標准答案】定義一個指針p,打印出sizeof(p),如果節 后是4,則表示該操作系統是32位,打印結果是2,表 示是16位。 22、 .用C++寫個程序,如何判斷一個操作系統是16位 還是32位的?不能用sizeof()函數。 【參考答案】 int a = ~0; if( a>65536 ) { cout<<"32 bit"<<endl; } else { cout<<"16 bit"<<endl; } 24、多態類中的虛函數表是Compile-Time,還是Run- Time時建立的? 【標准答案】虛擬函數表是在編譯期就建立了,各個虛 擬函數這時被組織成了一個虛擬函數的入口地址的數 組.而對象的隱藏成員--虛擬函數表指針是在運行期--也 就是構造函數被調用時進行初始化的,這是實現多態的 關鍵。 25、錯誤的轉義字符是 () A.'\091' B.'\\' C.'\0' D.'\'‘ 【標准答案】A 28、內存的分配方式有幾種? 【參考答案】一、從靜態存儲區域分配。內存在程序 編譯的時候就已經分配好,這塊內存在程序的整個運 行期間都存在。例如全局變量。二、在棧上創建。在 執行函數時,函數內局部變量的存儲單元都可以在棧 上創建,函數執行結束時這些存儲單元自動被釋放。 棧內存分配運算內置於處理器的指令集中,效率很高 ,但是分配的內存容量有限。 三、從堆上分配,亦稱動態內存分配。程序在運行的 時候用malloc或new申請任意多少的內存,程序員自己 負責在何時用free或delete釋放內存。動態內存的生存 期由我們決定,使用非常靈活,但問題也最多。 29、float a,b,c ,問等式 (a+b)+c==(b+a)+c 和 (a+b)+c==(a+c)+b能否成立? 【參考答案】兩者都不行。在比較float或double時,不 能簡單地比較。由於計算誤差,相等的概率很低。應 判斷兩數之差是否落在區間(-e,e)內。這個e應比浮點 數的精度大一個數量級。 32、In C++, what does "explicit" mean? what does "protected" mean? 【標准答案】c++中的explicit關鍵字用來修飾類的構造 函數,表明該構造函數是顯式的,在某些情況下,我 們要求類的使用者必須顯示調用類的構造函數時就需 要使用explicit,反之默認類型轉換可能會造成無法預期 的問題。protected控制的是一個函數對一個類的成員 (包括成員變量及成員方法)的訪問權限。protected 成員只有該類的成員函數及其派生類的成員函數可以 訪問。 32、In C++, what does "explicit" mean? what does "protected" mean? 【標准答案】c++中的explicit關鍵字用來修飾類的構造 函數,表明該構造函數是顯式的,在某些情況下,我 們要求類的使用者必須顯示調用類的構造函數時就需 要使用explicit,反之默認類型轉換可能會造成無法預期 的問題。protected控制的是一個函數對一個類的成員 (包括成員變量及成員方法)的訪問權限。protected 成員只有該類的成員函數及其派生類的成員函數可以 訪問。 33、重復多次fclose一個打開過一次的FILE *fp指針會 有什么結果,並請解釋。 【參考答案】考察點:導致文件描述符結構中指針指向 的內存被重復釋放,進而導致一些不可預期的異常。 34、為什么數組名作為參數,會改變數組的內容,而 其它類型如int卻不會改變變量的值? 【參考答案】當數組名作為參數時,傳遞的實際上是地 址。而其他類型如int作為參數時,由於函數參數值實 質上是實參的一份拷貝,被調函數內部對形參的改變 並不影響實參的值。 40、重載(overload)、重寫(override,有的書也叫做“ 覆蓋”)、重定義(redefinition)的區別? 【標准答案】 名稱 名字空間 區別 重載 同一名字空間 是指允許存在多個同名函數,而這些函數的參 數表不同。 重定義/隱 藏 不同名字空間 用於繼承,派生類與基類的函數同名,屏蔽基 類的函數 重寫/覆蓋 不同名字空間 用於繼承,子類重新定義復類虛函數的方法 41、多態的作用? 【參考答案】主要是兩個:1. 隱藏實現細節,使得代 碼能夠模塊化;擴展代碼模塊,實現代碼重用;2. 接 口重用:為了類在繼承和派生的時候,保證使用家族 中任一類的實例的某一屬性時的正確調用。 44、 C++里面是不是所有的動作都是main()引起的? 如果不是,請舉例。 【參考答案】比如全局變量的初始化,就不是由main函 數引起的。 47、“new”in c++ is a: A. library function like malloc in c B. key word C. operator D. none of the above 【參考答案】C。malloc是庫函數,不在編譯器控制范 圍之內;new是運算符,在編譯器控制范圍之內。 調用malloc時,從堆中申請內存;調用new時,從堆中 申請內存並為內存調用構造函數。 48、對於C++中類(class) 與結構(struct)的描述正確的為: A,類中的成員默認是private的,當是可以聲明public,private 和protected,結構中定義的成員默認的都是public; B,結構中不允許定義成員函數,當是類中可以定義成員函數; C,結構實例使用malloc() 動態創建,類對象使用new 操作符動 態分配內存; D,結構和類對象都必須使用new 創建; E,結構中不可以定義虛函數,當是類中可以定義虛函數. F,結構不可以存在繼承關系,當是類可以存在繼承關系. 【標准答案】A,D 50、C++程序下列說法正確的有: A,對調用的虛函數和模板類都進行遲后編譯. B,基類與子類中函數如果要構成虛函數,除了要求在基 類中用virtual 聲名,而且必須名字相同且參數類型相同 返回類型相同。 C,重載的類成員函數都必須要:或者返回類型不同,或者 參數數目不同,或者參數序列的類型不同. D,靜態成員函數和內聯函數不能是虛函數,友員函數和 構造函數也不能是虛函數,但是析構函數可以是虛函數. 【標准答案】A 51、在C++中有沒有純虛構造函數? 【標准答案】構造函數不能是虛的。只能有虛的析構 函數。 60、所有的運算符都能重載嗎? 【參考答案】不能被重載的運算符 在 C++運算符集合中,有一些運算符是不允許被重載 的。這種限制是出於安全方面的考慮,可防止錯誤和 混亂。 (1)不能改變 C++內部數據類型(如 int,float 等)的運算符。 (2)不能重載‘.’,因為‘.’在類中對任 何成員都有意義,已經成為標准用法。 (3)不能重 載目前 C++運算符集合中沒有的符號,如#,@,$等。 原因有兩點,一是難以理解,二是難以確定優先級。 (4)對已經存在的運算符進行重載時,不能改變優先級 規則,否則將引起混亂。 61、基類的析構函數不是虛函數,會帶來什么問題? 【參考答案】派生類的析構函數用不上,會造成資源 的泄漏。 76、以下三條輸出語句分別輸出什么? char str1[] = "abc"; char str2[] = "abc"; const char str3[] = "abc"; const char str4[] = "abc"; const char* str5 = "abc"; const char* str6 = "abc"; cout << boolalpha << ( str1==str2 ) << endl; // 輸出什么? cout << boolalpha << ( str3==str4 ) << endl; // 輸出什么? cout << boolalpha << ( str5==str6 ) << endl; // 輸出什么? 【參考答案】分別輸出false,false,true。str1和str2都是字符數組,每個都有其自己 的存儲區,它們的值則是各存儲區首地址,不等;str3和str4同上,只是按const語 義,它們所指向的數據區不能修改。str5和str6並非數組而是字符指針,並不分配 存儲區,其后的“abc”以常量形式存於靜態數據區,而它們自己僅是指向該區首地址 的指針,相等。 77、以下代碼有什么問題? cout << (true?1:"1") << endl; 【參考答案】三元表達式“?:”問號后面的兩個操作數必 須為同一類型。 79、以下代碼中的輸出語句輸出0嗎,為什么? struct CLS { int m_i; CLS( int i ) : m_i(i) {} CLS() { CLS(0); } }; CLS obj; cout << obj.m_i << endl; 【標准答案】不能。在默認構造函數內部再調用帶參的構造函數屬用戶 行為而非編譯器行為,亦即僅執行函數調用,而不會執行其后的初始化 表達式。只有在生成對象時,初始化表達式才會隨相應的構造函數一起 調用。 82、在排序方法中,關鍵碼比較次數與記錄地初始排 列無關的是() A. Shell排序 B. 歸並排序 C. 直接插入排序 D. 選擇排序 【標准答案】D 83、代碼 void func() { static int val; ... } 中,變量val的內存地址位於: A. 已初始化數據段 B.未初始化數據段 C.堆 D.棧 【標准答案】A 85、寫出判斷ABCD四個表達式的是否正確, 若正確, 寫出經過表達式中 a的值。 int a = 4; (A)a += (a++); (B) a += (++a) ; (C)(a++) += a;(D) (++a) += (a++); a = ? 【參考答案】C錯誤,左側不是一個有效變量,不能賦 值,可改為(++a) += a;改后答案依次為9,10,10,11
1.15.1,大小端模式對 union 類型數據的影響 下面再看一個例子: union { int i; char a[2]; }*p, u; p = &u; p->a[0] = 0x39; p->a[1] = 0x38; p.i 的值應該為多少呢? 這里需要考慮存儲模式:大端模式和小端模式。 大端模式(Big_endian):字數據的高字節存儲在低地址中,而字數據的低字節則存放 在高地址中。 小端模式(Little_endian):字數據的高字節存儲在高地址中,而字數據的低字節則存放 在低地址中。 union 型數據所占的空間等於其最大的成員所占的空間。對 union 型的成員的存取都是 相對於該聯合體基地址的偏移量為 0 處開始,也就是聯合體的訪問不論對哪個變量的存取都 是從 union 的首地址位置開始。如此一解釋,上面的問題是否已經有了答案呢?
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。