乙個C筆試題引出一系列的問題

2021-06-23 09:48:39 字數 2305 閱讀 1671

下段**的輸出是什麼?(這是我做過的乙個c筆試題目,當時213了,沒有給出完全正確的答案

int main(void) ;

int *p = a;

*(p++) += 123;   /* 其實沒必要把p++擴起來,*和++在同一優先順序,從右到左的結合順序 */

printf("%d, %d\n", *p, *(++p));

return 0;}

輸出是:8,8

來解釋一下為什麼是這個結果,主要注意兩個地方:

1、*(p++) += 123;在這個題目裡,這行**其實是忽悠你的,簡化就是p++;

2、第二點就需要注意函式引數的傳遞,函式引數傳遞是通過棧來實現(大部分是通過棧,還有些是通過暫存器),棧的操作方式是filo,傳遞引數的時候是第n個引數先入棧,然後是第n-1個,然後.....第1個。為什麼不按引數列表的順序來入棧呢?下面是《c和指標》上的解釋:

雖然像printf("%d, %d\n", *p, *(++p));這樣的**,平常是會被鄙視的,不提倡這樣的**風格和寫法,但是作為筆試題還是挺考驗基本功的。

到這裡這個題目算是做完了,但是我來深入分析一下:

1、*(p++) += 123;這行**產生了什麼樣的影響?

a[0] 的值變為129;

p指標向後移動乙個單位。

++i和i++有什麼區別,++i在i儲存的值上增加一併向使用它的表示式"返回"新的(增加後的值);而i++對i增加一,但返回原來的是未增加的值。國內的很多書上都沒把這點說清楚 - -|。所以我們這個地方p++只會對下乙個語句產生影響。

2、 a += b 是否和a = a+b等效?

大部分情況下是等效的,但是也有特例。就是我們下面的情況:

*(p++) += 123;

不等效於

*(p++) = *(p++) + 123;

如果講第一行**替換為第二行,輸出結果為 9,9。

3、函式引數入棧順序是不是真的與按照引數列表順序相反呢?口說無憑,來看下實驗

下面是編寫的一段測試**:

[cpp]view plain

copy

intfoo(

inti, 

intj, 

intk)  

intmain(

void

)    

然後編譯成彙編檔案(指令:gcc -c -g -wa,-adlhn source.c > source.s),我只擷取重要的部分:

[cpp]view plain

copy

9:source.c      ****         

inta = 1, b = 2, c = 3;  

50                            .loc 1 9 0  

51 0017 c745fc01              movl    $1, -4(%ebp)  

51      000000  

52 001e c745f802              movl    $2, -8(%ebp)  

52      000000  

53 0025 c745f403              movl    $3, -12(%ebp)  

53      000000  

10:source.c      ****         foo(a, b, c);  

54                            .loc 1 10 0  

55 002c 8b45f4                movl    -12(%ebp), %eax  

56 002f 89442408              movl    %eax, 8(%esp)    /* 把引數c壓入到[esp+8] */

57 0033 8b45f8                movl    -8(%ebp), %eax  

58 0036 89442404              movl    %eax, 4(%esp)    /* 把引數b壓入到[esp+4] */

59 003a 8b45fc                movl    -4(%ebp), %eax  

60 003d 890424                movl    %eax, (%esp)     /* 把引數a壓入到[esp],也就是棧頂 */

61 0040 e8fcffff              call    foo  

這裡的棧是向低位址增長,esp是棧頂指標。對x86的彙編不熟,就暫時分析道這裡。

從閉包引出來的一系列問題

for var i 0 i 5 i 1000 console.log new date,i 很明顯,由於非同步的作用。到最後輸出的結果為6個5 如果用箭頭表示前後兩次輸出有1s的間隔,用,代表前後一起輸出,那麼輸出結果是5 5,5,5,5,5 這個也很容易的就可以進行解釋,先執行console.lo...

關於c 繼承的一系列問題總結

物件導向設計的重要目的之一就是 重用,而繼承和多型是物件導向的兩個最主要的特徵。本文將主要圍繞c 中的繼承展開討論,並以一些簡單的例子來說明。一.首先觀察在繼承中,成員物件的初始化。1.建立派生類物件時,程式首先建立基類物件,這意味著基類物件應當在程式進入派生類建構函式前被建立。2.派生類建構函式應...

C 做乙個鍊錶,輸出一系列字串

突然手癢想寫個表達字串的鍊錶,通常都是傻傻的輸出數字,id什麼的。想輸出一系列數字,如 wo ai wo de zhu guo wo ai de ren bu ai wo 但是又嫌扣細節麻煩,故當了乙個表,c 鍊錶樣例參考源 自己改為實現形式 為了學習鍊錶,而又沒時間扣很長的構建class,copy...