摘要: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 程式在執行...