1. 找錯
#define MAX_SRM 256
DSN get_SRM_no()
{
static int SRM_no;
int I;
for(I=0;I<MAX_SRM;I++,SRM_no++)
{
SRM_no %= MAX_SRM;
if(MY_SRM.state==IDLE)
{
break;
}
}
if(I>=MAX_SRM)
return (NULL_SRM);
else
return SRM_no;
}
答:
(1). SRM_no沒有賦初值
(2). 由於static的聲明,使該函數成爲不可重入(即不可預測結果)函數,因爲SRM_no變量放在程序的全局存儲區中,每次調用的時候還可以保持原來的賦值。這裏應該去掉static聲明。
2. 寫出程序運行結果
int sum(int a)
{
auto int c=0;
static int b=3;
c+=1;
b+=2;
return(a+b+C);
}
void main()
{
int I;
int a=2;
for(I=0;I<5;I++)
{
printf("%d,", sum(a));
}
}
答:8,10,12,14,16
該題比較簡單。只要注意b聲明爲static靜態全局變量,其值在下次調用時是可以保持住原來的賦值的就可以。
3.
int func(int a)
{
int b;
switch(a)
{
case 1: b=30;
case 2: b=20;
case 3: b=16;
default: b=0;
}
return b;
}
則func(1)=?
答:func(1)=0,因爲沒有break語句,switch中會一直計算到b=0。
4.
int a[3];
a[0]=0; a[1]=1; a[2]=2;
int *p, *q;
p=a;
q=&a[2];
則a[q-p]=?
答:a[q-p]=a[2]=2;這題是要告訴我們指針的運算特點
5. 定義 int **a[3][4], 則變量佔有的內存空間爲:_____
答:此處定義的是指向指針的指針數組,對於32位系統,指針佔內存空間4字節,因此總空間爲3×4×4=48。
6. CObject類中的析構函數爲什麼是虛函數
面試SE時,很多公司喜歡問到虛函數相關。MFC類庫中,CObject類的重要性不言自明的。在CObject的定義中,我們看到一個有趣的現象,即CObject的析構函數是虛擬的。
在AFX.H中,CObject的定義:
class CObject
{
public:
// Object model (types, destruction, allocation)
virtual CRuntimeClass* GetRuntimeClass() const;
virtual ~CObject(); //virtual destructors are necessary
};
爲什麼MFC的編寫者認爲virtual destructors are necessary (虛擬的析構函數是必要的)?
在著名的VC教程 "精通Visual C++ for Windows 95/NT"(電子工業版, 1997年5月版,胡儉,丘宗明等著)第99頁中有這樣一段話:
“如果CObject的析構函數不是虛擬的,派生類就不會自動地得到虛擬的 析構函數,當對象撤消時就會帶來問題——只有當前類的析構函數得到調用而基類的析構函數就得不到調用...”
我認爲這段解釋是這本很不錯的書中一個不應出現的嚴重錯誤。其意思是說:
若:
class CBase
{
public:
~CBase() { };
};
class CChild : public CBase
{
public:
~CChild() { };
};
main()
{
Child c;
return 0;
}
上段代碼在運行時,當棧框中的自動對象 c 被撤消時,只調用~CChild(), 而不調用~CBase()。
我想但凡對C++繼承性理論有所瞭解的人都會立刻指出這是錯誤的。
由於在生成CChild對象c時,實際上在調用CChild類的構造函數之前必須首先 調用其基類CBase的構造函數,所以當撤消c時,也會在調用CChild類析構函數之後,調用CBase類的析構函數(析構函數調用順序與構造函數相反)。也就是說,無論析構函數是不是虛函數,派生類對象被撤消時,肯定會依次上調其基類的析構函數。
那麼爲什麼CObject類要搞一個虛的析構函數呢?
仍以上面代碼爲例,如果main()中有如下代碼:
...
CBase * pBase;
CChild c;
pBase = &c;
...
那麼在、當pBase指針被撤消時,調用的是CBase的析構函數還是CChild的呢? 顯然是CBase的(靜態聯編)。但如果把CBase類的析構函數改成virtual型,當 pBase指針被撤消時,就會先調用CChild類構造函數,再調用CBase類構造函數。
在這個例子裏,所有對象都存在於棧框中,當離開其所處的作用域時,該對象 會被自動撤消,似乎看不出什麼大問題。但是試想,如果CChild類的的構造函數在堆中分配了內存,而其析構函數又不是virtual型的,那麼撤消pBase時,將不會 調用CChild::~CChild(), 從而不會釋放CChild::CChild()佔據的內存,造成內存泄露。
而將CObject的析構函數設爲virtual型,則所有CObject類的派生類的析構函數都將 自動變爲virtual型,這保證了在任何情況下,不會出現由於析構函數未被調用而導致 的內存泄露。這纔是MFC將CObject::~CObject()設爲virtual型的真正原因。
注意:析構函數可以爲virtual型,構造函數則不能。
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/ssfp8762/archive/2009/05/08/4162063.aspx