嵌入式linux面试题解析(二)——C语言部分三
嵌入式linux面試題解析(二)——C語言部分三
1、下面的程序會(huì)出現(xiàn)什么結(jié)果
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void getmemory(char *p)
{
????p=(char *) malloc(100);
????strcpy(p,”hello world”);
}
int main( )
{
????char *str=NULL;
????getmemory(str);
????printf(“%s/n”,str);
????free(str);
????return 0;
}
程序崩潰,getmemory中的malloc 不能返回動(dòng)態(tài)內(nèi)存, free()對(duì)str操作很危險(xiǎn)
?
2、(void *)ptr 和 (*(void**))ptr的結(jié)果是否相同?
答:ptr為同一個(gè)指針
(void *)ptr 和 (*(void**))ptr值是相同的
?
3、對(duì)絕對(duì)地址0×100000賦值且想讓程序跳轉(zhuǎn)到絕對(duì)地址是0×100000去執(zhí)行
(unsigned int*)0×100000 = 1234;
首先要將0×100000強(qiáng)制轉(zhuǎn)換成函數(shù)指針,即:
(void (*)())0×100000
然后再調(diào)用它:
*((void (*)())0×100000)();
用typedef可以看得更直觀些:
typedef void(*)() voidFuncPtr;
*((voidFuncPtr)0×100000)();
?
4、下面的函數(shù)實(shí)現(xiàn)在一個(gè)數(shù)上加一個(gè)數(shù),有什么錯(cuò)誤?請(qǐng)改正。
int add_n ( int n )
{
????static int i = 100;
????i += n;
????return i;
}
????當(dāng)你第二次調(diào)用時(shí)得不到正確的結(jié)果,難道你寫個(gè)函數(shù)就是為了調(diào)用一次?問題就出在 static上
5、下面這個(gè)程序執(zhí)行后會(huì)有什么錯(cuò)誤或者效果:
#define MAX 255
int main()
{
????unsigned char A[MAX],i;//i被定義為unsigned char
????for (i=0;i<=MAX;i++)
????A[i]=i;
}
解答:死循環(huán)加數(shù)組越界訪問(C/C++不進(jìn)行數(shù)組越界檢查)
MAX=255
數(shù)組A的下標(biāo)范圍為:0..MAX-1,這是其一
其二、當(dāng)i循環(huán)到255時(shí),循環(huán)內(nèi)執(zhí)行:
A[255]=255;
這句本身沒有問題,但是返回for (i=0;i<=MAX;i++)語句時(shí),
由于unsigned char的取值范圍在(0..255),i++以后i又為0了..無限循環(huán)下去.
?
6、請(qǐng)問一下程序?qū)⑤敵鍪裁唇Y(jié)果?
char *RetMenory(void)
{
????char p[] = “hellow world”;
????return p;
}
void Test(void)
{
????char *str = NULL;
????str = RetMemory();
????printf(str);
}
????RetMenory執(zhí)行完畢,p資源被回收,指向未知地址。返回地址,str的內(nèi)容應(yīng)是不可預(yù)測(cè)的, 打印的應(yīng)該是str的地址
?
7、對(duì)下面程序進(jìn)行分析
void test2()
{
????char string[10], str1[10];
????int i;
????for(i=0; i<10; i++)
????{
????????str1[i] = 'a';
????}
????strcpy( string, str1 );
}
解答:
字符數(shù)組str1不能在數(shù)組內(nèi)結(jié)束
strcpy(string, str1)調(diào)用使得從str1內(nèi)存起復(fù)制到string內(nèi)存起所復(fù)制的字節(jié)數(shù)具有不確定性
指出庫函數(shù)strcpy工作方式
str1不能在數(shù)組內(nèi)結(jié)束:因?yàn)閟tr1的存儲(chǔ)為:{a,a,a,a,a,a,a,a,a,a},沒有'\0'(字符串結(jié)束符),所以不能結(jié)束
strcpy( char *s1,char *s2)他的工作原理是,掃描s2指向的內(nèi)存,逐個(gè)字符付到s1所指向的內(nèi)存,直到碰到'\0',因?yàn)閟tr1結(jié)尾沒有'\0',所以具有不確定性,不知道他后面還會(huì)付什么東東。
正確應(yīng)如下
void test2()
{
????char string[10], str1[10];
????int i;
????for(i=0; i<9; i++)
????{
????????str1[i] = 'a'+i; //把a(bǔ)bcdefghi賦值給字符數(shù)組
????}
????str[i]='\0';//加上結(jié)束符
????strcpy( string, str1 );
}
?
8、分析下列代碼輸出的值
int arr[] = {6,7,8,9,10};
int *ptr = arr;
*(ptr++)+=123;
printf(“ %d %d ”, *ptr, *(++ptr));
輸出:8 8
過程:對(duì)于*(ptr++)+=123;先做加法6+123,然后++,指針指向7;對(duì)于printf(“ %d %d ”, *ptr, *(++ptr));從后往前執(zhí)行,指針先++,指向8,然后輸出8,緊接著再輸出8
?
9、分析下面的代碼:
char *a = "hello";
char *b = "hello";
if(a= =b)
????printf("YES");
else
????printf("NO");
輸出YES
"hello"是一個(gè)常量字符串,位于靜態(tài)存儲(chǔ)區(qū),在程序生命期內(nèi)恒定不變,a和b同時(shí)指向同一個(gè)hello的。
?
10、已知strcpy函數(shù)的原型是:
char * strcpy(char * strDest,const char * strSrc);
不調(diào)用庫函數(shù),實(shí)現(xiàn)strcpy函數(shù)。
解釋為什么要返回char *。
解答:
strcpy實(shí)現(xiàn)代碼:
char * strcpy( char *strDest, const char *strSrc )
{
assert( (strDest != NULL) && (strSrc != NULL) );
char *address = strDest;
while( (*strDest++ = * strSrc++) != '’ );
return address;
}
?
11、判斷一個(gè)字符串是不是回文
int IsReverseStr(char *aStr)
{
????int i,j;
????int found=1;
????if(aStr==NULL)
????????return -1;
????j=strlen(aStr);
????for(i=0;i<j; i++)
????if(*(aStr+i)!=*(aStr+j-i-1))
????{
????????found=0;
????????break;
????}
????return found;
}
?
12、寫一個(gè)函數(shù)比較兩個(gè)字符串str1和str2的大小,若相等返回0,若str1大于
str2返回1,若str1小于str2返回-1
int strcmp ( const char * src,const char * dst)
{
????int ret = 0 ;
????while( ! (ret = *(unsigned char *)src – *(unsigned char *)dst) && *dst)
????{
????????++src;
????????++dst;
????}
????if ( ret < 0 )
????????ret = -1 ;
????else if ( ret > 0 )
????????ret = 1 ;
????return( ret );
}
13、給定字符串A和B,輸出A和B中的最大公共子串。
比如A="aocdfe" B="pmcdfa" 則輸出"cdf"
*/
//Author: azhen
#include
#include
#include
char *commanstring(char shortstring[], char longstring[])
{
????int i, j;
?char *substring=malloc(256);
?if(strstr(longstring, shortstring)!=NULL)
return shortstring;
????for(i=strlen(shortstring)-1;i>0; i–) //否則,開始循環(huán)計(jì)算
????{
????????for(j=0; j<=strlen(shortstring)-i; j++)
?{
????????????memcpy(substring, &shortstring[j], i);
????????????substring[i]='\0';
????????????if(strstr(longstring, substring)!=NULL)
????????????return substring;
????????}
????}
????return NULL;
}
int main()
{
????char *str1=malloc(256);
????char *str2=malloc(256);
????char *comman=NULL;
?gets(str1);
????gets(str2);
?if(strlen(str1)>strlen(str2)) //將短的字符串放前面
????????comman=commanstring(str2, str1);
????else
????????comman=commanstring(str1, str2);
????printf(“the longest comman string is: %s\n”, comman);
}
14、編寫一個(gè) C 函數(shù),該函數(shù)在一個(gè)字符串中找到可能的最長的子字符串,且該字符串是由同一字符組成的。
char * search(char *cpSource, char ch)
{
????char *cpTemp=NULL, *cpDest=NULL;
????int iTemp, iCount=0;
????while(*cpSource)
????{
????????if(*cpSource == ch)
????????{
????????????iTemp = 0;
????????????cpTemp = cpSource;
????????????while(*cpSource == ch)
????????????????++iTemp, ++cpSource;
????????????if(iTemp > iCount)
????????????????iCount = iTemp, cpDest = cpTemp;
????????????if(!*cpSource)
????????????????break;
????????}
????++cpSource;
????}
????return cpDest;
}
?
15、不用庫函數(shù),用C語言實(shí)現(xiàn)將一整型數(shù)字轉(zhuǎn)化為字符串
int getlen(char *s)
{
????int n;
????for(n = 0; *s != '\0'; s++)
????????n++;
????return n;
}
void reverse(char s[])
{
????int c,i,j;
????for(i = 0,j = getlen(s) - 1; i < j; i++,j--)
{
????????c = s[i];
????????s[i] = s[j];
????????s[j] = c;
????}
}
void itoa(int n,char s[])
{
????int i,sign;
????if((sign = n) < 0)
????n = -n;
????i = 0;
????do{/*以反序生成數(shù)字*/
????????s[i++] = n%10 + '0';/*get next number*/
????}while((n /= 10) > 0);/*delete the number*/
?if(sign < 0)
????????s[i++] = '-';
??? s[i] = '\0';
????reverse(s);
}
16、請(qǐng)說出const與#define 相比,有何優(yōu)點(diǎn)?
答:const作用:定義常量、修飾函數(shù)參數(shù)、修飾函數(shù)返回值三個(gè)作用。被Const修飾的東西都受到強(qiáng)制保護(hù),可以預(yù)防意外的變動(dòng),能提高程序的健壯性。
A、const常量有數(shù)據(jù)類型,而宏常量沒有數(shù)據(jù)類型。編譯器可以對(duì)前者進(jìn)行類型安全檢查。而對(duì)后者只進(jìn)行字符替換,沒有類型安全檢查,并且在字符替換可能會(huì)產(chǎn)生意料不到的錯(cuò)誤。
B、有些集成化的調(diào)試工具可以對(duì)const 常量進(jìn)行調(diào)試,但是不能對(duì)宏常量進(jìn)行調(diào)試。
?
17、編寫用C語言實(shí)現(xiàn)的求n階階乘問題的遞歸算法:
答:
long int fact(int n)
{
????if(n==0||n==1)
?? ????return 1;
????else
?????? return n*fact(n-1);
}
?
18、二分查找算法:
A遞歸方法實(shí)現(xiàn):
int BSearch(elemtype a[],elemtype x,int low,int high)
/*在下界為low,上界為high的數(shù)組a中折半查找數(shù)據(jù)元素x*/
{
int mid;
if(low>high)
return -1;
mid=(low+high)/2;
if(x?==?a[mid])
return mid;
?????? if(x<a[mid])
return(bsearch(a,x,low,mid-1));
else
return(BSearch(a,x,mid+1,high));
}
B、非遞歸方法實(shí)現(xiàn):
int BSearch(elemtype a[],keytype key,int n)
{
int low,high,mid;
low=0;high=n-1;
while(low<=high)
{
mid=(low+high)/2;
if(a[mid].key==key)
return mid;
else if(a[mid].key<key)
low="mid+1;</font">
else
high=mid-1;
}
return -1;
}
?
19、遞歸計(jì)算如下遞歸函數(shù)的值(斐波拉契)
f(1)=1
f(2)=1
f(n)=f(n-1)+f(n-2) n>2
解:
A、非遞歸算法
int f(int n)
{
int i,s,s1,s2;
s1=1;/*s1用于保存f(n-1)的值*/
s2=1;/*s2用于保存f(n-2)的值*/
s=1;
for(i=3;i<=n;i++)
{
s=s1+s2;
s2=s1;
?? s1=s;
}
return(s);
}
B、遞歸算法
int f(int n)
{
if(n==1||n==2)
?? ????????rerurn 1;
?????? else
?? ????????return f(n-1)+f(n-2);
}
20、如何判斷一段程序是由C 編譯程序還是由C++編譯程序編譯的?
答:
#ifdef __cplusplus
cout<<"c++";
#else
cout<<"c";
#endif
?
21、結(jié)構(gòu)與共用體有和區(qū)別?
答:
?A、結(jié)構(gòu)和共用體都是由多個(gè)不同的數(shù)據(jù)類型成員組成, 但在任何同一時(shí)刻, 共用體中只存放了一個(gè)被選中的成員(所有成員共用一塊地址空間), 而結(jié)構(gòu)的所有成員都存在(不同成員的存放地址不同)。
????B、對(duì)于共用體的不同成員賦值, 將會(huì)對(duì)其它成員重寫, 原來成員的值就不存在了, 而對(duì)于結(jié)構(gòu)的不同成員賦值是互不影響的
轉(zhuǎn)載于:https://blog.51cto.com/9291927/1831702
總結(jié)
以上是生活随笔為你收集整理的嵌入式linux面试题解析(二)——C语言部分三的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微软官方网站提供 MASM 8.0软件包
- 下一篇: linux文件管理器thunar,文件管