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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值