C问题集锦(一)
楼主发表于: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
相关文档:
VB
If MSComm1.PortOpen = True Then MSComm1.PortOpen = False
MSComm1.CommPort = i1
MSComm1.PortOpen = True
MSComm1.InputMode = comInputModeBinary
MSComm1.InBufferCount = 0
& ......
Delphi 与 C/C++ 数据类型对照表
Delphi数据类型C/C++
ShorInt
8位有符号整数
char
Byte
8位无符号整数
BYTE,unsigned short
SmallInt
16位有符号整数
short
Word
16位无符号整数
unsigned short
Integer,LongInt
32位有符号整数
int,long
Cardinal,LongWord/DWORD
32位无符号整数
unsigned long
Int6 ......
这篇文章介绍在LINUX下进行C语言编程所需要的基础知识.在这篇文章当中,我们将会学到以下内容:
源程序编译
Makefile的编写
程序库的链接
程序的调试
头文件和系统求助
1.源程序的编译
在Linux下面,如果要编译一个C语言源程序,我们要使用GNU的gcc编译器. &nb ......
C语言编译全过程
编译的概念:编译程序读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,再由汇编程序转换为机器语言,并且按照操作系统对可执行文件格式的要求链接生成可执行程序。
编译的完整过程:C源程序-->预编译处理(.c)-- ......
1、在cpp文件中调用c文件中实现的函数的时候,需要用extern "C"声明该函数,否则cpp会按名字改编后的
函数名去找该函数而找不到。
cpp文件调用c文件中函数如下:
c文件中有一函数:
void Transfer(int a; char b);
&nbs ......