嵌入式linux面試題解析(二)——C語言部分三
1、下面的程序會出現什么結果
#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 不能返回動態內存, free()對str操作很危險
?
2、(void *)ptr 和 (*(void**))ptr的結果是否相同?
答:ptr為同一個指針
(void *)ptr 和 (*(void**))ptr值是相同的
?
3、對絕對地址0×100000賦值且想讓程序跳轉到絕對地址是0×100000去執行
(unsigned int*)0×100000 = 1234;
首先要將0×100000強制轉換成函數指針,即:
(void (*)())0×100000
然后再調用它:
*((void (*)())0×100000)();
用typedef可以看得更直觀些:
typedef void(*)() voidFuncPtr;
*((voidFuncPtr)0×100000)();
?
4、下面的函數實現在一個數上加一個數,有什么錯誤?請改正。
int add_n ( int n )
{
????static int i = 100;
????i += n;
????return i;
}
????當你第二次調用時得不到正確的結果,難道你寫個函數就是為了調用一次?問題就出在 static上
5、下面這個程序執行后會有什么錯誤或者效果:
#define MAX 255
int main()
{
????unsigned char A[MAX],i;//i被定義為unsigned char
????for (i=0;i<=MAX;i++)
????A[i]=i;
}
解答:死循環加數組越界訪問(C/C++不進行數組越界檢查)
MAX=255
數組A的下標范圍為:0..MAX-1,這是其一
其二、當i循環到255時,循環內執行:
A[255]=255;
這句本身沒有問題,但是返回for (i=0;i<=MAX;i++)語句時,
由于unsigned char的取值范圍在(0..255),i++以后i又為0了..無限循環下去.
?
6、請問一下程序將輸出什么結果?
char *RetMenory(void)
{
????char p[] = “hellow world”;
????return p;
}
void Test(void)
{
????char *str = NULL;
????str = RetMemory();
????printf(str);
}
????RetMenory執行完畢,p資源被回收,指向未知地址。返回地址,str的內容應是不可預測的, 打印的應該是str的地址
?
7、對下面程序進行分析
void test2()
{
????char string[10], str1[10];
????int i;
????for(i=0; i<10; i++)
????{
????????str1[i] = 'a';
????}
????strcpy( string, str1 );
}
解答:
字符數組str1不能在數組內結束
strcpy(string, str1)調用使得從str1內存起復制到string內存起所復制的字節數具有不確定性
指出庫函數strcpy工作方式
str1不能在數組內結束:因為str1的存儲為:{a,a,a,a,a,a,a,a,a,a},沒有'\0'(字符串結束符),所以不能結束
strcpy( char *s1,char *s2)他的工作原理是,掃描s2指向的內存,逐個字符付到s1所指向的內存,直到碰到'\0',因為str1結尾沒有'\0',所以具有不確定性,不知道他后面還會付什么東東。
正確應如下
void test2()
{
????char string[10], str1[10];
????int i;
????for(i=0; i<9; i++)
????{
????????str1[i] = 'a'+i; //把abcdefghi賦值給字符數組
????}
????str[i]='\0';//加上結束符
????strcpy( string, str1 );
}
?
8、分析下列代碼輸出的值
int arr[] = {6,7,8,9,10};
int *ptr = arr;
*(ptr++)+=123;
printf(“ %d %d ”, *ptr, *(++ptr));
輸出:8 8
過程:對于*(ptr++)+=123;先做加法6+123,然后++,指針指向7;對于printf(“ %d %d ”, *ptr, *(++ptr));從后往前執行,指針先++,指向8,然后輸出8,緊接著再輸出8
?
9、分析下面的代碼:
char *a = "hello";
char *b = "hello";
if(a= =b)
????printf("YES");
else
????printf("NO");
輸出YES
"hello"是一個常量字符串,位于靜態存儲區,在程序生命期內恒定不變,a和b同時指向同一個hello的。
?
10、已知strcpy函數的原型是:
char * strcpy(char * strDest,const char * strSrc);
不調用庫函數,實現strcpy函數。
解釋為什么要返回char *。
解答:
strcpy實現代碼:
char * strcpy( char *strDest, const char *strSrc )
{
assert( (strDest != NULL) && (strSrc != NULL) );
char *address = strDest;
while( (*strDest++ = * strSrc++) != '’ );
return address;
}
?
11、判斷一個字符串是不是回文
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、寫一個函數比較兩個字符串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–) //否則,開始循環計算
????{
????????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、編寫一個 C 函數,該函數在一個字符串中找到可能的最長的子字符串,且該字符串是由同一字符組成的。
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、不用庫函數,用C語言實現將一整型數字轉化為字符串
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{/*以反序生成數字*/
????????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、請說出const與#define 相比,有何優點?
答:const作用:定義常量、修飾函數參數、修飾函數返回值三個作用。被Const修飾的東西都受到強制保護,可以預防意外的變動,能提高程序的健壯性。
A、const常量有數據類型,而宏常量沒有數據類型。編譯器可以對前者進行類型安全檢查。而對后者只進行字符替換,沒有類型安全檢查,并且在字符替換可能會產生意料不到的錯誤。
B、有些集成化的調試工具可以對const 常量進行調試,但是不能對宏常量進行調試。
?
17、編寫用C語言實現的求n階階乘問題的遞歸算法:
答:
long int fact(int n)
{
????if(n==0||n==1)
?? ????return 1;
????else
?????? return n*fact(n-1);
}
?
18、二分查找算法:
A遞歸方法實現:
int BSearch(elemtype a[],elemtype x,int low,int high)
/*在下界為low,上界為high的數組a中折半查找數據元素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、非遞歸方法實現:
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、遞歸計算如下遞歸函數的值(斐波拉契)
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、結構與共用體有和區別?
答:
?A、結構和共用體都是由多個不同的數據類型成員組成, 但在任何同一時刻, 共用體中只存放了一個被選中的成員(所有成員共用一塊地址空間), 而結構的所有成員都存在(不同成員的存放地址不同)。
????B、對于共用體的不同成員賦值, 將會對其它成員重寫, 原來成員的值就不存在了, 而對于結構的不同成員賦值是互不影響的
轉載于:https://blog.51cto.com/9291927/1831702