Chinaunix首页 | 论坛 | 博客
  • 博客访问: 94736
  • 博文数量: 41
  • 博客积分: 866
  • 博客等级: 准尉
  • 技术积分: 282
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-22 22:49
文章分类

全部博文(41)

文章存档

2011年(41)

我的朋友

分类: C/C++

2011-11-26 18:01:20

今天在CSDN上发现一个检测C语言功底的帖子,觉得挺好的,我有好几个地方都是第一次见到,学了这么多年的C语言,很惭愧。于是转过来学习一下,认真分析一下。

地址连接:

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

分析:主要考察setjump和longjump这两个函数的作用。从英文字面意思我们可以知道是跳转,程序的非本地跳转。

关于这两个函数的详细介绍可以参考维基百科:

只要知道了这两个函数的功能,就很容易知道本题的答案为:(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
9,The output for this program is: (a) i=4 j=2 (b) i=3 j=2 (c) i=3 j=4 (d) i=3 j=6
int main() {
   
int i=3;
   
int j;
    j
= sizeof(++i+ ++i);
printf("i=%d j=%d", i ,j);
   
return 0;
}
分析:因为sizeof是运算符,不是函数。我们很多时候都将sizeof当成了函数,这是不对的。sizeof只对数据类型进行判定而不是去计算表达式。所以i的值不会改变。关于sizeof我们可以看看MSDN上如何对sizeof进行定义的:
sizeof Operatorsizeof expression The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types). This keyword returns a value of type size_t. The expression is either an identifier or a type-cast expression_r(a type specifier enclosed in parentheses). When applied to a structure type or variable, sizeof returns the actual size, which may include padding bytes inserted for alignment. When applied to a statically dimensioned array, sizeof returns the size of the entire array. The sizeof operator cannot return the size of dynamically allocated arrays or external arrays.
答案 :(c) i=3 j=4
10,The output for this program is: (a) 5 5 5 5 (b) 3 5 3 5 (c) 5 3 5 3 (d) 3 3 3 3
void f1(int *, int);
void f2(int *, int);
void(*p[2]) ( int *, 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);
   
return 0;
}
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;
}
分析:考察函数参数的传递方式,值传递和地址传递。值传递在函数调用后不改变实参,而地址传递在函数调用后改变实参。只要知道这一点,本题就很好解答。f1和f2中的两个参数第一个都是地址传递,第二个都是值传递。
答案: (a) 5 5 5 5
11,The output for this program is: (a) 0 1 2 0 (b) 0 1 2 1 (c) 1 2 0 1 (d) 0 2 1 1
void e(int );
int main() {
   
int a;
    a
=3;
    e(a);
   
return 0;
}

void e(int n) {
   
if(n>0) {
        e(
--n);
        printf(
"%d" , n);
        e(
--n);
    }
}
分析:考察递归函数的调用,调用深度,调用后一级一级的返回。
e(3)  e(2)   e(1)
e(3):                                                  e(2):                                               e(1):
   e(2)                                                         e(1)                                                e(0)
   printf("%d" , n);  //2                                printf("%d" , n);  //1                     printf("%d" , n);  //0 
 e(1)                                                            e(0)                                                e(-1)
答案:
(a) 0 1 2 0
12,type of tmp is 
(a) Pointer to function of having two arguments that is pointer to float 
(b) int 
(c) Pointer to function having two argument that is pointer to float and return int 
(d) None of the above
typedef int (*test) ( float * , float*)
test tmp;
分析:考察函数指针和typedef。函数指针的形式是:数据类型标志符 (指针变量名) (形参列表); 例如:int (*f) (int x);
typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。在编程中使用typedef目的一般有两个,一个是给变量一个易记且意义明确的新名字,另一个是简化一些比较复杂的类型声明。 typedef int (*test) ( float* , float*)  中test是一个函数指针,经过typedef定以后成为一个函数指针的数据类型。所以test tmp中temp是一个指向函数的指针,这个函数返回整型值
答案:(c) Pointer to function having two argument that is pointer to float and return int 
13,The output for this program is: (a) 5 (b) 6 (c) 9 (d) None of the above
intmain() {
   
char*p;
   
charbuf[10]={1,2,3,4,5,6,9,8};
    p
=&((buf+1)[5]);
printf("%d" , *p);
   
return 0;
}
分析:考察数组地址的变化。buf是数组的起始地址,也即第一个元素的地址&buf[0],buf+1就是数组的第二个元素的地址&buf[1],现在要以buf+1作为起始地址,(buf+1)[5] 相当于 buf+1+5 即buf[6]
答案:(c) 9
14,The output for this program is: (a) ab (b) cd (c) ef (d) gh
Void f(char**);
int main() {
   
char * argv[] = { "ab" ,"cd" , "ef" ,"gh", "ij" ,"kl" };
    f( argv );
    
   
return 0;
}
void f( char **p ) {
   
char* t;
    t
= (p+= sizeof(int))[-1];
    printf(
"%s" , t);    
}
分析:数组中存放可以分高地址和低地址两种顺序存放。在调用函数f中 p+=sizeof(int) 相当于 p+=4 此时p指向第五个元素,再取p[-1]就相当于p-=1;此时指向了第四个元素。返回给t即 t =“gh”
答案:(d) gh
15,The output for this program is: (a) 7 (b) 6 (c) 5 (d) 3
#include<stdarg.h>
int ripple ( int , ...);
int main(){
   
int num;
num = ripple ( 3, 5,7); printf( " %d" , num);
   
return 0;
}
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;
}
分析:考察不定参数函数的知识点。
答案:(c) 5
16, The value of j at the end of the execution of the this program is:
 (a) 10 (b) 15 (c) 6 (d) 7
int counter (int i) {
static int count =0;
    count
= count +i;
   
return (count );
}
int main() {
   
int i , j;
   
for (i=0; i <=5; i++)
    j
= counter(i);
   
return 0;
}
分析:主要考察静态变量static,静态变量的生存期是在整个程序结束的时候才结束。内存中的位置:静态存储区(静态存储区在整个程序运行期间都存在)。
答案:(b) 15
阅读(755) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~