題目:程式執行結束應該列印什麼呢?
#include #include int main(int argc,char **ar**)解析:
術語:記憶體越界、溢位、棧空間、棧記憶體分配排序
關鍵點:
原因:記憶體越界、溢位;本質:棧空間、棧記憶體分配排序
具體**詳細步驟分析:
這一題目根據對c語言的理解不同,結果也不同,先來看一下64位linux正確的結果(cpu架構或os不一樣可能導致結果會有差異)
str1 = qrst, str2 = abcdefghijklmnopqrst這個結果可能會比較疑惑,將str2 copy到str1, 為何str1會受到影響呢,作如下測試
#include #include int main(int argc,char **ar**)可以將位址列印出來,就便於理解了,看下執行結果
str1 = qrst, str2 = abcdefghijklmnopqrst1、通過記憶體位址,會發現,str1在記憶體中的位置,是在str2之後的,str1 = 0x7ffcbc675fa0, str2 = 0x7ffcbc675f90
2、從str2 = "123"可以知道str2只有4個位元組,包括'\0',
3、當通過strcpy把str2拷貝到str1時,str1是無法容納的,因為會向位址大的方向溢位,但在列印時,遇到'\0'才會結束,所以通過printf列印str2時會發現結果是正常的,其實後面的已經溢位了,而溢位的空間已經不是str2的自有空間了,那str1為什麼會變呢, 0x90 + 0x10 = 0xa0, 就是str1和str2中間有16個位元組的區間,這個是和系統編譯器相關,經過strcpy後,記憶體中的情況如下:
str1(0x90)
str2(0xa0)
abcdefghijklmnop
qrst\0
4、解決方法,使用strncpy,可以**gets和fgets在日常編制中的注意點,這裡有乙個重要思想,庫給提供的介面,使用者需要確保使用介面的前提條件(這題的前提條件就是strcpy的第乙個引數的長度夠用),這應該成為程式設計者的基本素養。
5、這題也深刻體會到:c語言是把刀,程式設計師是用刀的人。
得分點:
1、原因(佔30分)
記憶體越界、溢位基本抓住考官的心
2、本質+解決方法
考官一般基於這個問題再深入問下去,考官希望通過乙個小點,來看應聘者對以下內容的理解:
棧空間、棧記憶體分配排序+strncpy(又加70分)
3、拓展:
a、有可能聊的開心的話會把c語言的執行時的記憶體結構(堆疊分配)給聊出來
b、c語言中的資料結構中堆疊結構
c、可以聊到函式棧為了加速使用cpu中的暫存器
d、可以聊到嵌入式為了不讓cpu內部暫存器加速,引入關鍵字volatile來操作io(能聊到這裡基本上可以直接談工資了)
tips:
有同學說,面試的時候會尬聊,在筆者看來,是否尬,就看應聘者的c語言知識面,在技術的基礎上,乙個看似平常的小bug,在面試的時候只向考官解決bug,那就沒啥好聊的,解完bug後,再講講本質,再拓展拓展,再聊聊自己對語言的整體認知。就本題夠開心聊半小時。
年輕人第一道C語言面試題
題目 請問以下例1和例2的str有什麼區別?例1 include int main int argc,char ar printf s n str 例2 include int main int argc,char ar 解析 術語 例1字串陣列,例2字串指標 關鍵點 例1 例2的str和hello...
C語言面試題 函式(二)
c語言面試題 函式 二 c語言中,跟函式相關的考題,偶爾還會出現與變長引數相關的問題。在c語言程式設計中有時會遇到一些引數個數可變的函式,如 printf scanf 函式,檢視man手冊時其函式原型為 int printf const char format,int scanf const cha...
C語言面試題
基礎篇 1 區域性變數能否和全域性變數重名?可以2 如何引用乙個已經定義過的全域性變數?直接呼叫並初始化 3 全域性變數可不可以定義在可被多個.c檔案包含的標頭檔案中?為什麼?可以,6 堆和棧有什麼區別?7 什麼是預編譯,何時需要預編譯 8 c和c 中的struct有什麼不同?9 memset me...