嵌入式linux面試題解析(二)——C語言部分三

嵌入式linux面試題解析(二)——C語言部分三

一、下面的程序會出現什麼結果
#include <stdio.h>
#include <stdlib.h>linux

#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操做很危險c++

 

2、(void *)ptr 和 (*(void**))ptr的結果是否相同?
答:ptr爲同一個指針
(void *)ptr 和 (*(void**))ptr值是相同的面試

 

三、對絕對地址0×100000賦值且想讓程序跳轉到絕對地址是0×100000去執行
(unsigned int*)0×100000 = 1234;
首先要將0×100000強制轉換成函數指針,即:
(void (*)())0×100000
而後再調用它:
*((void (*)())0×100000)();
用typedef能夠看得更直觀些:
typedef void(*)() voidFuncPtr;
*((voidFuncPtr)0×100000)();算法

 

四、下面的函數實如今一個數上加一個數,有什麼錯誤?請改正。
int add_n ( int n )
{
    static int i = 100;
    i += n;
    return i;
}
    當你第二次調用時得不到正確的結果,難道你寫個函數就是爲了調用一次?問題就出在 static上數組


五、下面這個程序執行後會有什麼錯誤或者效果:
#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了..無限循環下去.安全

 

六、請問一下程序將輸出什麼結果?
char *RetMenory(void)
{
    char p[] = 「hellow world」;
    return p;
}
void Test(void)
{
    char *str = NULL;
    str = RetMemory();
    printf(str);
}
    RetMenory執行完畢,p資源被回收,指向未知地址。返回地址,str的內容應是不可預測的, 打印的應該是str的地址ide

 

七、對下面程序進行分析
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內存起所複製的字節數具備不肯定性spa

指出庫函數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 );
}

 

八、分析下列代碼輸出的值
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

 

九、分析下面的代碼:
char *a = "hello";
char *b = "hello";
if(a= =b)
    printf("YES");
else
    printf("NO");
輸出YES

"hello"是一個常量字符串位於靜態存儲區,在程序生命期內恆定不變a和b同時指向同一個hello的。

 

十、已知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;
}

 

十一、判斷一個字符串是否是迴文
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;
}

 

十二、寫一個函數比較兩個字符串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 );

}


1三、給定字符串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;
}

 

1五、不用庫函數,用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);
}


1六、請說出const與#define 相比,有何優勢?
答:const做用:定義常量、修飾函數參數、修飾函數返回值三個做用。被Const修飾的東西都受到強制保護,能夠預防意外的變更,能提升程序的健壯性。
A、const常量有數據類型,而宏常量沒有數據類型。編譯器能夠對前者進行類型安全檢查。而對後者只進行字符替換,沒有類型安全檢查,而且在字符替換可能會產生意料不到的錯誤。
B、有些集成化的調試工具能夠對const 常量進行調試,可是不能對宏常量進行調試。

 

1七、編寫用C語言實現的求n階階乘問題的遞歸算法:

答:

long int fact(int n)
{

    if(n==0||n==1)

       return 1;

    else

       return n*fact(n-1);

}

 

1八、二分查找算法:

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;

}

 

1九、遞歸計算以下遞歸函數的值(斐波拉契)

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

 

2一、結構與共用體有和區別?
答:

 A、結構和共用體都是由多個不一樣的數據類型成員組成, 但在任何同一時刻, 共用體中只存放了一個被選中的成員(全部成員共用一塊地址空間), 而結構的全部成員都存在(不一樣成員的存放地址不一樣)。
    B、對於共用體的不一樣成員賦值, 將會對其它成員重寫, 原來成員的值就不存在了, 而對於結構的不一樣成員賦值是互不影響的

相關文章
相關標籤/搜索