在網上看到了一篇嵌入式的面試題,忽然覺得自己很渺小……在未來一段時間內我會陸續貼上我的答案,當然可能有些我做不出來,做出來的也不一定準確,在核對總和提高自己的同時,希望有走過路過高人指點一二。

下面的題目必須全部答對才給分:
1
如何在C中初始化一個字元陣列。
2
如何在C中為一個陣列分配空間。
3
如何初始化一個指標陣列。
4
、如何定義一個有10個元素的整數型指標陣列。
5
s[10]的另外一種表達方式是什麼。
6
GCC3.2.2版本中支援哪幾種編程語言。
7
要使用CHAR_BIT需要包含哪個頭檔。
8
(-1.2345)取整是多少?
9
如何讓局部變數具有全局生命期。
10
C中的常量字串應在何時定義?
11
、如何在兩個.c檔中引用對方的變數。
12
、使用malloc之前需要做什麼準備工作。
13
realloc函數在使用上要注意什麼問題。
14
strtok函數在使用上要注意什麼問題。
15
gets函數在使用上要注意什麼問題。
16
C語言的詞法分析在長度規則方面採用的是什麼策略?
17
a+++++b所表示的是什麼意思?有什麼問題?
18
、如何定義Bool變數的TRUEFALSE的值。
19
C語言的const的含義是什麼。在定義常量時,為什麼推薦使用const,而不是#define
20
C語言的volatile的含義是什麼。使用時會對編譯器有什麼暗示。

這部分是ANSI C的一些問題,題目的前提是必須都答對,看似很變態,但是細想一下,這些都是最基礎的,雖然我們在使用他們的時候會犯這樣那樣的錯誤,但是最終目的是不犯錯誤,不是麼,那麼好,從最基礎的開始。



1
如何在C中初始化一個字元陣列。
個問題看似很簡單,但是我們要將最簡單的問題用最嚴謹的態度來對待。關鍵的地方:初始化、字元型、陣列。最簡單的方法是char array[];。這個問題看似解決了,但是在初始化上好像還欠缺點什麼,個人認為:char array[5]={'1','2','3','4','5'};或者char array[5]={"12345"};或者char array[2][10]={"China","Beijing"};也許更符合初始化的意思。



2
如何在C中為一個陣列分配空間。
最簡單的方法是:char array[5];意思是分配給陣列array一個5個位元組的空間。但是我們要知道在C中陣列其實就是一個名字,其實質含義就是指標,比如char array[];是到底分配的多少空間?所以我們要將其分成為兩種不同的形式給出答案:
一種是棧的形式:char array[5]
一種是堆的形式:char *array; array=(char *)malloc(5);//C++: array=new char[5];
堆和棧的含義其實我也沒弄太透徹,改天明白了再發一篇。
我們要明白的是,第一種形式空間分配的大小可能會受作業系統的限制,比如windows會限制在2M;第二種形式成空間分配很靈活,想分配多少分配多少,只要RAM夠大。



3
如何初始化一個指標陣列。
首先明確一個概念,就是指向陣列的指標,和存放指標的陣列。
指向陣列的指標:char (*array)[5];含義是一個指向存放5個字元的陣列的指標。
存放指標的陣列:char *array[5];含義是一個陣列中存放了5個指向字元型資料的指標。
按照題意,我理解為初始化一個存放指標的陣列,char *array[2]={"China","Beijing"};其含義是初始化了一個有兩個指向字元型資料的指標的陣列,這兩個指標分別指向字串"China""Beijing"



4
、如何定義一個有10個元素的整數型指標陣列。
既然只是定義而不是初始化,那就很簡單且沒有爭議了:int *array[10];



5
s[10]的另外一種表達方式是什麼。
前面說過了,陣列和指標其實是資料存在形態的兩種表現形式,如果說對於陣列s[],我們知道*s=s[0],那麼s[10]的另一種表達方式就是:*(s+10)



6
GCC3.2.2版本中支援哪幾種編程語言。
個問題實在變態,就像問你#error的作用是什麼一樣。不可否認,gcclinux下一個亮點,是一個備受無數程式師推崇的編譯器,其優點省略 1000字,有興趣可以自己查,我翻了翻書,書上曰:支援C,C++,Java,Obj-C,Ada,Fortran,Pascal,Modula-3 語言,這個比較要命,不過我認為已經很全了,如果認為還是不全,乾脆把ASM也加上算了,不過那已經不算是編譯了。



7
要使用CHAR_BIT需要包含哪個頭檔。
如果結合上面的問題,答題的人估計會認為自己撞鬼了,這個問題實在是……搜索了一下,應該是limits.h



8
(-1.2345)取整是多少?
其實不同的取整函數可能有不同的結果,不過這個數沒有太大的爭議,答案是-1



9
如何讓局部變數具有全局生命期。
具體的生命期的概念我覺得我還要好好深入的學習一下,但是這個題目還算比較簡單,即用static修飾就可以了,但是只是生命期延長,範圍並沒有擴大,除非把這個變數定義在函數體外的靜態區,不過那樣就變成總體變數了,仿佛不符合題目要求。



10
C中的常量字串應在何時定義?
個問題說實話不是很理解題幹的意思,據我理解,有兩種情況,一種是預處理階段,用#define定義;還有就是使用const修飾詞,不過const修飾 的是一個變數,其含義是唯讀,稱之為常量並不準確,但是確實可以用操作變數的方法當常量用。所以還是第一種比較靠譜。



11
、如何在兩個.c檔中引用對方的變數。
個問題也問的挺含糊的,怎麼說呢,最簡單最直接的方法是為變數添加extern修飾詞,當然,這個變數必須是總體變數。還有一種就是利用函數調用來進行變 量的間接引用,比如這個C檔中的一個函數引用另外一個C中的函數,將變數通過實參的形式傳遞過去。不過題目既然說是引用,那麼還是用第一個答案好了。



12
、使用malloc之前需要做什麼準備工作。
實準備工作很多啊,比如你需要一台電腦之類的。玩笑話,我們首先要知道malloc的用途,簡單的說就是動態的分配一段空間,返回這段空間的頭指針。實 際的準備工作可以這麼分:需要這段空間的指標是否存在,若不存在,則定義一個指標用來被賦值,還要清楚要返回一個什麼類型的指標,分配的空間是否合理;如 果指標已經存在,那麼在重新將新的空間頭位址賦值給這個指標之前,要先判斷指標是否為NULL,如果不是要free一下,否則原來的空間就會被浪費,或者 出錯,free之後就按照前一種情形考慮就可以了。



13
realloc函數在使用上要注意什麼問題。
函數我也才知道的,汗一個。據我的初步理解,這個函數的作用是重新分配空間大小,返回的頭指標不變,只是改變空間大小。既然是改變,就有變大、變小和為什 麼改變的問題。變大,要注意不能大到記憶體溢出;變小,那變小的那部分空間會被徵用,原有資料不再存在;為什麼改變,如果是想重新挪作他用,還是先free 了吧。



14
strtok函數在使用上要注意什麼問題。
這個問題我不知道能不能回答全面,因為實在是用的 少。這個函數的作用是分割字串,但是要分割的字串不能是常量,這是要注意的。比如先定義一個字串:char array[]="part1,part2";strtok的原形是char *strtok(char *string, char *delim);,我們將","作為分隔符號,先用pt=strtok(array,",");,得到的結果print出來就是"part1",那後面的 呢,要寫成pt=strtok(NULL,",");,注意,要用NULL,如果被分割的字串會被分成N段,那從第二次開始就一直要用NULL。總結起 來,需要注意的是:被分割的字串和分隔符號都要使用變數;除第一次使用指向字串的指標外,之後的都要使用NULL;注意使用這個函數的時候千萬別把指標 跟丟了,不然就全亂了。



15
gets函數在使用上要注意什麼問題。
這是一個鍵盤輸入函數,將輸入字串 頭位址返回。說到要注意的問題,我還是先查了一下網上的一些情況,需要注意的就是gets以輸入回車結束,這個地球人都知道,但是很多人不知道的是,當你 輸入完一個字串後,這個字串可能依然存在於這個標準輸入流之中,當再次使用gets的時候,也許會把上次輸入的東西讀出來,所以應該在使用之後用 fflush(stdin);處理一下,將輸入流清空。最後也還是要注意溢出的問題。關於這個答案我比較含糊,不知道有沒有高人高見?



16
C語言的詞法分析在長度規則方面採用的是什麼策略?
無語……聞所未聞啊……還是搜索了一下,有一篇文章,地址是:http://202.117.80.9/jp2005/20/kcwz/wlkc /wlkc/03/3_5_2.htm,是關於詞法分析器的。其中提到了兩點策略: (1) 按最長匹配原則確定被選的詞型;(2) 如果一個字串能為若干個詞型匹配,則排列在最前面的詞型被選中。不知道是不是題幹的要求,還是其他什麼。我乃一介草民,望達人指點迷津!



17
a+++++b所表示的是什麼意思?有什麼問題?
個東西(稱之為東西一點都不過分)其實並沒有語法錯誤,按照C對運算符等級的劃分,++的優先順序大於+,那麼這句話會被編譯器看做:(a++)+ (++b),這回明白了吧。有什麼問題,語法上沒有問題,有的是道德上的問題!作為一個優秀的程式師,我們要力求語句的合法性和可讀性,如果寫這句的人是 在一個team裏,那麼他基本會被打的半死……最後討論一下結果:假設a之前的值是3b4,那麼運行完這個變態語句後,a的值是4b5,語句的結 果是8



18
、如何定義Bool變數的TRUEFALSE的值。
不知道這個題有什麼陷阱,寫到現在神經已經大了,一般來說先要把TUREFALSE給定義了,使用#define就可以:
#define TURE 1
#define FALSE 0
如果有一個變數需要定義成bool型的,舉個例子:bool a=TURE;就可以了。



19
C語言的const的含義是什麼。在定義常量時,為什麼推薦使用const,而不是#define
先,這個題幹抽了10題回答的一個大嘴巴。關於常量的概念看來我要好好看看書了……我說過了,const修飾詞可以將一個變數修飾為唯讀,這個就能稱 為常量麼?姑且認為可以。回到題目中,const是唯讀的意思,它限定一個變數不允許被改變,誰都不能改!既然是修飾變數,那麼變數的類型就可以豐富多 彩,int啊,char啊,只要C認識的都可以;但是#define就不可以了,在預處理階段缺乏類型檢測機制,有可能會出錯。還有就是變數可以 extern,但是#define就不可以。貌似const還可以節省RAM,這個我倒是沒有考證過。至於const的用法和作用,有很多,我會總結後發 上來。



20
C語言的volatile的含義是什麼。使用時會對編譯器有什麼暗示。
終於最後一題了,容易 ……如果這個測試是一個關於嵌入式的,那麼這道題非常重要!!從詞面上講,volatile的意思是易變的,也就是說,在程式運行過程中,有一些變數可 能會被莫名其妙的改變,而優化器為了節約時間,有時候不會重讀這個變數的真實值,而是去讀在寄存器的備份,這樣的話,這個變數的真實值反而被優化器給 掉了,用時髦的詞說就是被和諧了。如果使用了這個修飾詞,就是通知編譯器別犯懶,老老實實去重新讀一遍!可能我說的太通俗了,那麼我引用一下大師的標準解釋:
volatile
的本意是易變的
由於訪問寄存器的速度要快過RAM,所以編譯器一般都會作減少存取外部RAM的優化,但有可能會讀髒資料。當要求使用volatile 聲明的變數的值的時候,系統總是重新從它所在的記憶體讀取資料,即使它前面的指令剛剛從該處讀取過資料。而且讀取的資料立刻被保存。
精確地說就是,優化器在用到這個變數時必須每次都小心地重新讀取這個變數的值,而不是使用保存在寄存器裏的備份。
下面是volatile變數的幾個例子:
1).
並行設備的硬體寄存器(如:狀態寄存器)
2).
一個中斷服務副程式中會訪問到的非自動變數(Non-automatic variables)
3).
多線程應用中被幾個任務共用的變數
嵌入式系統程式師經常同硬體、中斷、RTOS等等打交道,所用這些都要求volatile變數。不懂得volatile內容將會帶來災難。

arrow
arrow
    全站熱搜

    立你斯 發表在 痞客邦 留言(0) 人氣()