C語言面試

2、評價下面的代碼片斷:
unsigned int zero = 0;
unsigned int compzero = 0xFFFF;

對於一個int型不是16位的處理器爲說,上面的代碼是不正確的。應編寫如下:
unsigned int compzero = ~0;
   
 這一問題真正能揭露出應試者是否懂得處理器字長的重要性。在我的經驗裏,好的嵌入式程序員非常準確地明白硬件的細節和它的侷限,然而PC機程序往往把硬件作爲一個無法避免的煩惱。

 

int main(){

char* src = "hello,world";

int len = strlen(src);

char* dest = (char*)malloc(len+1);//要爲\0分配一個空間,strlen的返回值不包括’0’

char* d = dest;

char* s = &src[len-1];//指向最後一個字符

while( len-- != 0 )

*d++=*s--;

*d = 0;//尾部要加\0

printf("%s\n",dest);

free(dest);// 使用完,應當釋放空間,以免造成內存匯泄露

return 0;

}

 

8、請問下面程序有什麼錯誤?

   int a[60][250][1000],i,j,k;

   for(k=0;k<=1000;k++)

    for(j=0;j<250;j++)

     for(i=0;i<60;i++)

      a[i][j][k]=0;

答案:把循環語句內外換一下

 

 

11、寫出下面的結果

char str1[] = "abc";

char str2[] = "abc";

 

const char str3[] = "abc";

const char str4[] = "abc";

 

const char *str5 = "abc";

const char *str6 = "abc";

 

char *str7 = "abc";

char *str8 = "abc";

 

cout << ( str1 == str2 ) << endl;

cout << ( str3 == str4 ) << endl;

cout << ( str5 == str6 ) << endl;

cout << ( str7 == str8 ) << endl;

 

結果是:0 0 1 1

解答:str1,str2,str3,str4是數組變量,它們有各自的內存空間;

str5,str6,str7,str8是指針,它們指向相同的常量區域。

 

12、以下代碼中的兩個sizeof用法有問題嗎?

void UpperCase( char str[] ) //  str 中的小寫字母轉換成大寫字母

{

    for( size_t i=0; i<sizeof(str)/sizeof(str[0]); ++i )

        if( 'a'<=str[i] && str[i]<='z' )

            str[i] -= ('a'-'A' );

}

char str[] = "aBcDe";

cout << "str字符長度爲: " << sizeof(str)/sizeof(str[0]) << endl;

UpperCase( str );

cout << str << endl;

答:函數內的sizeof有問題。根據語法,sizeof如用於數組,只能測出靜態數組的大小,無法檢測動態分配的或外部數組大小。函數外的str是一個靜態定義的數組,因此其大小爲6,函數內的str實際只是一個指向字符串的指針,沒有任何額外的與數組相關的信息,因此sizeof作用於上只將其當指針看,一個指針爲4個字節,因此返回4

 

 

main()

{

  int a[5]={1,2,3,4,5};

   int *ptr=(int *)(&a+1);

printf("%d,%d",*(a+1),*(ptr-1));

}

輸出:2,5

*(a+1)就是a[1]*(ptr-1)就是a[4],執行結果是25

&a+1不是首地址+1,系統會認爲加一個a數組的偏移,是偏移了一個數組的大小(本例是5int

int *ptr=(int *)(&a+1);

ptr實際是&(a[5]),也就是a+5

原因如下:

&a是數組指針,其類型爲 int (*)[5];

而指針加1要根據指針類型加上一定的值,

不同類型的指針+1之後增加的大小不同

a是長度爲5int數組指針,所以要加 5*sizeof(int)

所以ptr實際是a[5]                 

但是prt(&a+1)類型是不一樣的(這點很重要)

所以prt-1只會減去sizeof(int*)

a,&a的地址是一樣的,但意思不一樣,a是數組首地址,也就是a[0]的地址,&a是對象(數組)首地址,a+1是數組下一元素的地址,即a[1],&a+1是下一個對象的地址,即a[5].

 

 

 

函數前加 static 修飾 表明 該函數只能在 所在的 源文件裏調用

 

 

21、對絕對地址0x100000賦值且想讓程序跳轉到絕對地址是0x100000去執行

(unsigned int*)0x100000 = 1234;

首先要將0x100000強制轉換成函數指針,:

(void (*)())0x100000

然後再調用它:

*((void (*)())0x100000)();

typedef可以看得更直觀些:

typedef void(*)() voidFuncPtr;

*((voidFuncPtr)0x100000)();

 

指向函數的指針??

void GetMemory(char **p,int num)

{

    *p=(char *)malloc(num);

}       

int main()

{

    char *str=NULL;

    GetMemory(&str,100);

    strcpy(str,"hello");

    free(str);

    if(str!=NULL)

    {

        strcpy(str,"world");

    }   

    printf("\n str is %s",str);

    getchar();

}   

問輸出結果是什麼?希望大家能說說原因,先謝謝了

輸出str is world

free 只是釋放str指向的內存空間,它本身的值還是存在的.

所以free之後,有一個好的習慣就是將str=NULL.

此時str指向空間的內存已被回收,如果輸出語句之前還存在分配空間的操作的話,這段存儲空間是可能被重新分配給其他變量的,

儘管這段程序確實是存在大大的問題(上面各位已經說得很清楚了),但是通常會打印出world來。

這是因爲,進程中的內存管理一般不是由操作系統完成的,而是由庫函數自己完成的。

當你malloc一塊內存的時候,管理庫向操作系統申請一塊空間(可能會比你申請的大一些),然後在這塊空間中記錄一些管理信息(一般是在你申請的內存前面一點),並將可用內存的地址返回。但是釋放內存的時候,管理庫通常都不會將內存還給操作系統,因此你是可以繼續訪問這塊地址的,只不過。。。。。。。。樓上都說過了,最好別這麼幹。

 

 

sizeof(int)is 4

sizeof(long)is4

sizeof(char)is 4

sizeof(short)is 2

sizeof(double)is 8

sizeof(float)is 4

sizeof (long int )is 4

發佈了61 篇原創文章 · 獲贊 43 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章