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