嵌入式软件工程师笔试题
1?.?用預(yù)處理指令?#define?聲明一個(gè)常數(shù),用以表明?1年中有多少秒(忽略閏年問(wèn)題)?
#define?SECONDS_PER_YEAR?(60?*?60?*?24?*?365)UL
2?.?寫(xiě)一個(gè)?"標(biāo)準(zhǔn)"宏?MIN?,這個(gè)宏輸入兩個(gè)參數(shù)并返回較小的一個(gè)。?
#define?MIN(A,B)((A)?<=?(B)???(A)?:?(B))?
已知一個(gè)數(shù)組table,用一個(gè)宏定義,求出數(shù)據(jù)的元素個(gè)數(shù)。
參考答案:#define NTBL
#define NTBL (sizeof(table)/sizeof(table[0]))
3.?預(yù)處理器標(biāo)識(shí)?#error的目的是什么?
不知道
4.?嵌入式系統(tǒng)中經(jīng)常要用到無(wú)限循環(huán),你怎么樣用?C編寫(xiě)死循環(huán)呢??這個(gè)問(wèn)題用幾個(gè)解決方案。我首選的方案是:?
while(1)?{??}?
一些程序員更喜歡如下方案:?for(;;)?{??}
5.?用變量?a給出下面的定義?
a)?一個(gè)整型數(shù)(?An?integer)?
b)一個(gè)指向整型數(shù)的指針(?A?pointer?to?an?integer)?
c)一個(gè)指向指針的的指針,它指向的指針是指向一個(gè)整型數(shù)(?A?pointer?to?a?pointer?to?an?intege)r?
d)一個(gè)有?10個(gè)整型數(shù)的數(shù)組(?An?array?of?10?integers)?
e)一個(gè)有?10個(gè)指針的數(shù)組,該指針是指向一個(gè)整型數(shù)的。(?An?array?of?10?pointers?to?integers)?
f)?一個(gè)指向有?10個(gè)整型數(shù)數(shù)組的指針(?A?pointer?to?an?array?of?10?integers)?
g)?一個(gè)指向函數(shù)的指針,該函數(shù)有一個(gè)整型參數(shù)并返回一個(gè)整型數(shù)(?A?pointer?to?a?function?that?takes?an?integer?as?an?argument?and?returns?an?integer)?
h)一個(gè)有?10個(gè)指針的數(shù)組,該指針指向一個(gè)函數(shù),該函數(shù)有一個(gè)整型參數(shù)并返回一個(gè)整型數(shù)(?An?array?of?ten?pointers?to?functions?t?hat?take?an?integer?argument?and?return?an?integer?)?答案是:?
a)?int?a;?//?An?integer?
b)?int?*a;?//?A?pointer?to?an?integer?
c)?int?**a;?//?A?pointer?to?a?pointer?to?an?integer?d)?int?a[10];?//?An?array?of?10?integers?
e)?int?*a[10];?//?An?array?of?10?pointers?to?integers?
f)?int?(*a)[10];?//?A?pointer?to?an?array?of?10?integers?
g)?int?(*a)(int);?//?A?pointer?to?a?function?a?that?takes?an?integer?argument?and?returns?an?integer?
h)?int?(*a[10])(int);?//?An?array?of?10?pointers?to?functions?that?take?an?integer?argument?and?return?an?integer?
6.?關(guān)鍵字?static的作用是什么??
這個(gè)簡(jiǎn)單的問(wèn)題很少有人能回答完全。
在?C語(yǔ)言中,關(guān)鍵字?static有三個(gè)明顯的作用:
在函數(shù)體,一個(gè)被聲明為靜態(tài)的變量在這一函數(shù)被調(diào)用過(guò)程中維持其值不變。
在模塊內(nèi)(但在函數(shù)體外),一個(gè)被聲明為靜態(tài)的變量可以被模塊內(nèi)所用函數(shù)訪問(wèn),但不能被模塊外其它函數(shù)訪問(wèn)。它是一個(gè)本地的全局變?量。?
在模塊內(nèi),一個(gè)被聲明為靜態(tài)的函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用。那就是,這個(gè)函數(shù)被限制在聲明它的模塊的本地范圍內(nèi)使用。
7.關(guān)鍵字?const有什么含意?
只讀
(1)欲阻止一個(gè)變量被改變,可以使用const關(guān)鍵字。在定義該const變量時(shí),通常需要對(duì)它進(jìn)行初始化,因?yàn)橐院缶蜎](méi)有機(jī)會(huì)再去改變它了;
(2)對(duì)指針來(lái)說(shuō),可以指定指針本身為const,也可以指定指針?biāo)傅臄?shù)據(jù)為const,或二者同時(shí)指定為const;
(3)在一個(gè)函數(shù)聲明中,const可以修飾形參,表明它是一個(gè)輸入?yún)?shù),在函數(shù)內(nèi)部不能改變其值;
(4)對(duì)于類(lèi)的成員函數(shù),若指定其為const類(lèi)型,則表明其是一個(gè)常函數(shù),不能修改類(lèi)的成員變量;
(5)對(duì)于類(lèi)的成員函數(shù),有時(shí)候必須指定其返回值為const類(lèi)型,以使得其返回值不為“左值”
const?int?a;?a是一個(gè)常整型數(shù)
int?const?a;?a是一個(gè)常整型數(shù)
const?int?*a;?a是一個(gè)指向常整型數(shù)的指針
int?*?const?a;?a是一個(gè)指向整型數(shù)的常指針
int?const?*?a?const;??a是一個(gè)指向常整型數(shù)的常指針
8.?關(guān)鍵字?volatile有什么含意??并給出三個(gè)不同的例子。
一個(gè)定義為?volatile的變量是說(shuō)這變量可能會(huì)被意想不到地改變
并行設(shè)備的硬件寄存器(如:狀態(tài)寄存器)?
一個(gè)中斷服務(wù)子程序中會(huì)訪問(wèn)到的非自動(dòng)變量?(Non-automatic?variables)
多線程應(yīng)用中被幾個(gè)任務(wù)共享的變量
9.?嵌入式系統(tǒng)總是要用戶(hù)對(duì)變量或寄存器進(jìn)行位操作。給定一個(gè)整型變量?a,寫(xiě)兩段代碼,第一個(gè)設(shè)置?a的?bit?3,第二個(gè)清除?a?的?bit?3。
#define?BIT3?(0x1?<<?3)?static?int?a;?
void?set_bit3(void)?{?a?|=?BIT3;?}?
void?clear_bit3(void)?{?a?&=?~BIT3;?
}
10.?嵌入式系統(tǒng)經(jīng)常具有要求程序員去訪問(wèn)某特定的內(nèi)存位置的特點(diǎn)。在某工程中,要求設(shè)置一絕對(duì)地址為?0x67a9的整型變量的值為?0xaa6
int?*ptr;?
ptr?=?(int?*)0x67a9;
*ptr?=?0xaa55;
11.?中斷是嵌入式系統(tǒng)中重要的組成部分,這導(dǎo)致了很多編譯開(kāi)發(fā)商提供一種擴(kuò)展?―讓標(biāo)準(zhǔn)?C支持中斷。具代表事實(shí)是,產(chǎn)生了一個(gè)新的關(guān)鍵?
字__interrupt。下面的代碼就使用了?__interrupt關(guān)鍵字去定義了一個(gè)中斷服務(wù)子程序?(ISR),請(qǐng)?jiān)u論一下這段代碼的。?
__interrupt?double?compute_area?(double?radius)?{?
double?area?=?PI?*?radius?*?radius;?printf("\nArea?=?%f",?area);?return?area;?}?
這個(gè)函數(shù)有太多的錯(cuò)誤了,以至讓人不知從何說(shuō)起了:?
ISR不能返回一個(gè)值。如果你不懂這個(gè),那么你不會(huì)被雇用的。?
ISR不能傳遞參數(shù)。如果你沒(méi)有看到這一點(diǎn),你被雇用的機(jī)會(huì)等同第一項(xiàng)。?
在許多的處理器?/編譯器中,浮點(diǎn)一般都是不可重入的。有些處理器?/編譯器需要讓額處的寄存器入棧,有些處理器?/編譯器就是不允許在?IS?
R中做浮點(diǎn)運(yùn)算。此外,?ISR應(yīng)該是短而有效率的,在?ISR中做浮點(diǎn)運(yùn)算是不明智的。
與第三點(diǎn)一脈相承,?printf()經(jīng)常有重入和性能上的問(wèn)題。如果你丟掉了第三和第四點(diǎn),我不會(huì)太為難你的。不用說(shuō),如果你能得到后兩點(diǎn)
12?.?下面的代碼輸出是什么,為什么??void?foo(void)?{?
unsigned?int?a?=?6;?int?b?=?-20;?
(a+b?>?6)???puts(">?6")?:?puts("<=?6");?}
?C語(yǔ)言中的整數(shù)自動(dòng)轉(zhuǎn)換原則
當(dāng)表達(dá)式中存在有符號(hào)類(lèi)型和無(wú)符號(hào)類(lèi)型時(shí)所有的操作數(shù)都自動(dòng)轉(zhuǎn)換為無(wú)符號(hào)類(lèi)型。
15?Typedef?在?C語(yǔ)言中頻繁用以聲明一個(gè)已經(jīng)存在的數(shù)據(jù)類(lèi)型的同義字。也可以用預(yù)處理器做類(lèi)似的事。
例如,思考一下下面的例子:?
#define?dPS?struct?s?*?
typedef?struct?s?*?tPS;
16?.?C語(yǔ)言同意一些令人震驚的結(jié)構(gòu)?,下面的結(jié)構(gòu)是合法的嗎,如果是它做些什么??
int?a?=?5,?b?=?7,?c;?
c?=?a+++b;?
就近原則
17 堆棧
int a = 0;全局初始化區(qū)
char *p1;全局未初始化區(qū)
main()
{
int b;棧
char s[] ="abc";棧
char *p2;棧
char *p3 ="123456"; 123456\0在常量區(qū),p3在棧上。
static int c =0;全局(靜態(tài))初始化區(qū)
p1 = (char*)malloc(10);
p2 = (char*)malloc(20);分配得來(lái)得10和20字節(jié)的區(qū)域就在堆區(qū)。
strcpy(p1,"123456"); 123456\0放在常量區(qū),編譯器可能會(huì)將它與p3所指向的"123456"優(yōu)化成一個(gè)地方。
18 什么是野指針?產(chǎn)生的原因?
“野指針”不是NULL指針,是指向“垃圾”內(nèi)存(不可用內(nèi)存)的指針。“野指針”是很危險(xiǎn)的,if無(wú)法判斷一個(gè)指針是正常指針還是“野指針”。有個(gè)良好的編程習(xí)慣是避免“野指針”的唯一方法。
野指針的成因主要有三種:
一、指針變量沒(méi)有被初始化。指針變量在創(chuàng)建的同時(shí)應(yīng)當(dāng)被初始化,要么將指針設(shè)置為NULL,要么讓它指向合法的內(nèi)存。
二、指針p被free或者delete之后,沒(méi)有置為NULL,讓人誤以為p是個(gè)合法的指針。
三、指針操作超越了變量的作用范圍。比如不要返回指向棧內(nèi)存的指針或引用,因?yàn)闂?nèi)存在函數(shù)結(jié)束時(shí)會(huì)被釋放。比如說(shuō)某個(gè)地址的生命期,使用一個(gè)沒(méi)有生命期的指針是非常危險(xiǎn)的。
19 sizeof和strlen區(qū)別
sizeof
sizeof(...)是運(yùn)算符,在頭文件中typedef為unsigned int,其值在編譯時(shí)即計(jì)算好了,參數(shù)可以是數(shù)組、指針、類(lèi)型、對(duì)象、函數(shù)等。它的功能是:獲得保證能容納實(shí)現(xiàn)所建立的最大對(duì)象的字節(jié)大小。
strlen
strlen(...)是函數(shù),要在運(yùn)行時(shí)才能計(jì)算。參數(shù)必須是字符型指針(char*)。當(dāng)數(shù)組名作為參數(shù)傳入時(shí),實(shí)際上數(shù)組就退化成指針了。
它的功能是:返回字符串的長(zhǎng)度
某32位系統(tǒng)下, C++程序,請(qǐng)計(jì)算sizeof 的值(5分).
char str[] = “http://www.ibegroup.com/”
char *p = str ;
int n = 10;
請(qǐng)計(jì)算
sizeof (str ) = ?(1)
sizeof ( p ) = ?(2)
sizeof ( n ) = ?(3)
void Foo ( char str[100]){
請(qǐng)計(jì)算
sizeof( str ) = ?(4)
}
void *p = malloc( 100 );
請(qǐng)計(jì)算
sizeof ( p ) = ?(5)
答:(1)25 (2)4 (3) 4 (4)4 (5)4
20
char iArr[10]={0,1,2,3,4,5,6,7,8,9};
short int *pVal = NULL;
pVal = (short int *)(iArr+2);
short int tVal = *pVal;
請(qǐng)問(wèn):Intel CPU的計(jì)算機(jī)中:tVal = ?
char iArr[10]={0,1,2,3,4,5,6,7,8,9};
short int *pVal = NULL;
pVal = (short int *)(iArr+2); //pVal和(iArr+2)都指向數(shù)組iArr的的3個(gè)元素2的地址
short int tVal = *pVal; //pVal指向的地址的內(nèi)容(按字節(jié))是:0x02,0x03,0x04,0x05
由于tVal和pVal分別是short類(lèi)型的變量和指針
而Intel CPU的對(duì)short雙字節(jié)的存放是:高字節(jié)在后,低字節(jié)在前
所以,tVal=*pVal=0x02+(0x03<<8)=0x0302=77
21 寫(xiě)出strcpy,strcmp,strlen,memcpy函數(shù)源碼的實(shí)現(xiàn)。
char * strcpy( char*strDest, const char *strSrc )
{
assert( (strDest !=NULL) && (strSrc != NULL) );
char *address =strDest;
while( (*strDest++= * strSrc++) !=‘\0’ );
return address;
}
int strlen( const char *str ) //輸入?yún)?shù)const
{
assert(strt != NULL); //斷言字符串地址非0
intlen;
while( (*str++) !='\0' )
{
len++;
}
return len;
}
內(nèi)存區(qū)域相對(duì)位置和重疊關(guān)系 //不知道兩個(gè)指針的類(lèi)型,不可以這樣自加
void* mymemcpy( void *dest, const void *src, size_t count )
{
char *ret;
char *dst_t;
char *src_t;
ret = (char *)dst;
if ((unsigned char*)dst <= (unsigned char*)src|| (unsigned char *)dst >= ((unsigned char *)src + count))
{ //Non-Overlapping Buffers,copy from lower addresses to higher addresse
dst_t = (char *)dst;
src_t = (char *)src;
while (count--)
{
*dst_t++ = *src_t++;
}
}else
{//Overlapping Buffers,copy from higher addresses to lower addresses
dst_t = (char *)dst + count - 1;
src_t = (char *)src + count - 1;
while (count--)
{
*dst_t-- = *src_t--;
}
}
return(ret);
}
int main( void )
{
char str[] = "0123456789";
mymemcpy( str+1, str+0, 9 );
cout << str << endl;
system( "Pause" );
return 0;
}
char * __cdecl strcat (char * dst, const char * src)
{
char * cp = dst;
while( *cp )
cp++; /* find end of dst */
while( *cp++ = *src++ ) ; /* Copy src to end of dst */
return( dst ); /* return dst */
}
int strcmp(char *str1,char *str2)
{
if(*str1==‘\0’||*str2==’\0’) return;
while(*str1!=’\0’&&*str2!=’\0’&&*str1==*str2)
{
str1++;
str2++;
}
if(*str1==*str2)
return 1;
else return 0;
}
}
22 請(qǐng)寫(xiě)一個(gè)C函數(shù),判斷大小端。
int checkCPU()
{
{
union w
{
int a;
char b;
} c;
c.a = 1;
return (c.b == 1); 小端
}
}
23 與“零值”比較
分別給出BOOL,int,float,指針變量與“零值”比較的 if語(yǔ)句(假設(shè)變量名為var)
解答:
BOOL 型變量:if(!var)
int型變量:if(var==0)
float 型變量:
const floatEPSINON = 0.00001;
if ((x >= -EPSINON) && (x <= EPSINON)
指針變量:if(var==NULL)
24 對(duì)齊方式
·使用偽指令#pragma pack (n),編譯器將按照n 個(gè)字節(jié)對(duì)齊;
·使用偽指令#pragma pack (),取消自定義字節(jié)對(duì)齊方式。
25 不是使用變量,調(diào)換兩個(gè)變量的值
a = a + b;
b = a - b;
a = a - b;
或者:
a = a ^ b;
b = a ^ b;
a = a ^ b;
26
(1).Void GetMemory(char **p, int num){
*p = (char *)malloc(num);
}
void Test(void){
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
請(qǐng)問(wèn)運(yùn)行Test 函數(shù)會(huì)有什么樣的結(jié)果?
答:輸出“hello”
(2). void Test(void){
char *str = (char *) malloc(100);
strcpy(str, “hello”);
free(str);
if(str != NULL){
strcpy(str, “world”);
printf(str);
}
}
請(qǐng)問(wèn)運(yùn)行Test 函數(shù)會(huì)有什么樣的結(jié)果?
答:輸出“world”
(3). char *GetMemory(void){
char p[] = "hello world";
return p;
}
void Test(void){
char *str = NULL;
str = GetMemory();
printf(str);
}
請(qǐng)問(wèn)運(yùn)行Test 函數(shù)會(huì)有什么樣的結(jié)果?
答:無(wú)效的指針,輸出不確定
轉(zhuǎn)載于:https://www.cnblogs.com/gjianw217/p/5272489.html
總結(jié)
以上是生活随笔為你收集整理的嵌入式软件工程师笔试题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 安装jdk源码
- 下一篇: 将前台json对象传入java后台