C语言简答题含有部分我们阶段测试的题目(二)

来源:互联网 发布:淘宝怎么买飞行员燃料 编辑:程序博客网 时间:2024/05/22 04:33
 11、什么是内存操作越界?

答:
所谓内存操作越界,就是指当内存输入超出了预分配空间的大小,就会覆盖该空间之后的一段存储区域,导致系统异常。 

12、什么是内存泄漏?造成内存泄漏的原因有哪些?

答:
内存泄漏也称作“存储渗漏”,用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。即所谓内存泄漏。 简单地说就是申请了一块内存空间,使用完毕后没有释放掉。它的一般表现方式是程序运行时间越长,占用内存越多,最终用尽全部内存,整个系统崩溃。由程序申请的一块内存,且没有任何一个指针指向它,那么这块内存就泄露了。 
②动态分配的内存没有释放,比如
new出一块内存,没有delete掉,相应的内存就会泄露;类没有析构函数,但类的析构函数是系统默认的,局部对象在生存周期结束之后会自动调用的;malloc没有free一般是链表的删除时会出现。 

13、请说出const#define相比,有何优点?

答:
const作用:定义常量、修饰函数参数、修饰函数返回值三个作用。被Const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。 
const的使用方法不仅仅是定义常量,还可有定义常对象,常成员函数,用来限制函数参数,函数返回值等;
const的定义是有变量类型的,而#define只是简单的替换,而不能进行调试;
③编译器永远也看不到你的宏定义,在进入编译器之前,它已经被预处理器替换掉了;
④最基本的,
const#define多了一个类型检查。const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。

14、函数式宏定义和函数调用有什么不同?

答:
(1)宏替换不占运行时间,只占编译时间;而函数调用则占运行时间(分配单元、保留现场、值传递、返回),所以每次执行都要载入所以执行起来比较慢一些。

(2)定义宏的时候不要在宏及其参数之间键入空格,因为宏替换的时候会把你不经意打的空格当作宏的一部分进去。
 

(3)在宏定义中把每个参数都用括号括起来,同时把整个结果也用括号(对于单个表达式的宏,可以使用小括号
(),对于宏定义的复合语句可以使用{}Linux内核中有一个比较好的宏定义,do {…}while(0))括起来,以防止当宏用于一个更大的表达式时可能出现的问题。 

(4)使用宏次数多时,宏展开后源程序长,因为每展开一次都使程序增长,
但是执行起来比较快一点(这也不是绝对的,当有很多宏展开,目标文件很大,执行的时候运行时系统换页频繁,效率就会低下)。而函数调用不使源程序变长。 

(5)函数调用时,先求出实参表达式的值,然后带入形参。而使用带参的宏只是进行简单的字符替换

(6)
函数调用是在程序运行时处理的,分配临时的内存单元;而宏展开则是在编译时进行的,在展开时并不分配内存单元,不进行值的传递处理,也没有返回值的概念。 

(7)
对函数中的实参和形参都要定义类型,二者的类型要求一致,如不一致,应进行类型转换;而宏不存在类型问题,宏名无类型,它的参数也无类型,只是一个符号代表,展开时带入指定的字符即可。宏定义时,字符串可以是任何类型的数据。 

(8) 
调用函数只可得到一个返回值,且有返回类型,而宏没有返回值和返回类型,但是用宏可以设法得到几个结果。 

(9)
函数体内有Bug,可以在函数体内打断点调试。如果宏体内有Bug,那么在执行的时候是不能对宏调试的,即不能深入到宏内部。 

(10)
宏的定义很容易产生二义性,如:定义#define S(a) (a)*(a),代码S(a++),宏展开变成(a++)*(a++)这个大家都知道,在不同编译环境下会有不同结果。  

15C语言中参数传递有什么特点?我们应当注意些什么?

答:
参数传递的特点:
①数值传递:被调用函数中对形参的操作不影响主调用函数中的实参值。 
②地址传递:可以通过被调用函数中对形参的操作来修改主调用函数中的实参值。

     注意事项:用malloc new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL 的内存。 

16goto语句有什么特点?在C语言中对goto的使用有什么注意事项。

答:
   特点:
goto语句会跳跃到编写程序的任意地点

注意事项:goto语句不能跨越变量的定义向前跳转

18、使用swicth的注意事项。

答:

    (1)每个case 语句的结尾不要忘了加break,否则将导致多个分支重叠(除非有意使多个分支重叠)。 
    (2)不要忘记最后那个default 分支。即使程序真的不需要default 处理,也应该保留语句 default : break; 这样做并非多此一举,而是为了防止别人误以为你忘了default 处理。
    (3) 在使用switch语句时,不管case分支中有几条语句,都是用”{}”将其括起来。

19、嵌入式系统中经常要用到的无限循环,你怎样使用C编写死循环呢?

答:
   
①while(1)      ②for(;;)

     {                {

        ;                 

 }                }
 

20typedef unsigned char BYTE#defineSTRING char*;哪个更好一些为什么?

答:
 
typedef unsigned char BYTE更好点。#define只作简单的替换,不作语法检查,而typedef是重命名,不影响定义类型的语法。