在程式語言之中,C++一直是我最熟悉的語言之一,也由於之前在五專時代曾經寫過物件導向SCSI驅動程式的經驗,讓我的C的程式語言能力有一定的水準。不過自從上了大學之後,就一路忙著學習著Linux的架設與網頁程式(PHP,ASP,ZOPE...等)其實C++已經忘記的差不多。所以最近去幾家公司面試的時候也著實讓我吃盡了苦頭。
由於我之前去許多家公司面試軟體研發工程師(RD)的職位,也由於我本身喜歡挑戰新的領域與事物,於是我在面試的時候,全部避開之前熟悉網站程式設計或是Linux的架設部分,而盡量選擇系統軟體程式設計師或是LINUX的程式設計師。所以去每家公司自然而然要考一些基本的C++基礎與一些程式設計的概念。或許大家看到這邊,會覺得很簡單,C++不就是基本的程式概念,有哪一些需要學習呢?但是自從我去幾家軟體公司面試以來,有一些題目還真是有點刁鑽與難懂,明明是很簡單的概念,卻往往容易疏忽而犯錯。以下就將幾題我之前去面試的題目提供出來,你又能答對幾題呢?
|
1. #include <iostream.h> |
| Q: What is the output? i=?? j=?? |
|
2. #include <iostream.h> |
| Q: What is the output? |
|
3.
Static i; |
| Q: What is difference between i,j?? and what is difference between Static and Global?? |
|
4. string s1("test1"); |
| Q: What is the output aboute between Label1 and Label2? |
解答1:
第一題的答案是 i=3 j=5,並不會執行 j=6 這個給定值,由於C++是左手邊優先(Left hand side),所以當OR( || )給值出現的時候,所出現的就是第一個成立就不再往下看。所以並不會執行到 j=6 自然而然 j=5
解答2:
針對這一題,可真是難倒我了,答案就是
在類別的建構者函數與解構者函數之中,會呼叫到建構者函數就是當物件成立的時候,所以當 C1 c; 的時候就會呼叫 C1 的建構者函數。但是 在建立類別指標的時候(物件指標)並不會呼叫建構者函數與解構者函數,反倒是在指向位址時所使用的 C2( ) 所代表的就是將『類別當成靜態函數來使用』這樣一來可以讓指標去指定該物件,但是由於是當成函數使用所以 C2的建構者函數與解構者函數都會一併執行。而在Scope方面,由於 Static 的Scope 是最大的,所以相對的解構者函數也會比較慢出現~~~
解答3:
在Scope方面,大家都知道 Static 與 Global的用法,就是比起一般區域變數的Scope都還大,但是這兩個到底有什麼差距呢?原來,比起來Global比Static 更廣大的Scope,也就是 Static 代表該變數的 Scope範圍到『整個檔案』,但是 Global卻是橫跨數個檔案,皆可以呼叫Global的參數(只要使用 extern來呼叫即可~~~)所以大家都會忘記,其實 Global的範圍才最大,但是記得使用外部檔案的變數還是要宣告一下。
解答4:
這一題只要是在考『指標』(pointer)與『物件化身』(reference)兩者的差別,根據去查書『More Effective C++』裡面有提到,其實兩者用法很像,確有以下的不同
所以以上的題目中 rs =s2 是將 s1中的值改為 s2的數值,而 ps=&s2 則是將指標 ps 指向 s2而已罷了~~~
大家對幾題阿?有題目的話歡迎來分享~~~
Static 變數的scope 會比在main 中auto變數久
所以會先跑 main 中的 C1 a;的 解構函數
再跑 static C2 aa;的解構函數
妳們沒有人實際跑跑看嗎
第二個題目程式不能跑
要改成下面那樣 而v->i = 111 也會顯示出來
int main(int argc, char* argv[])
{
int x=0;
C1 c;
C2 * v=NULL;
cout i =111;
cout i<<endl;
}
用VC++的結果
將第二題的函示改為以下還是可以跑
void fun1( )
{
static C2 aa;
C1( );
cout <<"test_function--------"<<endl;
}
只是把回傳值限定不傳罷了
我是用VC++ 本來fun1 我就是用void的
死在 中的 *v=c2(); 而且 C2 * v=NULL; 要做初始化比較好 我的不做初始化會有warrning
原本的
void main()
{
int x=0;
C1 c;
C2 * v ; //有warnning
cout i =111;
cout i<<endl;
//Sleep(100);
}
由 阿仁 發表於 May 18, 2004 04:57 PM怎麼會沒給值呢
指標的運用上,基本上 *v=C2() 與 v=&C2()
因為*v=C2() 代表 指標v 指向一個利用類別作為靜態變數之用的物件
v=&C2() 代表說 v裡面存放著 C2的位址
不一樣嗎?
由 Evan 發表於 May 19, 2004 03:59 PMBCB5 --> 可以執行
VC++ 6.0-->改為 void 後可以執行
不過我還是會去詢問其他人或老師,看看這兩個之間的差異,
感謝您的指教 :)
我懂其中的差異了
只是很怪的 我利用 BCB在COMMAND MODE下利用SGI 的 STL來編譯這段程式
卻是成功的
差異如下:
基本上
int x=10;
int *v;
*v=x;
此時由於 v尚未給值, 所以 *v 給定x時,會發生不可預知的錯誤
所以一開始在初始化指標的時候,都應該給定一個位置
v=&x 才能將位址給v
而 *v 才能找到 x
而不是不可預知的位置
謝謝 阿仁
由 Evan 發表於 May 19, 2004 06:19 PM後來仔細觀察記憶體,發現
原來在BCB,STL之中
所配置出的記憶體,較不會因為給值*v=x的動作而發生錯誤
但是基本上
*v=x與 v=&x 是完全不同的
咳咳...
個人覺得, 你們可以再回去看看 data structure 的書...
語法簡單, 精神難學啊...
你們對一些 C 和 data structure 的基本架構完全不清楚...:p (原諒我這麼直接)
int x=10;
int *v;
*v=x;
x, &x, v, *v, &v 這幾個的意義清楚嗎?
compile 後,
x 會有一個 int 大小的記憶體, 內容是 10, &x 是 x 的記憶體位址 (address)
v 是一個 pointer, 要指向一個 int 大小的記憶體位址,
&v 是 v 的記憶體位址, *v 是 v 所指向的那個記憶體位址的內容, int *v 後, 系統只給 v 一個 pointer 大小的記憶體, v 所指向的位址並沒有給..., 你沒有指定 v 指向某塊記憶體, 卻要更改這個 "某塊記憶體內容", int *v 讓 v = 一個未知的記憶體位址 (也許是系統 address 0x0000??), 也就是 v 指到一個未知的記憶體, 而你用 *v = x, 要強迫更改這個未知記憶體的內容, 你要把 address 0x0000?? 的內容變成 10, 當然是錯誤!!! 因為 address 0x0000?? 的位置並不是你的程式可以存取的地方....
而 v = &x, 是指定 v 的內容為 x 的 address, 也就是 v 指向 x 這個己經被系統配置的記憶體位置, 它是真實被 x 宣告可使用的, *v = 5 這時所更改的, 也就是 x 的內容...
你們會的是語法, 不是系統....data structure 不管用什麼程式語言都是一樣的...
由 Dave 發表於 May 22, 2004 01:55 AM一句老話
想不到一個錯字,引來那麼多迴響
以後是否該多錯一點 >__________<
感謝 Dave :
其實我不是不知道,只是我很久沒有寫程式了
腦袋整個都是空空的,不過還是謝謝你指教 :)
阿仁兄:
依然感恩阿.... 我知道是題目有錯
最近在寫一些其他方面的備忘錄( CGI,Process & thread)
到時候在跟兩位好好請教 :p
亂連連過來
不過 看到第二題好像有點怪怪的
不論是*v=C2();或v=&C2();應該都不行
前者原因已經有人指出
可是後者...
產生出const temp obj
她的生命週期應該只存在於v=&C2();
即下下行當我們用
v->i=111;
就會存取到不存在的物件
接下來應該就是undefine了
我也是被google大神帶來的路人
正好在看這些令人頭昏的pointer、reference...
板主是個用功的人!!寫了很多好文章
有關樓上的說:
"她的生命週期應該只存在於v=&C2();"這句應該是沒錯
我作了一點實驗加了一行讓它變成以下這樣:
...
fun1( );
cout ii =111;
cout ii
但是我想v還是存在的、也可以說並非undefine
或是說v只是內容被清了
所以在下一行給值的時候v->i=111還是合法的...
有錯誤請再指教了!!