C的几个简答题

1.C++中有了malloc/free,为什么还需要new/delete?

答:主要是除了控制内存还能执行其他编译器相关操作。malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。对于非内部数据类型的对象而言,只用malloc/free无法满足动态对象的要求——即对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析造函数。

由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析造函数的任务强加于malloc/free。因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。new/delete不是库函数,而是运算符。

 

内部数据类型:编译器本来就认识的,不需要用户自己定义,如int,char,float等;

非内部数据类型:不是编译器本来就认识的,需要用户自己定义才能让编译器识别,如struct,enum,union,class等。

为什么库函数不在编译器控制权限之内?

运算符使用是否正确,编译器在编译扫描分析时就可以判定;

库函数是已编译的代码,编译器不会编译检查,由链接器将库同用户写的代码合成exe文件。

 

综上,对于非内部数据类型,malloc/free能完成的工作是有限的(因为库函数,所以不受编译器控制),而new/delete因为是运算符在编译器控制权限之内,故能完成动态分配/释放内存之外的其他工作,如初始化和清理。

 

2.有两个变量a和b,不用“if”,“?:”,“switch"或其他判断语句,找出两数中间的最大值?

int max = ((a+b)+abs(a-b) ) /2;——纯数学方法!

 

3.在C++程序中调用被C编译后的函数,为什么要加extern"C"?

C++语言支持函数重载,C语言不支持函数重载,函数被C++编译器编译后在库的名字与C语言的不同。

假设某个函数的原型为void foo(int x, inty)。该函数被C编译器编译后与库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。

 

4.return(x&y)+((x^y)>>1))返回值的结果是什么?

(x&y)+((x^y)>>1),把x和y里对应的每一位(指二进制位)都分成三类,每一类分别计算平均值,最后汇总。其中,一类是x,y对应位都是1,用x&y计算其平均值(都是1的时候相与结果才是1——这和1+1的平均值是1是一个效果);一类是x,y中对应位有且只有一位是1,用(x^y)>>1计算其平均值(先提取(第一部分的漏网之鱼),再右移,右移一位相当于除以2);还有一另是x,y中对应位均为0,无须计算。

下面分别说明前两种情况的计算方法:

第一部分,x,y对应位均为1,相加后再除以2还是原来的数,如两个00001111相加后除以2仍得00001111。

第二部分,对应位有且只有一位为1,先用“异或”运算提取出来,然后>>1(右移一位,相当于除以2),即到到第二部分的平均值。

第三部分,对应位均为零,因为相加后再除以二还是0,所以不用计算。

三部分汇总之后就是(x&y)+((x^y)>>1).

这样做可以避免溢出:假设x,y均为unsignedchar型数据(0~255,占用一字节),显然,x,y的平均数也在0~255之间,但如果直接x+y可能会使结果大于255,这就产生溢出,虽然最终结果在255之内,但过程中需要额外处理溢出的那一位,在汇编中就需要考虑这种高位溢出的情况,如果(x&y)+((x^y)>>1)计算则不会.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值