標籤:http strong os 檔案 資料 art
約定:
1) 下面的測試題中,認為所有必須的標頭檔都已經正確的包含了
2)資料類型
char 一個位元組 1 byte
int 兩個位元組 2 byte (16位系統,認為整型是2個位元組)
long int 四個位元組 4 byte
float 四個位元組4 byet
double 八個位元組 8 byte
long double 十個位元組 10 byte
pointer 兩個位元組 2 byte(注意,16位系統,地址匯流排只有16位)
第1題: 考查對volatile關鍵字的認識
#include<setjmp.h>
static jmp_buf buf;
main()
{
volatile int b;
b =3;
if(setjmp(buf)!=0) //後面加的,第一次返回時等於0,第二次時就不會等於0,buf等於longjmp傳遞給他的,這裡longjmp把1傳遞給了buf
{
printf("%d ", b);
exit(0);
}
b=5;
longjmp(buf , 1);
} 請問,這段程式的輸出是
(a) 3
(b) 5
(c) 0
(d) 以上均不是
第2題:考查類型轉換
main()
{
struct node
{
int a;
int b;
int c;
};
struct node s= { 3, 5,6 };
struct node *pt = &s;
printf("%d" , *(int*)pt);
}
這段程式的輸出是:
(a) 3
(b) 5
(c) 6
(d) 7
第3題:考查遞迴調用
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 (x的n次冪)
(b) x*n(x與n的乘積)
(c) n^x(n的x次冪)
(d) 以上均不是
第4題:考查指標,這道題只適合於那些特別細心且對指標和數組有深入理解的人
main()
{
int a[5] = {1,2,3,4,5};
int *ptr = (int*)(&a+1);
printf("%d %d" , *(a+1), *(ptr-1) );
}
這段程式的輸出是:
(a) 2 2
(b) 2 1
(c) 2 5
(d) 以上均不是
第5題:考查多維陣列與指標
void foo(int [][3] );
main()
{
int a [3][3]= { { 1,2,3} , { 4,5,6},{7,8,9}};
foo(a);
printf("%d" , a[2][1]);
}
void foo( int b[][3])
{
++ b;
b[1][1] =9;
}
這段程式的輸出是:
(a) 8
(b) 9
(c) 7
(d)以上均不對
第6題目:考查逗號運算式
main()
{
int a, b,c, d;
a=3;
b=5;
c=a,b;
d=(a,b);
printf("c=%d" ,c);
printf("d=%d" ,d);
}
這段程式的輸出是:
(a) c=3 d=3
(b) c=5 d=3
(c) c=3 d=5
(d) c=5 d=5
第7題:考查指標數組
main()
{
int a[][3] = { 1,2,3 ,4,5,6};
int (*ptr)[3] =a; //自己加的理解,注意這裡其實進行了兩步,int (*ptr)[3];(*ptr)=a;
printf("%d %d " ,(*ptr)[1], (*ptr)[2] );
++ptr;
printf("%d %d" ,(*ptr)[1], (*ptr)[2] );
}
這段程式的輸出是:
(a) 2 3 5 6
(b) 2 3 4 5
(c) 4 5 0 0
(d) 以上均不對
第8題:考查函數指標
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;
}
上面這3個函數哪一個最可能引起指標方面的問題
(a) 只有 f3
(b) 只有f1 and f3
(c) 只有f1 and f2
(d) f1 , f2 ,f3
第9題:考查自加操作(++)
main()
{
int i=3;
int j;
j = sizeof(++i+ ++i);
printf("i=%d j=%d", i ,j);
}
這段程式的輸出是:
(a) i=4 j=2
(b) i=3 j=2
(c) i=3 j=4
(d) i=3 j=6
第10題:考查形式參數,實際參數,指標和數組
void f1(int *, int);
void f2(int *, int);
void(*p[2]) ( int *, int);
main()
{
int a;
int b;
p[0] = f1;
p[1] = f2;
a=3;
b=5;
p[0](&a , b);
printf("%d\t %d\t" , a ,b);
p[1](&a , b);
printf("%d\t %d\t" , a ,b);
}
void f1( int* p , int q)
{
int tmp;
tmp =*p;
*p = q;
q= tmp;
}
void f2( int* p , int q)
{
int tmp;
tmp =*p;
*p = q;
q= tmp;
}
這段程式的輸出是:
(a) 5 5 5 5
(b) 3 5 3 5
(c) 5 3 5 3
(d) 3 3 3 3
第11題:考查自減操作(--)
void e(int );
main()
{
int a;
a=3;
e(a);
}
void e(int n)
{
if(n>0)
{
e(--n);
printf("%d" , n);
e(--n);
}
}
這段程式的輸出是:
(a) 0 1 2 0
(b) 0 1 2 1
(c) 1 2 0 1
(d) 0 2 1 1
第12題:考查typedef類型定義,函數指標
typedef int (*test) ( float * , float*)
test tmp;
tmp 的類型是
(a) 函數的指標,該函數以 兩個指向浮點數(float)的指標(pointer)作為參數(arguments)
Pointer to function of having two arguments that is pointer to float
(b) 整型
(c) 函數的指標,該函數以 兩個指向浮點數(float)的指標(pointer)作為參數(arguments),並且函數的傳回值類型是整型
Pointer to function having two argument that is pointer to float and return int
(d) 以上都不是
第13題:數組與指標的區別與聯絡
main()
{
char p;
char buf[10] ={ 1,2,3,4,5,6,9,8};
p = (buf+1)[5];
printf("%d" , p);
}
這段程式的輸出是:
(a) 5
(b) 6
(c) 9
(d) 以上都不對
第14題: 考查指標數組的指標
Void f(char**);
main()
{
char * argv[] = { "ab" ,"cd" , "ef" ,"gh", "ij" ,"kl" };
f( argv );
}
void f( char **p )
{
char* t;
t= (p+= sizeof(int))[-1];
printf( "%s" , t);
}
這段程式的輸出是:
(a) ab
(b) cd
(c) ef
(d) gh
第15題:此題考查的是C的變長參數,就像標準函數庫裡printf()那樣,這個話題一般國內大學課堂是不會講到的,不會也情有可原呵呵,
#include<stdarg.h>
int ripple ( int , ...);
main()
{
int num;
num = ripple ( 3, 5,7);
printf( " %d" , num);
}
int ripple (int n, ...)
{
int i , j;
int k;
va_list p;
k= 0;
j = 1;
va_start( p , n);
for (; j<n; ++j)
{
i = va_arg( p , int);
for (; i; i &=i-1 )
++k;
}
return k;
}
這段程式的輸出是:
(a) 7
(b) 6
(c) 5
(d) 3
第16題:考查靜態變數的知識
int counter (int i)
{
static int count =0;
count = count +i;
return (count );
}
main()
{
int i , j;
for (i=0; i <=5; i++)
j = counter(i);
}
本程式執行到最後,j的值是:
(a) 10
(b) 15
(c) 6
(d) 7
詳細參考答案
第1題: (b)
volatile字面意思是易於揮發的。這個關鍵字來描述一個變數時,意味著 給該變數賦值(寫入)之後,馬上再讀取,寫入的值與讀取的值可能不一樣,所以說它"容易揮發"的。
這是因為這個變數可能一個寄存器,直接與外部裝置相連,你寫入之後,該寄存器也有可能被外部裝置的寫操作所改變;或者,該變數被一個中斷程式,或另一個進程
改變了.
volatile 不會被編譯器最佳化影響,在longjump 後,它的值 是後面假定的變數值,b最後的值是5,所以5被列印出來.
setjmp : 設定非局部跳轉 /* setjmp.h*/
Stores context information such as register values so that the lomgjmp function can return control to the statement following the one calling setjmp.Returns 0 when it is initially called.
Lonjjmp: 執行一個非局部跳轉 /* setjmp.h*/
Transfers control to the statement where the call to setjmp (which initialized buf) was made. Execution continues at this point as if longjmp cannot return the value 0.A nonvolatile automatic variable might be changed by a call to longjmp.When you use setjmp and longjmp, the only automatic variables guaranteed to remain valid are those declared volatile.
Note: Test program without volatile qualifier (result may very)
更詳細介紹,請參閱 C語言的setjmp和longjmp
第2題: (a)
結構題的成員在記憶體中的地址是按照他們定義的位置順序依次增長的。如果一個結構體的指標被看成 它的第一個成員的指標,那麼該指標的確指向第一個成員
第3題: (a)
此題目較難.
這個程式的非遞迴版本int what ( int x , int n)
{
int val;
int product;
product =1;
val =x;
while(n>0)
{
if (n%2 == 1)
product = product*val; /*如果是奇數次冪, x(val)
要先乘上一次,;
偶數次冪,最後返回時才會到這裡
乘以1*/
val = val* val;
n = n/2;
}
return product;
}
/* 用二元複乘策略 */
演算法描述
(while n>0)
{
if next most significant binary digit of n( power) is one
then multiply accumulated product by current val ,
reduce n(power) sequence by a factor of two using integer division .
get next val by multiply current value of itself
}
第4題: (c)
a的類型是一個整型數組,它有5個成員
&a的類型是一個整型數組的指標
所以&a + 1指向的地方等同於 a[6]
所以*(a+1) 等同於a[1]
ptr等同 a[6], ptr-1就等同與a[5]
第5題: (b)
題目自身就給了足夠的提示
b[0][0] = 4
b[1][0] = 7
第6題: (c)
考查逗號運算式,逗號運算式的優先順序是很低的,比 賦值(=)的優先順序 低. 逗號運算式的值就是最後一個元素的值
逗號運算式的還有一個作用就是分割函數的參數列表..
E1, E2, ..., En
上面這個表示式的左右是,E1, E2,... En的值被分別計算出來,En計算出來的結構賦給整個逗號運算式c=a,b; / *yields c=a* /
d=(a,b); /* d =b */
第7題: (a)
ptr是一個數組的指標,該數組有3個int成員
第8題: (c)
f1顯然有問題,它返回一個局部變數的指標,局部變數是儲存在stack中的,退出函數後,局部變數就銷毀了,保留其指標沒有意義,因為其指向的stack空間可能被其他變數覆蓋了
f2也有問題, ptr是局部變數,未初始化,它的值是未知的,*ptr不知道指向哪裡了,直接給*ptr賦值可能會覆蓋重要的系統變數,這就是通常說的野指標的一種
第9題: (b)
sizeof 操作符給出其運算元需要佔用的空間大小,它是在編譯時間就可確定的,所以其運算元即使是一個運算式,也不需要在運行時進行計算.( ++i + ++ i )是不會執行的,所以
i 的值還是3
第10題: (a)
很顯然選a.
f1交換*p 和 q的值,f1執行完後, *p 和 q的值的確交換了, 但 q的改變不會影響到 b的改變, *p 實際上就是 a
所以執行f1後, a=b=5
這道題考查的知識範圍很廣,包括typedef自訂類型,函數指標,指標數組
void(*p[ 2 ]) ( int *, int);
定義了一個函數指標的數組p,p有兩個指標元素. 元素是函數的指標,函數指標指向的函數是一個帶2個參數,返回void的函數,所帶的兩個參數是 指向整型的指標,和整型
p[ 0 ] = f1; p[ 1 ] = f2 contain address of function .function name without parenthesis represent address of function Value and address of variable is passed to function only argument that is effected is a (address is passed). Because of call by value f1, f2 can not effect b
第11題: (a)
考查--操作和遞迴調用,仔細分析一下就可以了
第12題: (c)
建議不會的看看C專家編程
從左往有,遇到括弧停下來,將第一個括弧裡的東西看成一個整體
第13題: (c)
考查什麼時候數組就是指標.對某些類型T而言,如果一個運算式是 T[] (T的數組), 這個運算式的值實際上就是指向該數組的第一個元素的指標.所以(buf+1)[5]實際上就是*(buf +6)或者buf[6]
第14題: (b) sizeof(int)的值是2,所以p+=sizeof(int) 指向 argv[2],這點估計大家都沒有什麼疑問
(p+=sizeof(int))[-1] 指向 argv[1],能理解嗎,因為(p+=sizeof(int))[-1] 就相當於 (p+=2)[-1] ,也就是(p+2-1)
第15題: (c)
在C編譯器通常提供了一系列處理可變參數的宏,以屏蔽不同的硬體平台造成的差異,增加程式的可移植性。這些宏包括va_start、 va_arg和va_end等。 採用ANSI標準形式時,參數個數可變的函數的原型聲明是: type funcname(type para1, type para2, ...) 這種形式至少需要一個普通的形式參數,後面的省略符號不表示省略,而是函數原型的一部分。type是函數傳回值和形式參數的類型。
不同的編譯器,對這個可變長參數的實現不一樣 ,gcc4.x中是內建函數.
關於可變長參數,可參閱
http://www.upsdn.net/html/2004-11/26.html
http://www.upsdn.net/html/2004-11/24.html
程式分析
va_list p; /*定義一個變數 ,儲存 函數參數列表 的指標*/
va_start( p , n); /*用va_start宏 初始化 變數p,
va_start宏的第2個參數n ,
是一個固定的參數,
必須是我們自己定義的變長函數的最後一個入棧的參數
也就是調用的時候參數列表裡的第1個參數*/
for (; j<n; ++j) /* j從1開始, 遍曆所有可變參數 */
{
i = va_arg( p , int); /*va_arg取出當前的參數,
並認為取出的參數是一個整數(int) */
for (; i; i &=i-1 ) /*判斷取出的i是否為0*/
++k; /* 如果i不為0, k自加,
i與i-1進行與邏輯運算, 直到i 為0
這是一個技巧,下面會談到它的功能*/
}
當我們調用ripple函數時,傳遞給ripple函數的 參數列表的第一個參數n的值是3 .
va_start 初始化 p士氣指向第一個未命名的參數(n是有名字的參數) ,也就是 is 5 (第一個).
每次對 va_arg的調用,都將返回一個參數,並且把 p 指向下一個參數.
va_arg 用一個類型名來決定返回的參數是何種類型,以及在 var_arg的內部實現中決定移動多大的距離才到達下一個 參數
(; i; i&=i-1) k++ /* 計算i有多少bit被置1 */
5用二進位表示是 (101) 2
7用二進位表示 (111) 3
所以 k 返回 5(2+3),也即本題應該選c
舉個例子,就很好理解了
令 i= 9 = 1001
i-1 = 1000
(i-1) +1 = i
1000
+1
1 001
因為i與i-1的最右邊的那位(最低位) 肯定是不同,如果i1,i-1肯定是0,反之亦然. i & i-1 這個運算,在二相補的數字系統中,將會 消除最右邊的1位
第16題: (b) 答案是 (b) 相傳高斯小學一年級的時候就會做這類等比數列的題目了.這道題考查的是靜態變數的知識,當每次調用完函數之後,靜態變數的值不會丟失,這與棧中的臨時局部變數明顯不同的地方. 所以,第一次調用counter(0)之後,count =0 第二次調用 counter(1)後 count = 0+1; 第三次調用 counter(2) count = 1+2; /* count = count +i */ 第四次調用 counter(3) count = 3+3; 第五次調用 counter(4) count = 6+4; 第六次調用 counter(5) count = 10+5;