|
|
发表于 2008-4-28 02:14:00
|
显示全部楼层
Re:关于函数指针和共用体的问题
楼主的代码有两大问题:
一: 普通字符串编译器默认类型为const char[],你不能使用char *去指向const char [].(其实就是 const char []无法隐式转换为 char *)
代码应该改为:
struct func_type
{
char m_name[40];
union
{
void (*p1)();
void (*p2)(int);
} m_func;
};
如果要使用char * 那么应该这么初始化结构 更好的做法,如果不改动字符串,应该把
所有的char *和char []改为const char *和 const char [])
char func_name1[] = "print1";
char func_name2[] = "print2";
func_type func_table[] = {
{ func_name1, print1}, //char []类型这里会被编译器转换为 char *
{ func_name2, print2} //char []类型这里会被编译器转换为 char *
};
二: 编译器不能成功编译代码是因为你对union语义理解不正确, union的正确语义应该是同样的数据(内存地址)
表现多种类型.
union的大小为最大的类型,比如: union test { int i; char c;}; //sizeof(test) = 4 bytes
当你初始化union时其他类型会被编译器自动转型为union声明中最大的类型.
比如: test t[] = { 1, '1'}; 编译器会把'1'char 转型为int然后贮存.
char c = t[1]; 这里编译器会把 '1' int 转型为char 然后赋值给 c
基础类型编译器都会隐式强制帮你转换,当遇到复杂类型就需要自己手动转换.
代码改为:
typedef void (*pfvv)();
typedef void (*pfvi)(int);
char func_name1[] = "print1";
char func_name2[] = "print2";
func_type func_table[] = {
{ func_name1, print1},
{ func_name2, (pfvv)print2} //强制类型转换
};
函数指针类型所占用空间是一样的,但是不同类型返回值和参数的函数指针之间是不能隐式转换的,
所以编译器无能为力,你必须手动强制转化才能通过编译.
pfvv pfvv1 = fun_table[0].m_func.p1; //这里取得的默认类型为 void (*pfvv)()
pfvi pfvi1 = fun_table[0].m_func.p2; //这里取得的默认类型为 void (*pfvi)(int)
//注意这里编译器自动为 你转型
备注:如果union所含类型所占的内存空间都是一样的,初始化union的时候则默认储存类型则为第一个声明的类型.这也是楼主原始代码不能编译通过的原因,void (pfvv)()的声明次序在前,所以void (*pfvi)(int)必须转型为void(*pfvv)(),由于编译器不能隐式转换,所以就必须强制类型转换才能通过编译.
|
|