c 面試題目

2021-06-16 09:20:16 字數 4177 閱讀 3996

摘要:12個c語言面試題,涉及指標、程序、運算、結構體、函式、記憶體,看看你能做出幾個!

1.gets()

函式

問:請找出下面**裡的問題:

#include

int main(void)

答:上面**裡的問題在於函式

gets()

的使用,這個函式從

stdin

接收乙個字串而不檢查它所複製的快取的容積,這可能會導致快取溢位。這裡推薦使用標準函式

fgets()

代替。

2.strcpy()

函式

問:下面是乙個簡單的密碼保護功能,你能在不知道密碼的情況下將其破解嗎?

#include

int main(int argc, char *argv)

if(flag)else

return0; }

答:破解上述加密的關鍵在於利用攻破

strcpy()

函式的漏洞。所以使用者在向

「passwd」

快取輸入隨機密碼的時候並沒有提前檢查

「passwd」

的容量是否足夠。所以,如果使用者輸入乙個足夠造成快取溢位並且重寫

「flag」

變數預設值所存在位置的記憶體的長「密碼

」,即使這個密碼無法通過驗證,

flag

驗證位也變成了非零,也就可以獲得被保護的資料了。例如:

$./psswd aaaaaaaaaaaaa 

passwordcracked

雖然上面的密碼並不正確,但我們仍然可以通過快取溢位繞開密碼安全保護。

要避免這樣的問題,建議使用

strncpy()

函式。

作者注:最近的編譯器會在內部檢測棧溢位的可能,所以這樣往棧裡儲存變數很難出現棧溢位。在我的

gcc裡預設就是這樣,所以我不得不使用編譯命令

『-fno-stack-protector』

來實現上述方案。

3.main()

的返回型別

問:下面的**能

編譯通過嗎?如果能,它有什麼潛在的問題嗎?

#include

voidmain(void)

else

return; }

答:因為

main()

方法的返回型別,這段**的錯誤在大多數編譯器裡會被當作警告。

main()

的返回型別應該是

「int」

而不是「void」

。因為「int」

返回型別會讓程式返回狀態值。這點非常重要,特別當程式是作為依賴於程式成功執行的指令碼的一部分執行時。

4.

記憶體洩露

問:下面的**會導致記憶體洩漏嗎?

#include

void main(void)

else

return; }

答:儘管上面的**並沒有釋放分配給

「ptr」

的記憶體,但並不會在程式退出後導致記憶體洩漏。在程式結束後,所有這個程式分配的記憶體都會自動被處理掉。但如果上面的**處於乙個

「while迴圈」

中,那將會導致嚴重的記憶體洩漏問題!

valgrind

上的文章。

5.free()

函式

問:下面的程式會在使用者輸入

'freeze'

的時候出問題,而

'zebra'

則不會,為什麼?

#include

int main(int argc, char *argv)

elseif(argc == 1)

else

if(*ptr == 'z')

free(ptr); }

return0; }

答:這裡的問題在於,**會(通過增加

「ptr」

)修改while

迴圈裡「ptr」

儲存的位址。當輸入

「zebra」

時,while

迴圈會在執行前被終止,因此傳給

free()

的變數就是傳給

malloc()

的位址。但在

「freeze」

時,「ptr」

儲存的位址會在

while

迴圈裡被修改,因此導致傳給

free()

的位址出錯,也就導致了

seg-fault

或者崩潰。

6.

使用_exit

退出

問:在下面的**中,

atexit()

並沒有被呼叫,為什麼?

#include

void func(void)

int main(void)

這是因為

_exit()

函式的使用,該函式並沒有呼叫

atexit()

等函式清理。如果使用

atexit()

就應當使用

exit()

或者「return」

與之相配合。

7.void*和c

結構體

問:你能設計乙個能接受任何型別的引數並返回

interger

(整數)結果的函式嗎?

答:如下:

intfunc(void*ptr)

如果這個函式的引數超過乙個,那麼這個函式應該由乙個結構體來呼叫,這個結構體可以由需要傳遞引數來填充。

8.*和++

操作

問:下面的操作會輸出什麼?為什麼?

#include

intmain(void)

答:輸出結果應該是這樣:

[l] 

[i] 因為

「++」

和「*」

的優先權一樣,所以

「*ptr++」

相當於「*(ptr++)」

。即應該先執行

ptr++

,然後才是

*ptr

,所以操作結果是

「l」。第二個結果是

「i」。

9.

問:修改**片段(或者唯讀**)

問:下面的**段有錯,你能指出來嗎?

#include

intmain(void)

答:這是因為,通過

*ptr = 『t』

,會改變記憶體中**段(唯讀**)

「linux」

的第乙個字母。這個操作是無效的,因此會造成

seg-fault

或者崩潰。

10.

會改變自己名字的程序

問:你能寫出乙個在執行時改變自己程序名的程式嗎?

答:參見下面這段**:

#include

intmain(intargc, char*argv)

11.

返回本地變數的位址

問:下面**有問題嗎?如果有,該怎麼修改?

#include

int* inc(intval)

intmain(void)

答:儘管上面的程式有時候能夠正常執行,但是在

「inc()」

中存在嚴重的漏洞。這個函式返回本地變數的位址。因為本地變數的生命週期就是

「inc()」

的生命週期,所以在

inc結束後,使用本地變數會發生不好的結果。這可以通過將

main()

中變數「a」

的位址來避免,這樣以後還可以修改這個位址儲存的值。

12.

處理printf()

的引數

問:下面**會輸出什麼?

#include

intmain(void)

答:輸出結果是:

110..40..60

這是因為

c語言裡函式的引數預設是從右往左處理的,輸出時是從左往右。

C 面試題目

1 ispostback正確的是 首次載入頁面的ispostback的值為false 重新整理頁面後的ispostback的值為true 第三個選項忘了 2 頁面傳值的幾種方式 request.querystring session server.transfer 3 什麼是瀏覽器的 無狀態 如何解...

C 面試題目彙總

寫這篇文章的初衷 平時在實驗室用的都是linux系統的ubuntu版本,想儲存一下c 面試相關的題目及答案的時候,沒辦法用office套件記錄,就用寫部落格的方式記錄吧,殊途同歸。文章持續更新中 const比 define好。首先,它能夠明確指定型別,能夠在編譯階段進行型別檢查,而 define只是...

c 面試題目總結

面試常見題目總結 1 ifndef define endif的作用 答 防止標頭檔案重複引用,增加工程編譯時間。2.vector中10個元素依次刪除一半直接用迴圈刪是不是安全的,需要考慮什麼問題 答 vector在刪除元素後返回的迭代器指標已經自加,所以需要自減。否則會出現野指標。3.c 程式在執行...