陸志平 胡晨駿
摘要:在根據(jù)不同條件選擇執(zhí)行不同函數(shù)的程序中,if-else if-elses或者witch/case結構需要經過多次匹配且執(zhí)行效率較低。該文對函數(shù)指針進行深入分析與研究,提出了采用函數(shù)指針數(shù)組解決此類問題的觀點,提高了程序的簡潔性與效率。
關鍵詞:函數(shù)指針;數(shù)組;switch/case
中圖分類號:TP311 文獻標識碼:A 文章編號:1009-3044(2015)13-0230-02
Abstract: In the program that perform different functions according to different conditions, the structure of if-else if-else or switch/case need to go through many times and low operating efficiency. This paper makes a deep analysis and research on the function pointer, have brought forward the viewpoint adopt the function pointer array to resolve this kind problem, that have raised program elegance and efficiency.
Key words: function pointer;array;switch/case
在項目開發(fā)中經常會遇到根據(jù)不同條件選擇不同函數(shù)的問題。例如項目中需要調用各自的函數(shù)處理不同類別的信號,這些信號采用統(tǒng)一的編碼表示。如:zyc000XXXXX、zyc001XXXXX等,編碼的3-5位為0-9之間的數(shù)字,線性排列,分別表示不同種類的信號。后面五個字符標識該類別中的不同信號。在編程處理時,一般會想到采用if-else if-else或者switch-case結構來處理[1]。但是當判斷的條件較多時,程序就會變得冗長、復雜,且效率降低。本文研究采用函數(shù)指針解決此類問題,減少冗余代碼,使得代碼更為簡潔、高效[2-3]。
1 函數(shù)指針
C語言的函數(shù)在調用時會在內存中占用一段存儲空間,這段存儲空間有一個起始地址,這個起始地址稱為函數(shù)的入口地址,即函數(shù)的指針[4]。在程序中,函數(shù)一般是通過函數(shù)名來調用的。與數(shù)組名類似,函數(shù)名也代表了函數(shù)的入口地址,是一個指針常量[5]。
指針既然可以指向整型、字符型、數(shù)組等類型,當然也能指向一個函數(shù)。因此可以定義一個指針變量,讓其值等于函數(shù)的入口地址,此指針變量即為指向函數(shù)指針變量[6],其存放的值即為函數(shù)指針。然后可以通過這個指針變量來調用該函數(shù)[7]。
在C語言中,變量必須先定義后使用,指針變量也不例外[8]。函數(shù)指針變量的定義格式為:
類型標識符 (*指針變量名)( [ 形參類型1, 形參類型2,..., 形參類型n ] ) [9]
其中:
類型標識符為指針變量所指向的函數(shù)的返回值類型。形參類型指的是函數(shù)指針所指向函數(shù)的形參的數(shù)據(jù)類型。若是函數(shù)沒有形參,定義時可省略[10]。
例如:
int (*p)(int, int);
本語句定義了一個指向函數(shù)的指針變量,此函數(shù)返回值類型為int類型,有兩個int類型的參數(shù)[11]。
在初始化指針變量時,只需要把函數(shù)名賦值給指針變量即可[12]。使用指針變量調用函數(shù)可以采用如下格式:
(*指針變量名)(實參列表) [13]
例如下列代碼完成了一個函數(shù)指針變量的定義、初始化以及調用函數(shù)的過程:
int max(int x, int y){
/*函數(shù)體*/
}
int main(void){
int a=3,b=4;
int max(int,int); /*max函數(shù)的聲明*/
int (*f) (int x, int y); /*定義一個函數(shù)指針變量f */
f=max; /* 將max函數(shù)的入口地址賦給指針f */
f(a,b); /*通過函數(shù)指針變量f調用max函數(shù) */
}
上述代碼中,在給函數(shù)指針變量f賦值時,是將max函數(shù)的入口地址賦給f,而函數(shù)名max代表的就是函數(shù)的入口地址,所以賦值時max不需要括號和參數(shù),僅需要函數(shù)名即可。賦值后,函數(shù)指針f就指向函數(shù)max的入口地址,通過f(a,b)即完成了函數(shù)max的調用。
2 函數(shù)指針數(shù)組應用研究
單個函數(shù)指針的應用與函數(shù)名類似,但函數(shù)指針數(shù)組在處理具有大量條件與函數(shù)關聯(lián)時具有很大的優(yōu)勢[14]。
如前言中所述,信號為zyc000XXXXX、zyc001XXXXX等字符串數(shù)據(jù),程序接收到傳過來的信號后,取其第3-5位的字符,并將其轉換為十進制整數(shù),其值為0-999,這里將它稱為類型碼,要求每一個類型碼對應一個函數(shù)來進行處理。
首先討論采用switch()來對類型碼進行判斷[15],匹配成功后調用相應的函數(shù),實現(xiàn)方法如下:
witch(i){ /* 假設i為類型碼 */
case 0: fun0(); break;
case 1: fun1 (); break;
…
case 999: fun999 (); break;
default: break;
}
從上述代碼可以看到,這樣判斷的次數(shù)最少為1次,最多為1000次,平均為500次。而且每次接收到信號后都要進行判斷,系統(tǒng)效率極低。
如何提高程序的效率?我們可以將每一個信號的類型碼(0-999)類型綁定一個函數(shù)。程序接收到信號后,根據(jù)其類型碼值0-999便可以直接調用綁定的函數(shù)。而綁定函數(shù)的功能則可以通過函數(shù)指針數(shù)組來完成。
在程序中定義一個1000個元素的函數(shù)指針數(shù)組,并將其元素初始化為定義好的函數(shù)的指針。這樣,類型碼的值對應著函數(shù)指針數(shù)組的下標,從而完成了類型碼與函數(shù)指針的綁定。
實現(xiàn)方法如下:
/* 假設信號字符串為str,其類型碼為整型數(shù)值idata */
#include
int fun0(string str){ …}
int fun1(string str){ …}
…
int fun999(string str){ …}
int main(void){
/* 定義函數(shù)指針數(shù)組并初始化 */
int (*p[1000])(string)={fun1, fun2,…,fun999};
/* 這里的idata為信號的類型碼 */
int type=idata;
/*通過 (*p[ idata ])( str ) 實現(xiàn)綁定函數(shù)的調用*/
(*p[ idata ])( str ) ;
return 0;
}
從上面的方法可以看到,采用函數(shù)指針數(shù)組后,只需要一次調用就可以實現(xiàn)按需調用函數(shù)的功能,可見無論是程序編寫的簡潔性或者程序運行的效率都遠遠高于采用switch-case結構[16]。
3 結束語
函數(shù)指針是C/C++中一個非常重要的知識,但由于其概念較為抽象,使用技巧性強,應用復雜,且如果使用不當,會導致很嚴重的錯誤[17],所以很多人沒有認識到它在程序編寫中的作用。通過本篇介紹,希望大家合理的利用函數(shù)指針,設計出更為簡潔、高效的程序。
參考文獻:
[1] 譚浩強. C程序設計[M]. 北京: 清華大學出版社, 2011: 220-222.
[2] Chow F, Chan S, Kenny R, et al. A new algorithm for partial redundancy elimination based on SSA form[C]// Proc of ACMSIGPLAN Conference on Programming Language Design and Implementation. New York: ACM Press, 1997: 273-286.
[3] Kennedy R, Ruthing O, LIU Shin-ming, et al. Partial redundancy elimination in SSA form[J]. ACM Trans on Programming Language and Systems, 1999, 21(3): 627-630.
[4] 蘇小紅, 王宇穎, 孫志崗. C語言程序設計[M]. 北京: 高等教育出版社, 2011: 264-272.
[5] Reek K A. C和指針[M]. 北京: 人民郵電出版社, 2008: 33-34.
[6] Peter Van, Der LinDer. C專家編程[M]. 北京: 人民郵電出版社, 2008: 230-232.
[7] stephen Prata.C Primer Plus[M]. 北京: 人民郵電出版社, 2005: 236-238.
[8] Kernighan B W, Ritchie D M. C程序設計語言[M]. 北京: 機械工業(yè)出版社, 2004: 79-80.
[9] Harbison III SP, Steele Jr GL[M]. C語言參考手冊. 北京: 機械工業(yè)出版社, 2003: 95-97.
[10] 許永達. C語言指針錯誤的分析及調試[J]. 計算機系統(tǒng)應用,2013,23(3): 153-155.
[11] 古輝, 喬凱旋. C++指針機制與源文件關聯(lián)關系的可視化研究[J]. 計算機系統(tǒng)應用,2012,21(7): 238-238.
[12] 劉宏, 李颯. C語言中用指針指向函數(shù)的方法及其高級處理技巧的研究與應用[J].東北農業(yè)大學學報.1994,25(2):186-189.
[13] 何靈敏, 許翔, 陸慧娟, 等. C++教學中變成習慣的養(yǎng)成[J]. 計算機教育, 2011(9): 64-67
[14] 郭曦, 何炎祥, 張煥國, 等. 一種改進的指針安全分析算法[J]. 武漢大學學報: 理工版, 2010, 56(2): 170-174.
[15] 龔松顯, 董銳, 劉躍宣. 用函數(shù)指針替代Switch/Case語句的程序設計方法[J]. 單片機與嵌入式系統(tǒng)應用, 2014(9): 14-15.
[16] 姚宇峰. 面向軟件可信性的可信指針分析技術綜述[J]. 計算機應用研究, 2012, 29(2): 427-430.