C语言面试题库1-3

来源:互联网 发布:阿尔法淘宝下载序列号 编辑:程序博客网 时间:2024/05/29 08:40
1.下面的函数有什么错误:

int square(volatile int *ptr)

{

return *ptr * *ptr;

}

        这段代码有点变态。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:

int square(volatile int *ptr)

{

    int a,b;

    a = *ptr;

    b = *ptr;

    return a * b;

}

       由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:

long square(volatile int *ptr)

{

    int a;

    a = *ptr;

    return a * a;

}

2.下面的代码输出是什么,为什么?

void foo(void)

{

unsigned int a = 6;

int b = -20;

(a+b > 6) puts("> 6") : puts("<= 6");

}

       答案是输出是”>6”。

       原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。因此-20变成了一个非常大的正整数,所以该表达式计算出的结果大于6。这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。

/*有符号数的扩展,只是在符号位前面补充和符号位一样的数*/

/*为了使0经过转变之后,还是0,所以:补码=~源码 + 1*/

3.尽管不像非嵌入式计算机那么常见,嵌入式系统还是有从堆(heap)中动态分配内存的过程的。那么嵌入式系统中,动态分配内存可能发生的问题是什么?

       主要有三种类型:内存泄露、内存碎片和内存崩溃,内存崩溃是内存使用最严重的结果,主要原因有数组访问越界、写已经释放的内存、指针计算错误、访问堆栈地址越界等等。碎片收集的问题,变量的持行时间等等

4.typedef 在C语言中频繁用以声明一个已经存在的数据类型的同义字。也可以用预处理器做类似的事。例如,思考一下下面的例子,那个更好,为什么?

#define dPS struct s *

typedef struct s * tPS;

       答案是:typedef更好。思考下面的例子:

dPS p1,p2;

tPS p3,p4;

第一个扩展为

struct s * p1, p2;

上面的代码定义p1为一个指向结构的指,p2为一个实际的结构,这也许不是你想要的。第二个例子正确地定义了p3和p4两个指针。

5.找错题

 试题1:

void test1()

{

 char string[10];

 char* str1 = "0123456789";

 strcpy( string, str1 );

}

试题2:

 void test2()

{

 char string[10], str1[10];

 int i;

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

 {

  str1[i] = 'a';

 }

 strcpy( string, str1 );

/*没有\0,strcpy停止不了*/

}

 试题3:

voidtest3(char* str1)

{

 char string[10];

 if( strlen( str1 ) <= 10 )//strlen不计算\0

 {

  strcpy( string, str1 );

 }

}

  解答:

  试题1字符串str1需要11个字节才能存放下(包括末尾的’\0’),而string只有10个字节的空间,strcpy会导致数组越界;

  对试题2,如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string,str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10分;

  对试题3,if(strlen(str1)<= 10)应改为if(strlen(str1)< 10),因为strlen的结果未统计’\0’所占用的1个字节。


 

0 0
原创粉丝点击