一、問題的提出
早期的數(shù)據(jù)庫編程語言,如dBaseⅢ、Foxbase 2.0等對于變量的定義一般不需要作顯式的說明也可引用,只要求用戶對其進行相應(yīng)的賦值,系統(tǒng)中就可為該變量準(zhǔn)備相應(yīng)的存儲空間,系統(tǒng)中也能認(rèn)同該變量,正是由于我們大多數(shù)編程人員具有這樣的編程經(jīng)驗,在數(shù)據(jù)庫編程時對于變量不作一些說明直接引用,往往會導(dǎo)致一些錯誤的發(fā)生,而這些錯誤在編程調(diào)試中是不易發(fā)現(xiàn)的,特別是局部與全局變量在遞歸中的使用問題;數(shù)據(jù)庫在升級及更新?lián)Q代的過程中,亦然兼容大多數(shù)人對于簡單變量不定義但能使用的這種用法,另一方面更倡導(dǎo)結(jié)構(gòu)化的設(shè)計思想,如果用戶在閱讀VFP提供的一些范例,不難看出它的編程風(fēng)格完全和結(jié)構(gòu)化的編程思想是一致的,
VFP編程中的變量操作
。筆者認(rèn)為站在VFP的角度就應(yīng)該完全按照結(jié)構(gòu)化的思想來設(shè)計程序:如程序結(jié)構(gòu)化、過程函數(shù)中的變量不用或者少用全局變量,內(nèi)部使用的變量一般作局部變量進行定義;當(dāng)然所有這些均建立在可視化的前提下,這是無容置疑的。筆者下面的一道程序正是犯了未定義局部變量而濫用全局變量的毛病。
二、實例
下面是筆者通過在VFP中的插入一個oleCtrol控件來實現(xiàn)將磁盤中的文件目錄保存到一個目錄樹中以實現(xiàn)打開一個目錄及迭起一個目錄的操作,在裝填oleCtrol的數(shù)據(jù)時對于目錄樹宜采用遞歸調(diào)用,其形式可采用深度優(yōu)先搜索法,對于該結(jié)點在插入到oleCtrol后,然后對于與該結(jié)點相鄰的所有結(jié)點為普通結(jié)點直接插入到oleCtrol中,若為子目錄結(jié)點則遞歸調(diào)用該插入子程序(即深度遍歷目錄結(jié)構(gòu))。
下面是有關(guān)將用戶選擇的目錄中的數(shù)據(jù)填入到目錄樹中的一個遞歸程序,其過程叫做filltree(m.path,m.count),其代碼如下:
*procedure filltree(m.path,m.nlevel)
parameters m.path,m.nlevel
local nlvl,DirArr,nTotDir
**由于該處缺少對于程序中的變量I的定義而導(dǎo)致程序不正常運行,改進后該位置增加了對于變量I的定義
**該過程僅需要一個參數(shù),其它參數(shù)可以缺少,對于缺少的參數(shù)進行設(shè)定
m.path=alltrim(m.path)
if (parameters()<2) or (type("m.nlevel")#"N")
nlvl=0
else
nlvl=m.nlevel
endif
lvl=nlvl+1
*將當(dāng)前參數(shù)傳過來的m.path及所處的層數(shù)保存在對象oleControl1中
this.olecontrol1.AddItem(LOWER(m.path))
this.olecontrol1.Indent(m.nlvl-1)=m.nlvl
*列出當(dāng)前目錄下的所有目錄,并排序
DIMENSION DirArr[1,1]
nTotDir=ADIR(DirArr,m.path+"*.","D")
ASORT(DirArr)
*對于當(dāng)前目錄下的所有目錄實施相同的填充目錄樹的方式進行目錄樹的填入
*即對于當(dāng)前目錄下的其它所有目錄均采用filltree進行遞歸調(diào)用的處理
FOR i = 1 TO m.nTotDir
IF DirArr[m.i,1] != '.' AND ATC('D',DirArr[m.i,5])#0
THIS.FillTree(m.path+DirArr[m.i,1]+'\', m.nlvl)
ENDIF
ENDFOR
****過程結(jié)束
其中filltree是該表單form的一個方法程序,通過新建方法來設(shè)定的,filltree中的參數(shù)m.path是借助于命令按鈕Directory傳遞過來的,Directory的Click事件是這樣的,
電腦資料
《VFP編程中的變量操作》(http://m.oriental01.com)。**Directory的命令按扭事件借助于getdir()得到當(dāng)前的路徑
local m.cdir
m.cdir=getdir()
thisform.olecontrol1.clear
thisform.filltree(m.cdir)
在上述程序運行的過程中,只能檢索到一個目錄,且是一個死循環(huán),花了一上午的時間,終于被我檢查出來了,這就是在該過程中對于過程中用到的變量i沒有定義,而該變量i是作為深度優(yōu)先搜索算法中的中間變量,在遞歸調(diào)用返回時應(yīng)恢復(fù)到其調(diào)用遞歸前的狀態(tài),即是借助于局部數(shù)據(jù)區(qū)域保存的數(shù)據(jù),或者說是每一次遞歸調(diào)用時,臨時又分配一個這樣的內(nèi)存變量來保存數(shù)據(jù),遞歸返回時撤消其生存的空間而恢復(fù)父進程的一些變量,可是由于沒有被定義,而對于數(shù)據(jù)庫語言將其作為全程變量來進行處理,該變量的值并不能在遞歸返回時恢復(fù),因而出現(xiàn)死循環(huán),可是對于變量沒有被定義這樣的處理,在VFP中是容許的,但是作為該種版本的數(shù)據(jù)庫系統(tǒng)并不倡導(dǎo)這種處理方式,而這些也正是初次接觸VFP或者是慣于使用Foxbase等語言的同志容易犯的錯誤所在,對于其它的高級語言如Pascal、C等語言,由于其變量要求先定義后引用的限制則不可能出現(xiàn)這種問題。
三、結(jié)束語
筆者是一個學(xué)習(xí)VFP的新手,對于象我這樣一個學(xué)習(xí)VFP的新手來說,我認(rèn)為除了要繼承Foxbase等低級數(shù)據(jù)庫的編程技巧外,更應(yīng)去適應(yīng)高版本的語言系統(tǒng)的一些規(guī)范,如對于VFP中的類的認(rèn)識理解,對于VFP中編程中的一些模塊化的風(fēng)格(在過程或函數(shù)中少用或不用轉(zhuǎn)移語句,對于過程或函數(shù)內(nèi)部的變量應(yīng)加以說明,一般不得使用全程變量)的理解,如上例中由于在方法程序中對于所使用的變量i進行顯示的說明而導(dǎo)致程序嚴(yán)重的錯誤,而這種錯誤一般是不易發(fā)現(xiàn)的,這些錯誤也往往是容易犯的,希望通過此篇文章的闡述,讓讀者以此為戒,不犯同樣的錯誤。