單片機編程面試題 常見問題及答案
時間:2018-01-24 來源:未知
2018年(nian)新(xin)的(de)(de)一年(nian),新(xin)的(de)(de)開始,相信(xin)有很多人都在備戰找新(xin)的(de)(de)工作了(le)。那么不妨來了(le)解一些單片機編程面試題,做好萬全的(de)(de)準備,才(cai)可能百發百中嘛。下面分享三(san)個(ge)單片機編程面試題,都是很常見的(de)(de)問題,附(fu)帶答案。

問題一:char *p="abc" 與 char p[]="abc" 的區別
答案:
1.以字符(fu)串形式(shi)出現的,編譯器都(dou)會為該字符(fu)串自動添加(jia)一個(ge)0作為結束(shu)符(fu),如在代碼中寫"abc",那么編譯器幫你(ni)存儲的是"abc\0"
2."abc"是常(chang)量嗎?
答案:有(you)時是,有(you)時不(bu)是
不是常量的情況(kuang):
"abc"作(zuo)為字符數組初始值的(de)時(shi)候就不(bu)是(shi),如
char str[] = "abc";
因為(wei)定義(yi)的是一(yi)個(ge)字(zi)符(fu)數組(zu),所(suo)以就相當于定義(yi)了一(yi)些空間(jian)來存(cun)放"abc",而(er)又(you)因為(wei)字(zi)符(fu)數組(zu)就是把(ba)字(zi)符(fu)一(yi)個(ge)一(yi)個(ge)地存(cun)放的,所(suo)以編譯器把(ba)這個(ge)語(yu)句解析為(wei)
char str[3] = {'a','b','c'};
又根據上(shang)面的總結1,所以char str[] = "abc";的終結果是
char str[4] = {'a','b','c','\0'};
做一下擴展,如果char str[] = "abc";是在(zai)(zai)函數內部寫的話(hua),那么這里的"abc\0"因為不是常量,所以(yi)應該被放(fang)在(zai)(zai)棧上。
是常量的(de)情況:
把"abc"賦給一個(ge)字(zi)符指(zhi)針變(bian)量時,如
char* ptr = "abc";
因 為(wei)定義的(de)(de)是一(yi)個普通指針(zhen),并(bing)沒有定義空(kong)間來(lai)存放"abc",所(suo)以編(bian)譯(yi)器得幫我們(men)找地(di)方來(lai)放"abc",顯然,把這里(li)的(de)(de)"abc"當成常量(liang)并(bing)把它放到程序(xu)的(de)(de) 常量(liang)區是編(bian)譯(yi)器合適的(de)(de)選擇。所(suo)以盡(jin)管ptr的(de)(de)類型不是const char*,并(bing)且(qie)ptr[0] = 'x';也能編(bian)譯(yi)通過,但是執行ptr[0] = 'x';就(jiu)會(hui)發生(sheng)運行時(shi)異常,因為(wei)這個語句試圖去修(xiu)改(gai)程序(xu)常量(liang)區中的(de)(de)東西。
記(ji)得哪(na)本書中曾經說過char* ptr = "abc";這種寫(xie)法原來在(zai)c++標(biao)準中是(shi)不允(yun)許(xu)(xu)的(de)(de),但(dan)是(shi)因(yin)為(wei)這種寫(xie)法在(zai)c中實在(zai)是(shi)太多了(le),為(wei)了(le)兼容c,不允(yun)許(xu)(xu)也得允(yun)許(xu)(xu)。雖然允(yun)許(xu)(xu),但(dan)是(shi)建議(yi)的(de)(de)寫(xie)法應(ying)該是(shi) const char* ptr = "abc";這樣如果后面寫(xie)ptr[0] = 'x'的(de)(de)話(hua)編譯器就不會讓它編譯通過,也就避(bi)免了(le)上面說的(de)(de)運行時異常。
又擴展一下(xia),如果char* ptr = "abc";寫在(zai)函數體(ti)內,那(nei)么雖然這里(li)的"abc\0"被(bei)(bei)放在(zai)常(chang)量區(qu)中,但是(shi)(shi)ptr本身只是(shi)(shi)一個普通的指針變量,所(suo)以ptr是(shi)(shi)被(bei)(bei)放在(zai)棧上的,只不(bu)過是(shi)(shi)它所(suo)指向(xiang)的東西被(bei)(bei)放在(zai)常(chang)量區(qu)罷了。
3.字(zi)符串常(chang)(chang)量的(de)類型可(ke)以理解為相應字(zi)符常(chang)(chang)量數(shu)組的(de)類型,如"abcdef"的(de)類型就可(ke)以看成是const char[7]
4. 如果(guo)真的需要使用"abcd"作(zuo)為指針,建議(yi)寫為const char * p="abcd";
如(ru)果(guo)是(shi)初始化字(zi)符串數組,建議寫為char p[]="abcd";
如果(guo)p為(wei)指針,需要(yao)初始化,應該是char *p;p=malloc(STR_SIZE);strcpy(p,"abcd");
問題二:單片機實現軟件復位(軟復位)的方法及討論
1、放狗(gou);2、((void(code *)(void))0x0000)();3、用單(dan)片(pian)(pian)機(ji)一個引腳(jiao)控(kong)(kong)制點一下RSTRST;4、用單(dan)片(pian)(pian)機(ji)一個引腳(jiao)控(kong)(kong)制重新加電(dian);5、用單(dan)片(pian)(pian)機(ji)自帶的軟件復位(wei)指令(ling)或內狗(gou)指令(ling);6、goto大(da)法
方法1:“放狗”是(shi)單(dan)片機(ji)軟(ruan)復位的好辦法,也基(ji)本上是(shi)唯一(yi)的一(yi)個辦法。但并不是(shi)所有單(dan)片機(ji)都具備看門狗的功能(neng),也不是(shi)一(yi)個萬全(quan)之策。
辦法(fa)2:這不(bu)是(shi)復位(wei),只是(shi)把程序轉到地(di)(di)(di)址0去(qu)執行,不(bu)如用(yong)(yong)一個JMP更直接。目前可(ke)能極(ji)少數單(dan)片(pian)機或者(zhe)用(yong)(yong)戶已(yi)經自行添加Boot load時用(yong)(yong)戶程序的(de)程序開始地(di)(di)(di)址并不(bu)為0x0000,所以(yi)需(xu)要(yao)查(cha)找這些特定單(dan)片(pian)機的(de)啟動地(di)(di)(di)址。在keil C51下面(mian)可(ke)以(yi)這樣(yang)實(shi)現:void soft_reset(void){ ((void (code *) (void)) 0x0000) ();}或者(zhe)void (*reset)()=0x0000;在需(xu)要(yao)軟(ruan)(ruan)件復位(wei)的(de)地(di)(di)(di)方使用(yong)(yong)語句:soft_reset(); 一般可(ke)實(shi)現軟(ruan)(ruan)件復位(wei)。
辦法(fa)3:用軟件實現的硬復(fu)位。需要犧(xi)牲一個(ge)單(dan)片(pian)機引腳,且增加了單(dan)片(pian)機外部電路構造(zao)的復(fu)雜(za)性(xing),很(hen)不可取。
辦法4:類似(si)辦法3,同樣需要犧牲(sheng)一個單(dan)片機引腳,且增加了單(dan)片機外(wai)部電(dian)路構(gou)造(zao)的復(fu)雜性,很不可取。但不能把它單(dan)單(dan)地當成是復(fu)位(wei),應該叫上電(dian)復(fu)位(wei)。
辦法5:Atmel 89C不帶(dai)內(nei)狗,S的(de)(de)(de)有(you)內(nei)狗,只是(shi)一條(tiao)指(zhi)令就行(xing)。如STC的(de)(de)(de)單(dan)片機有(you)軟件(jian)復(fu)位指(zhi)令,即ISP_CONTR,地(di)址(zhi)在(zai)0E7H 單(dan)元(即str ISP_CONTR=0xE7),MOV ISP_CONTR,#00100000B(C語言為ISP_CONTR=0x20),內(nei)狗也是(shi)一條(tiao)指(zhi)令MOV WDT_CONTR,#00111100B!STC 51系(xi)列(lie)單(dan)片機Datasheet中指(zhi)出(chu):傳統的(de)(de)(de)8051 單(dan)片機由于(yu)硬件(jian)上未支持此(ci)功能(neng)(neng),用(yong)戶(hu)(hu)必(bi)須用(yong)軟件(jian)模(mo)擬實現(xian),實現(xian)起來較(jiao)麻(ma)煩(fan)。現(xian)STC 新推出(chu)的(de)(de)(de)增強(qiang)型(xing)8051 根據客戶(hu)(hu)要求增加了(le)ISP_CONTR 特(te)殊(shu)功能(neng)(neng)寄存器,實現(xian)了(le)此(ci)功能(neng)(neng)。用(yong)戶(hu)(hu)只需簡單(dan)的(de)(de)(de)控(kong)制ISP_CONTR 特(te)殊(shu)功能(neng)(neng)寄存器的(de)(de)(de)其中兩(liang)位 SWBS / SWRST 就可以(yi)系(xi)統復(fu)位了(le)。
辦法(fa)6:程序(xu)從頭(上電復位處(chu))開始運行,且只有一(yi)(yi)(yi)個(ge)(ge)循環這種情況(kuang),當然可以(yi)用(yong)goto,如在main()的(de)開頭設一(yi)(yi)(yi)個(ge)(ge)start:,在程序(xu)的(de)唯(wei)一(yi)(yi)(yi)循環中(zhong)設定(ding)一(yi)(yi)(yi)個(ge)(ge)條(tiao)件(jian),然后goto命令。但需(xu)要注意(yi),如果(guo)是(shi)在中(zhong)斷(duan)例程里,那(nei)么中(zhong)斷(duan)掛號寄(ji)存(cun)器(qi)仍置位,同級(ji)(ji)中(zhong)斷(duan)不能(neng)執(zhi)行。所以(yi)必(bi)須先使(shi)中(zhong)斷(duan)掛號寄(ji)存(cun)器(qi)清零,EA = 0。只有RETI指(zhi)令可以(yi)使(shi)中(zhong)斷(duan)掛號寄(ji)存(cun)器(qi)清零。51單片機(ji)有兩(liang)級(ji)(ji)中(zhong)斷(duan)優先級(ji)(ji),所以(yi)需(xu)要執(zhi)行兩(liang)次RETI指(zhi)令。這用(yong)匯(hui)編是(shi)很簡單的(de)事,而(er)C則比較難以(yi)實現。但是(shi),goto命令盡量不要用(yong),因為(wei)goto會到處(chu)亂竄,而(er)且goto不能(neng)跑到函數(shu)外面去(qu)執(zhi)行一(yi)(yi)(yi)個(ge)(ge)命令。
后總結如下:好使(shi)用(yong)辦(ban)法5為簡潔方(fang)便,使(shi)用(yong)辦(ban)法2實現也不(bu)失為一種好方(fang)法
問題三:
int main()
{ int a=5;
int*q;
q=(int*)&a;
printf("%d\n",*q);
}
代碼(ma)沒有問題,面試中可能會(hui)把q=(int *)&a;中的強制轉換去掉問你會(hui)出什么問題
以上內容(rong)總(zong)結的(de)三個單片機編程面試常(chang)見(jian)問題,你都會(hui)了嗎?如(ru)果還不會(hui),再仔細看看答案哦。