读c语言进阶书籍
个人那本书写的很好。。。我自己记录里面一些东西
假定有下面的函数声明intptr;intfn(int);int(*fp)(int);指出下面的语句是否合法?,为什么?。fp= fn; //正确,将函数fn的地址赋给fpfp= fn(5); //错误,返回给fp的结果不是一个函数地址。fp= &ptr;// 错误,ptr的地址不在程序代码区,两种数据类型不能转换。从上面的例子可以看出:
(1)不能将普通变量的地址赋给函数指针;(2)不能将函数的调用赋给函数指针(3)可以将函数名赋给一个函数指针
函数指针的用途
一旦函数可以通过指针被传递、被记录,这开启了许多应用,特别是下列三者:1. 多态(polymorphism):指用一个名字定义不同的函数,这函数执行不同但又类似的操作,从而实现“一个接口,多种方法”。
2. 多线程(multithreading):将函数指针传进负责建立多线程的API 中:例如Win32 的CreateThread(...pF...)。
3. 回调(call-back):所谓的回调机制就是:「当发生某事件时,自动呼叫某段程序代码」。事件驱动(event-driven) 的系统经常透过函数指针来实现回调机制,例如Win32 的WinProc 其实就是一种回调,用来处理窗口的讯息。
函数指针数组
对于一个复杂的程序,switch语句将非常长。我们可以用函数指针数组来完成。这样非常简单。
可能你用switch 写100多行,用函数指针数组就只要2行 这样就减少大大减少代码时间了。
witch(oper){caseADD:result=add(op1,op2); break;caseSUB:result=sub(op1,op2); break;... }对于一个复杂的计算器,switch语句将非常长。我们可以用函数指针数组来完成。doubleadd(double,double);doublesub(double,double);...double(*oper_func[])(double,double)={add,sub,...};第2个步骤是用下面语句替换前面整条switch语句:result=oper_func[oper](op1,op2);oper从数组中选择正确的函数指针,而函数调用操作符将执行这个函数。
这里可以用宏定义oper 比喻#define ADD 1 #define SUB 2 然后用oper=ADD or SBU 这样程序又简洁又清晰。。
ASIX Window中的函数指针
typedefstructwindow_class{
U8wndclass_id;
STATUS (*create)(char*caption, U32 style, U16 x, U16 y, U16 width, U16 hight, U32 wndid, U32 menu, void **ctrl_str, void *exdata);
STATUS (*destroy)(void*ctrl_str);
STATUS (*msg_proc)( U32 win_id, U16 asix_msg, U32 lparam, void *data, U16 wparam, void *reserved);
STATUS (*msg_trans)(void*ctrl_str, U16 msg_type, U32 areaId, P_U16 data, U32 size, PMSG trans_msg);
STATUS (*repaint)(void*ctrl_str, U32 lparam);STATUS (*move)(void*ctrl_str, U16 x, U16 y, U16 width, U16 hight, void *reserved);
STATUS (*enable)(void*ctrl_str, U8 enable);STATUS (*caption)(void*ctrl_str, char *caption, void *exdata);STATUS (*information)(void*ctrl_str, structasix_window*wndinfo);
}WNDCLASS;
WNDCLASSWindowClass[] = {{WNDCLASS_WIN, wn_create, wn_destroy, wn_msgproc,wn_msgtrans, wn_repaint, NULL,NULL,wn_caption, NULL},{WNDCLASS_BUTTON,Btn_create,Btn_destroy,Btn_msg_proc,Btn_msg_trans,Btn_repaint,NULL,Btn_enable,Btn_caption, NULL},{WNDCLASS_SELECT,sl_create, sl_destroy, sl_msg_proc, sl_msg_trans, sl_repaint,NULL, sl_enable, sl_caption, NULL},{WNDCLASS_SELECTCARD,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL},{WNDCLASS_MENU,menu_create, menu_destroy, menu_msgproc, menu_msgtrans, mn_repaint, NULL, NULL,NULL,NULL},{WNDCLASS_LIST, Lbox_create,Lbox_destroy, Lbox_msgproc, Lbox_msgtrans, lb_repaint, NULL, NULL,NULL,NULL},{WNDCLASS_KEYBD, kbd_create,kbd_destroy,kbd_msgproc, kbd_msgtrans, kbd_repaint, NULL, NULL,NULL,NULL},{WNDCLASS_SCROLL,sb_create,sb_destroy, sb_msgproc,sb_msgtrans, sb_repaint, NULL,sb_enable, NULL,NULL},{WNDCLASS_KEYBAR,kb_create,kb_destroy, kb_msgproc,kb_msgtrans,NULL,NULL, NULL,NULL, NULL},
#ifdefASIX_DEBUG{WNDCLASS_TEST,tst_create, tst_destroy, tst_msgproc, tst_msgtrans, NULL,NULL,NULL,NULL,NULL}#endif};
这上面是好东西啊,我正好需要这个东西。。。。这个数据结构要学习一下啊,呵呵,无意发现。。。。