C語言測試題第一部分

 今天在CSDN上發現一個檢測C語言功底的帖子,覺得挺好的,我有好幾個地方都是第一次見到,學了這麼多年的C語言,很慚愧。於是轉過來學習一下,認真分析一下。

地址連接:http://topic.csdn.net/u/20110729/12/9973E5A4-A414-4714-871F-905A85612297.html

1,The output for this program is: (a) 3 (b) 5 (c) 0
#include<setjmp.h>
static jmp_buf buf;
int main() {
   
volatileint b;
    b
=3;
   
if(setjmp(buf)!=0) {
        printf(
"%d", b);
        exit(
0);
    }
    b
=5;
    longjmp(buf ,
1);
   
return 0;
}

分析:主要考察setjump和longjump這兩個函數的作用。從英文字面意思我們可以知道是跳轉,程序的非本地跳轉。

關於這兩個函數的詳細介紹可以參考維基百科:http://zh.wikipedia.org/wiki/Setjmp.h#cite_note-macro-0

只要知道了這兩個函數的功能,就很容易知道本題的答案爲:(b) 5
2,The output for this program is: (a) 3 (b) 5 (c) 6 (d) 7

struct node { int a; int b;int c; };
int main() {
   
struct node s= {3, 5,6 };
   
struct node*pt = &s;
    printf(
"%d" ,*(int*)pt);
   
return 0;
}

分析:程序的意思是將一個結構體指針轉換爲整型指針,結構體是由三個整型的變量構成的,存放在內存的位置是連續的。此結構體的大小爲12字節,int型的爲4字節,我們知道在32位機器上面,指針類型佔用4個字節。將結構體類型的指針轉換爲int型指針,那麼int型指針就指向了結構體中第一個整型變量。所以輸出結果爲:(a) 3

3,What function of x and n is compute by this code segment? 
(a) x^n (b) x*n (c) n^x (d) None of the above

int foo ( int x , int n) {
   
int val;
    val
=1;
   
if (n>0) {
       
if (n%2== 1) val= val *x;

   val = val * foo(x*x , n/2);
    }
   
return val;
}
分析:通過遞歸來求x^n,分奇偶次方來求。答案爲:(a) x^n
4,The output for this program is: (a) 2 2 (b) 2 1 (c) 2 5 (d) None of the above
int main() {
   
int a[5]= {1,2,3,4,5};
   
int *ptr = (int*)(&a+1);
    printf(
"%d %d" ,*(a+1),*(ptr-1) );
   
return 0;
}
分析:我們知道數組的名字就是數組的首地址,也即數組第一個元素的地址。a+1就是對應的第二個元素a[1]。對數組名字就行取地址操作&a獲得的是該數組的地址,因爲數組的長度爲5,那麼&a+1就指向了下一個數組,即&a+1就相當於&a[4]+1,所以prt-1 就是&a[4]。
所以答案爲:(c) 2 5
5,The output for this program is: (a) 8 (b) 9 (c) 7 (d) None of the above
void foo(int [][3] );int main(){
   
int a [3][3]= { { 1,2,3} , {4,5,6},{7,8,9}};
    foo(a);
    printf(
"%d" , a[2][1]);
   
return 0;
}
void foo( int b[][3]) {
   
++ b;
    b[
1][1]=9;
}
分析:此題考察二維數組,在C語言中二維數組是按照一維數組來處理,即先存放行然後是列,即前面是行數後面是列數。a[3][3]表示a有三行三列,可以看成是三個一維數組(每個數組有三個元素)構成。數組名字a表示數組第一個元素地址,也是第一行的地址,也就是第一個數組的地址。對a進行++a後變成了第二行,也就是第二個數組的地址,其實++a相當於進行了a=a+3操作。在調用函數foo中,是進行的值傳遞,不改變a的值,只是改變了a中的元素。調用函數的時候進行實參與形成的傳遞,b[][3] =  { { 1,2,3} , {4,5,6},{7,8,9}}; ,當進行++b後,b變成了第二行了,即b[][3] =  { {4,5,6},{7,8,9},{ }}; 此時的b[1][1] = 8,改成了9。調用結束後輸出a[2][1]爲:9。
所以答案爲:(b) 9
6,The output for this program is: (a) c=3 d=3 (b) c=5 d=3 (c) c=3 d=5 (d) c=5 d=5
int main() {
   
int a, b,c, d;
    a
=3;
    b
=5;
    c
=a,b;
    d
=(a,b);
    printf(
"c=%d" ,c);
    printf(
"d=%d" ,d);
   
return 0;
}
分析:此題考察逗號表達式,很少用到。我們知道逗號表達式最終取值是最後一個變量的值,逗號運算符的優先級低於賦值運算符,所以c=a,b; 執行的操作是先將a賦給c,而不是將b賦給c。所以c=3。而d=(a,b); 就不一樣了,逗號表達式加括號了,優先級最高,先計算括號裏面的值,然後將最後的結果賦給d。逗號表達式值取最後一個變量的值b,所以d=b
答案爲: (c) c=3 d=5
7,The output for this program is:(a) 2 3 5 6 (b) 2 3 4 5 (c) 4 5 0 0 (d) None of the above
int main() {
   
int a[][3]= { 1,2,3 ,4,5,6};
   
int (*ptr)[3]=a;
    printf(
"%d %d" ,(*ptr)[1], (*ptr)[2] );
   
++ptr;
    printf(
"%d %d" ,(*ptr)[1], (*ptr)[2] );
   
return 0;
}
分析:主要考察指針數組和數組指針的區別。指針數組是者數組中存放的元素是指針,本質上是一個數組,例如 int *p[2],定義了一個指針數組 ,存放兩個整型的指針。而指針數組是說指針指向一個數組,本質是一個指針,例如 int (*p) [3] ,定義了一個指向一個含有三個元素的數組的指針。
int m =9,int n=10;
int *p[2] ={&m,&n}; //指針數組,數組中有兩個整型指針
printf("%d %d",*p[0],*p[1]); //輸出m和n的值
而本題中
int a[][3]= { 1,2,3 ,4,5,6};  //定義了一個二維數組
int (*ptr)[3]=a;  //定義一個數組指針,指向二維數組a,ptr也就是數組a的首地址
printf(
"%d %d" ,(*ptr)[1], (*ptr)[2] );  //輸出 2 3
 
++ptr;  //指向下一個相當於 ptr = a+3,指向a[1]
printf(
"%d %d" ,(*ptr)[1], (*ptr)[2] );  //輸出 5 6
答案:(a) 2 3 5 6
8,Which of the above three functions are likely to cause problem with pointers 
(a) Only f3 (b) Only f1 and f3 (c) Only f1 and f2 (d) f1 , f2 ,f3
 int *f1(void) {
   
int x =10;
   
return(&x);
}
int *f2(void) {
   
int*ptr;   
    *ptr=10;
   
return ptr;
}
int *f3(void) {
   
int *ptr;
    ptr
=(int*) malloc(sizeof(int));
   
return ptr;
}
分析:f1中返回臨時變量的地址,在函數調用結束後臨時變量已經銷燬。不對。f2中  ptr沒有分配內存空間,直接就賦值返回,不對。f3分配了內存空間,動態分配。可以。
答案:(c) Only f1 and f2
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章