|
1.關(guān)鍵字 static 的作用是什么?
在 C 語(yǔ)言中,關(guān)鍵字 static有三個(gè)明顯的作用:
解析:
a. 在函數(shù)體,一個(gè)被聲明為靜態(tài)的變量在這一函數(shù)被調(diào)用過(guò)程中維持其值不變。
b. 在模塊內(nèi)(但在函數(shù)體外),一個(gè)被聲明為靜態(tài)的變量可以被模塊內(nèi)所用函數(shù)訪問(wèn),但不能被模塊外其它
函數(shù)訪問(wèn)。它是一個(gè)本地的全局變量。
c. 在模塊內(nèi),一個(gè)被聲明為靜態(tài)的函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用。那就是,這個(gè)函數(shù)被限制在聲
明它的模塊的本地范圍內(nèi)使用。
2.引用和指針的區(qū)別是什么?
解析:
a. 引用必須被初始化,指針不必。
b. 引用初始化以后不能被改變,指針可以改變所指的對(duì)象。
c. 不存在指向空值的引用,但是存在指向空值的指針。
3..h 頭文件中的 ifndef/define/endif 的作用:
解析:
防止該頭文件被重復(fù)引用
4.#include 與 #include "file.h"的區(qū)別?
解析:
前者是從 Standard Library 的路徑尋找和引用 file.h,而后者是從當(dāng)前工作路徑搜尋并引用 file.h
5.全局變量與局部變量在內(nèi)存中的區(qū)別?
解析:
全局變量?jī)?chǔ)存在靜態(tài)數(shù)據(jù)區(qū),局部變量在堆棧中
6.堆棧溢出一般有什么原因能導(dǎo)致?
解析:
a.沒有回收垃圾資源
b.層次太深的遞歸調(diào)用
7.不能申明為虛函數(shù)的函數(shù)?
解析:
constructor
8.隊(duì)列與棧的區(qū)別?
解析:
隊(duì)列先進(jìn)先出,棧后進(jìn)先出
9.不能做switch()的參數(shù)類型
解析:
Switch的參數(shù)不能為實(shí)型
10.局部變量和全局變量能否重名?
解析:
能,局部會(huì)屏蔽全局。要用全局變量,需要使用"::"
局部變量可以與全局變量同名,在函數(shù)內(nèi)引用這個(gè)變量時(shí),會(huì)用到同名的局部變量,而不會(huì)用到全局變量。
11.如何引用一個(gè)已經(jīng)定義過(guò)的全局變量?
解析:
可以用引用頭文件的方式,也可以用 extern 關(guān)鍵字
如果用引用頭文件方式來(lái)引用某個(gè)在頭文件中聲明的全局變量,假定你將那個(gè)變量寫錯(cuò)了,那么在編譯期間會(huì)報(bào)錯(cuò)
如果你用 extern 方式引用時(shí),假定你犯了同樣的錯(cuò)誤,那么在編譯期間不會(huì)報(bào)錯(cuò),而在連接期間報(bào)錯(cuò)。
12.語(yǔ)句 for( ;1 ;)有什么問(wèn)題?它是什么意思?
解析:
和 while(1)相同,無(wú)限循環(huán)
13.程序的內(nèi)存分配?
解析:
一個(gè)由 c/C++編譯的程序占用的內(nèi)存分為以下幾個(gè)部分:
a.棧區(qū)(stack)—由編譯器自動(dòng)分配釋放,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)
結(jié)構(gòu)中的棧
b.堆區(qū)(heap)—一般由程序員分配釋放,若程序員不釋放,程序結(jié)束時(shí)可能由 OS回收。注意它與數(shù)據(jù)結(jié)
構(gòu)中的堆是兩回事,分配方式倒是類似于鏈表,呵呵
c.全局區(qū)(靜態(tài)區(qū))(static)—全局變量和靜態(tài)變量的存儲(chǔ)是放在一塊的,初始化的全局變量和靜態(tài)變量
在一塊區(qū)域,未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域。程序結(jié)束后由系統(tǒng)釋放.
d.文字常量區(qū)—常量字符串就是放在這里的。程序結(jié)束后由系統(tǒng)釋放
e.程序代碼區(qū)—存放函數(shù)體的二進(jìn)制代碼
例子程序
這是一個(gè)前輩寫的,非常詳細(xì)
//main.cpp
int a=0; //全局初始化區(qū)
char *p1; //全局未初始化區(qū)
main()
{
intb;棧
char s[]="abc"; //棧
char*p2; //棧
char *p3="123456"; //123456\0在常量區(qū),p3 在棧上。
static int c=0; //全局(靜態(tài))初始化區(qū)
p1 = (char*)malloc(10);
p2 = (char*)malloc(20); //分配得來(lái)得10 和 20 字節(jié)的區(qū)域就在堆區(qū)。
strcpy(p1,"123456"); //123456\0放在常量區(qū),編譯器可能會(huì)將它與 p3 所向"123456"優(yōu)化成一
個(gè)地方。
}
14.三種基本的數(shù)據(jù)模型?
解析:
按照數(shù)據(jù)結(jié)構(gòu)類型的不同,將數(shù)據(jù)模型劃分為層次模型、網(wǎng)狀模型和關(guān)系模型
15.結(jié)構(gòu)和聯(lián)合有什么區(qū)別?
解析:
a. 結(jié)構(gòu)和聯(lián)合都是由多個(gè)不同的數(shù)據(jù)類型成員組成, 但在任何同一時(shí)刻,
聯(lián)合中只存放了一個(gè)被選中的成員(所有成員共用一塊地址空間),
而結(jié)構(gòu)的所有成員都存在(不同成員的存放地址不同)。
b. 對(duì)于聯(lián)合的不同成員賦值, 將會(huì)對(duì)其它成員重寫, 原來(lái)成員的值就不存在了, 而對(duì)于結(jié)構(gòu)的不同成員賦值是互不影響的
16.描述內(nèi)存分配方式以及它們的區(qū)別?
解析:
a.從靜態(tài)存儲(chǔ)區(qū)域分配。內(nèi)存在程序編譯的時(shí)候就已經(jīng)分配好,這塊內(nèi)存在程序的整個(gè)運(yùn)行期間都存在。例如全局變量,static變量。
b.在棧上創(chuàng)建。在執(zhí)行函數(shù)時(shí),函數(shù)內(nèi)局部變量的存儲(chǔ)單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時(shí)這些存儲(chǔ)單元自動(dòng)被釋放。棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集。
c.從堆上分配,亦稱動(dòng)態(tài)內(nèi)存分配。程序在運(yùn)行的時(shí)候用 malloc 或 new 申請(qǐng)任意多少的內(nèi)存,程序員自己負(fù)責(zé)在何時(shí)用 free或 delete 釋放內(nèi)存。動(dòng)態(tài)內(nèi)存的生存期由程序員決定,使用非常靈活,但問(wèn)題也最多
17.請(qǐng)說(shuō)出 const 與#define 相比,有何優(yōu)點(diǎn)?
解析:
Const 作用:定義常量、修飾函數(shù)參數(shù)、修飾函數(shù)返回值三個(gè)作用。被 Const修飾的東西都受到強(qiáng)制保護(hù),可以預(yù)防意外的變動(dòng),能提高程序的健壯性
a.const常量有數(shù)據(jù)類型,而宏常量沒有數(shù)據(jù)類型。編譯器可以對(duì)前者進(jìn)行類型安全檢查。而對(duì)后者只進(jìn)行字符替換,沒有類型安全檢查,并且在字符替換可能會(huì)產(chǎn)生意料不到的錯(cuò)誤。
b. 有些集成化的調(diào)試工具可以對(duì) const 常量進(jìn)行調(diào)試,但是不能對(duì)宏常量進(jìn)行調(diào)試
18.分別寫出 BOOL,int,float,指針類型的變量 a 與“零”的比較語(yǔ)句?
解析:
BOOL : if (!a ) or if(a)
int: if ( a == 0)
float : const EXPRESSION EXP =0.000001
if ( a < EXP && a >-EXP)
pointer : if ( a != NULL) or if(a == NULL)
19.如何判斷一段程序是由C編譯程序還是C++編譯程序編譯的?
解析:
#ifdef __cplusplus
cout<<"c++";
#else
cout<<"c";
#endif
20.論述含參數(shù)的宏與函數(shù)的優(yōu)缺點(diǎn)?
解析: 帶參宏 函數(shù)
處理時(shí)間 編譯時(shí) 程序運(yùn)行時(shí)
參數(shù)類型 沒有參數(shù)類型問(wèn)題 定義實(shí)參、形參類型
處理過(guò)程 不分配內(nèi)存 分配內(nèi)存
程序長(zhǎng)度 變長(zhǎng) 不變
運(yùn)行速度 不占運(yùn)行時(shí)間 調(diào)用和返回占用時(shí)間
21.用兩個(gè)棧實(shí)現(xiàn)一個(gè)隊(duì)列的功能?要求給出算法和思路?
解析:
設(shè) 2 個(gè)棧為 A,B, 一開始均為空.
入隊(duì):
將新元素 push 入棧 A;
出隊(duì):
(1)判斷棧 B 是否為空;
(2)如果不為空,則將棧 A 中所有元素依次 pop 出并 push 到棧 B;
(3)將棧 B 的棧頂元素 pop 出;
這樣實(shí)現(xiàn)的隊(duì)列入隊(duì)和出隊(duì)的平攤復(fù)雜度都還是 O(1), 比上面的幾種方法要好
22.中斷(Interrupts)
解析:
中斷是嵌入式系統(tǒng)中重要的組成部分,這導(dǎo)致了很多編譯開發(fā)商提供一種擴(kuò)展—讓標(biāo)準(zhǔn) C 支持中斷。具代表事實(shí)是,產(chǎn)生了一個(gè)新的關(guān)鍵字__interrupt。下面的代碼就使用了__interrupt關(guān)鍵字去定義了一個(gè)中斷服務(wù)子程序(ISR),請(qǐng)?jiān)u論一下這段代碼的。
__interrupt double compute_area (double radius)
{
double area = PI * radius * radius;
printf("\nArea = %f", area);
return area;
}
這個(gè)函數(shù)有太多的錯(cuò)誤了,以至讓人不知從何說(shuō)起了:
1)ISR 不能返回一個(gè)值。如果你不懂這個(gè),那么你不會(huì)被雇用的。
2) ISR 不能傳遞參數(shù)。如果你沒有看到這一點(diǎn),你被雇用的機(jī)會(huì)等同第一項(xiàng)。
3) 在許多的處理器/編譯器中,浮點(diǎn)一般都是不可重入的。有些處理器/編譯器需要讓額處的寄存器入棧,有些處理器/編譯器就是不允許在ISR 中做浮點(diǎn)運(yùn)算。此外,ISR 應(yīng)該是短而有效率的,在 ISR 中做浮點(diǎn)運(yùn)算是不明智的。
4)與第三點(diǎn)一脈相承,printf()經(jīng)常有重入和性能上的問(wèn)題。如果你丟掉了第三和第四點(diǎn),我不會(huì)太為難你的。不用說(shuō),如果你能得到后兩點(diǎn),那么你的被雇用前景越來(lái)越光明了
23.寫一個(gè)“標(biāo)準(zhǔn)”宏
解析:
輸入兩個(gè)參數(shù),輸出較小的一個(gè):#define MIN(A,B) ((A) < (B))? (A) : (B))
表明 1 年中有多少秒(忽略閏年問(wèn)題):#define SECONDS_PER_YEAR (60 * 60 * 24 *365)UL
以下是加括號(hào)和不加括號(hào)的區(qū)別:
#define DOUBLE(x) x+x 與 #defineDOUBLE(x) ((x)+(x))
i = 5*DOUBLE(5); i 為 30 i = 5*DOUBLE(5); i 為50
24. A.c 和 B.c 兩個(gè) c 文件中使用了兩個(gè)相同名字的 static變量,編譯的時(shí)候會(huì)不會(huì)有問(wèn)題?這兩個(gè) static變量會(huì)保存到哪里(棧還是堆或者其他的)?
解析:
static 的全局變量,表明這個(gè)變量?jī)H在本模塊中有意義,不會(huì)影響其他模塊。
他們都放在數(shù)據(jù)區(qū),但是編譯器對(duì)他們的命名是不同的。
如果要使變量在其他模塊也有意義的話,需要使用 extern 關(guān)鍵字
|
|