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)计算则不会.