楼主发表于:2009-07-24 10:11:03是这样的,去一家公司面试,遇到了一道c语言的题,个人
感觉很怪,以前没见过类似的,然后主考官说这是关于C语言强弱类型转换什么的,我感觉他
自己都不完全清楚,然后回来在网上查到这是英国剑桥大学网上出的计算机题 :
#include <stdio.h>
#define init_employee(X,Y) {(X),(Y),wage_emp}
typedef struct Employee Em;
struct Employee {int hours,salary;int (*wage)(Em*);};
int wage_emp(Em *ths) {return ths->hours*ths->salary;}
#define init_manager(X,Y,Z) {(X),(Y),wage_man,(Z)}
typedef struct Manager Mn;
struct Manager {int hours,salary;int (*wage)(Mn*);int bonus;};
int wage_man(Mn *ths) {return ths->hours*ths->salary+ths->bonus;}
int main(void) {
Mn m = init_manager(40,10,20);
Em *e= (Em *) &m;
printf("%d\n",e->wage(e));
return 0;
}
最后输出是420,可我写的是400,有请高人能详细解释下这题的意思么,为什么函数指针调用
的不是wage_emp,参数都不匹配阿,而且Em *e= (Em *) &m到底有什么意义,因为它后面还有
添加的问题是用C++来重写并说明好处,那它这么实现是想用C实现多态的性质么,总之感觉
很怪,望高人解答!!
-------------------------------
nit_manager时,写入到结构体中的指针就是wage_man,而不是wage_emp,后面虽然&m被强
制转换成了Em*类型,但类型强制转换并不会改变结构体变量中的数据。因此那个函数指针
指向的仍然是wage_man这个函数。
这里运用了一些巧合:虽然wage_emp跟wage_man两个函数的签名是不一样的,但从底层来
看,并无多大区别,参数都是一个四字节的指针,返回值都是int,这就使得它们的底层调
用机制是一样的,函数调用无非是参数压栈、指针跳转这类指令,参数和返回值类型都一
样,调用的指令就肯定是完全一样的。
因此虽然是传递一个Em*类型的参数而实际调用的是wage_man,但由于这些巧合,编译器就
这样被轻而易举地欺骗……,也就是说,最后被实际调用的wage_man仍然把参数当成Mn*,
而实际上它又确确实实是个Mn*,于是也不会出任何问题。
如果用C++来写,由于C++有内置地支持多态的机制,就用不着使用这些令人费解的欺骗编
译器的手法了。
-------------------------------
实际上观察Employee 和Manager 的结构不难发现
Manager 只是比Em