国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

減少后置自增自減運(yùn)算符非預(yù)期結(jié)果的研究

2016-01-20 03:17張合花齊永奇
關(guān)鍵詞:程序員表達(dá)式字符

張合花, 齊永奇

(1.鄭州大學(xué) 物理工程學(xué)院, 鄭州 450001; 2.華北水利水電大學(xué) 機(jī)械學(xué)院, 鄭州 450045)

減少后置自增自減運(yùn)算符非預(yù)期結(jié)果的研究

張合花1, 齊永奇2

(1.鄭州大學(xué) 物理工程學(xué)院, 鄭州 450001; 2.華北水利水電大學(xué) 機(jī)械學(xué)院, 鄭州 450045)

摘要:在VC 6.0中調(diào)用函數(shù)時(shí),如果實(shí)際參數(shù)表達(dá)式中使用了后置自增、自減運(yùn)算符,發(fā)布版的運(yùn)行結(jié)果可能不同于調(diào)試版的預(yù)期。本文在分析問(wèn)題構(gòu)成條件的基礎(chǔ)上,選擇編寫Add-in類型的程序來(lái)發(fā)現(xiàn)這種問(wèn)題并提醒程序員修改源程序,并在討論有關(guān)注意事項(xiàng)后列出了主要開發(fā)步驟。所開發(fā)的Add-in程序可自動(dòng)分析VC 6.0活動(dòng)項(xiàng)目中的所有源文件和頭文件,檢查是否存在這種問(wèn)題,從而降低出現(xiàn)非預(yù)期結(jié)果的可能性。

關(guān)鍵詞:自增運(yùn)算符;自減運(yùn)算符;調(diào)試版;發(fā)行版;Add-in;VC 6.0

由于高版本VC軟件的局限性,VC 6.0仍然是功能最強(qiáng)大、使用范圍最廣泛的軟件開發(fā)工具[1]。它的一個(gè)重要功能是可以在調(diào)試版中單步執(zhí)行和跟蹤,排除算法錯(cuò)誤后再生成小而快的發(fā)布版可執(zhí)行文件[2]。目前,許多高校用它作為C/C++的教學(xué)平臺(tái),程序員也用它進(jìn)行各種各樣的應(yīng)用開發(fā)。C/C++的自增、自減運(yùn)算符具有簡(jiǎn)便、高效的特點(diǎn),常被用來(lái)提高程序的運(yùn)行速度。

使用自增、自減運(yùn)算符的主要問(wèn)題在于當(dāng)它被用于復(fù)雜表達(dá)式的時(shí)候會(huì)降低可移植性。這是因?yàn)闃?biāo)準(zhǔn)C/C++沒(méi)有規(guī)定子表達(dá)式的求值順序,而允許各編譯系統(tǒng)自己安排[3-5]。我們?cè)趯?shí)踐中發(fā)現(xiàn),在VC 6.0中調(diào)用函數(shù)時(shí),如果實(shí)際參數(shù)表達(dá)式中使用了后置自增、自減運(yùn)算符,并且受該運(yùn)算符作用的對(duì)象在多個(gè)實(shí)際參數(shù)表達(dá)式中同時(shí)出現(xiàn),那么發(fā)布版的運(yùn)行結(jié)果可能與調(diào)試程序時(shí)的預(yù)期結(jié)果不相同。為此,本文用VC 6.0開發(fā)了一個(gè)能夠?qū)υ闯绦蜻M(jìn)行自動(dòng)分析的Add-in程序。該程序一旦發(fā)現(xiàn)這種情況,就會(huì)提醒程序員修改源程序。

1問(wèn)題及構(gòu)成條件

1.1問(wèn)題

我們用VC 6.0新建了一個(gè)控制臺(tái)類型的項(xiàng)目,項(xiàng)目名為PostfixError。其中有一個(gè)名字為Postfix.cpp的源文件,文件內(nèi)容如下:

#include

void func(int i,int j){

cout<<“i =”<

void main(){ int a = 1; func(a,a--); }

在調(diào)試版下運(yùn)行程序,輸出為:

i=1,j=1

而在發(fā)布版下,輸出為:

i=0,j=1

顯然二者存在差別,但是在兩個(gè)版本下進(jìn)行編譯、鏈接時(shí)均沒(méi)有任何錯(cuò)誤或警告。將自減運(yùn)算符改為自增運(yùn)算符后,問(wèn)題同樣存在。

程序員往往在調(diào)試版中調(diào)試算法,如果運(yùn)行結(jié)果符合預(yù)期,則認(rèn)為算法正確,發(fā)布程序時(shí)往往不再全面測(cè)試運(yùn)行結(jié)果。而且對(duì)于復(fù)雜的源程序來(lái)說(shuō),即使是調(diào)試版,也很難進(jìn)行全面的測(cè)試。這就可能產(chǎn)生錯(cuò)誤的程序運(yùn)行結(jié)果。

1.2問(wèn)題的構(gòu)成條件

實(shí)踐發(fā)現(xiàn),在VC 6.0中使用自增、自減運(yùn)算符時(shí),調(diào)試版與發(fā)布版的運(yùn)行結(jié)果大多數(shù)情況下相同,僅當(dāng)同時(shí)滿足以下條件時(shí)才可能出現(xiàn)不同:①自增或自減運(yùn)算符出現(xiàn)在函數(shù)調(diào)用的實(shí)際參數(shù)表達(dá)式中;②該運(yùn)算符為后置的而非前置的;③所調(diào)用的函數(shù)具有至少2個(gè)形式參數(shù),并且為全局函數(shù)而非成員函數(shù);④該運(yùn)算符的作用對(duì)象至少在所調(diào)用函數(shù)的2個(gè)實(shí)際參數(shù)表達(dá)式中同時(shí)出現(xiàn)。

2解決方案及有關(guān)事項(xiàng)

2.1用Add-in查找問(wèn)題

文獻(xiàn)[6]列舉、比較了3 條可以用來(lái)與VC 6.0交互的途徑,并指出編寫Add-in類型的程序是與VC 6.0交互的最好選擇。在Add-in程序中可以對(duì)VC 6.0活動(dòng)項(xiàng)目中的所有源文件和頭文件進(jìn)行分析,查找各種各樣的問(wèn)題。它已經(jīng)被成功地用來(lái)減少重復(fù)聲明復(fù)合類型可能帶來(lái)的風(fēng)險(xiǎn)[6]以及使用goto語(yǔ)句可能出現(xiàn)的死循環(huán)[7]。因此,我們可選擇編寫Add-in類型的程序來(lái)查找符合上述條件的情況,發(fā)現(xiàn)問(wèn)題時(shí)輸出警告信息。

2.2確定源程序分析時(shí)機(jī)

Add-in程序以動(dòng)態(tài)鏈接庫(kù)的形式存在,無(wú)法在Windows中直接運(yùn)行,卻可以在VC 6.0中加載并運(yùn)行。VC 6.0根據(jù)已經(jīng)發(fā)生或即將發(fā)生的事件調(diào)用Add-in程序中的不同函數(shù),實(shí)現(xiàn)與Add-in程序的交互。這些事件包括打開或者關(guān)閉文檔、即將執(zhí)行Build菜單命令或執(zhí)行完畢Build菜單命令等。因此,Add-in程序可選擇不同的時(shí)機(jī)對(duì)源程序進(jìn)行分析。但是文件分析非常復(fù)雜,為了避免諸如語(yǔ)法錯(cuò)誤等造成的分析困難,一般選擇在源程序無(wú)編譯和鏈接錯(cuò)誤時(shí)對(duì)其進(jìn)行分析。

為了僅處理屬于源程序的文件,并且不產(chǎn)生遺漏,還應(yīng)該在分析之前由Add-in程序通知VC 6.0,讓其保存程序員針對(duì)項(xiàng)目所做的改動(dòng),包括添加和刪除文件等。這是因?yàn)槟J(rèn)情況下執(zhí)行Build菜單命令時(shí)僅自動(dòng)保存針對(duì)文件內(nèi)容所做的改動(dòng)。

2.3準(zhǔn)確查找和定位

(1)發(fā)現(xiàn)問(wèn)題時(shí)給出的警告信息應(yīng)該完整和準(zhǔn)確。因?yàn)橥粋€(gè)函數(shù)可能在多處使用不同形式的實(shí)際參數(shù)調(diào)用,所以當(dāng)發(fā)現(xiàn)問(wèn)題時(shí)僅給出函數(shù)調(diào)用表達(dá)式及其所在文件的名字是不夠的,還必須指出問(wèn)題出現(xiàn)在哪一行以及哪個(gè)或者哪些變量存在問(wèn)題,才有助于程序員迅速解決問(wèn)題。

(2)分析文件時(shí)需要排除那些不滿足條件的情況,以便盡量避免誤報(bào)。我們很容易判定變量情況是否滿足問(wèn)題構(gòu)成條件①③④,但是很難判定是否滿足條件②。這是因?yàn)闂l件②的判定依據(jù)是該運(yùn)算符的左側(cè)存在作用對(duì)象,并且該作用對(duì)象為左值表達(dá)式,而左值表達(dá)式的提取與判定非常困難。因此,目前僅限于處理變量(包括數(shù)組元素,下同),即只要該運(yùn)算符左側(cè)為變量,就認(rèn)為它是后置的。

(3)分析文件時(shí)需要避免字符串或注釋中存在符合條件的內(nèi)容而產(chǎn)生誤報(bào),同時(shí)避免將其他內(nèi)容當(dāng)作字符串或注釋而產(chǎn)生漏報(bào)。這可以通過(guò)簡(jiǎn)化字符串和注釋來(lái)實(shí)現(xiàn)。但是,簡(jiǎn)化只能在內(nèi)存中進(jìn)行,不能改變?cè)瓋?nèi)容。為了方便簡(jiǎn)化字符串和注釋,通常還需簡(jiǎn)化字符常量。在所有這些處理中,均不能改變行序號(hào),以免在給出行序號(hào)時(shí)出錯(cuò)。

3實(shí)現(xiàn)解決方案的主要步驟

由于Add-in程序的代碼較長(zhǎng),這里僅給出主要開發(fā)步驟及實(shí)現(xiàn)的功能。

3.1創(chuàng)建Add-in項(xiàng)目

在VC 6.0中執(zhí)行File/New菜單命令,彈出對(duì)話框。在Projects選項(xiàng)卡的列表框中選擇DevStudio Add-in Wizard類型,在項(xiàng)目名編輯框中輸入項(xiàng)目名FindPostfixError。點(diǎn)擊OK按鈕,再?gòu)棾鰧?duì)話框。取消復(fù)選框Provides a toolbar的選中狀態(tài),使其只能自動(dòng)運(yùn)行,以免有錯(cuò)誤時(shí)被人工運(yùn)行。確保復(fù)選框Responds to Developer Studio events處于選中狀態(tài),使其響應(yīng)VC 6.0的事件,以便在正確的時(shí)機(jī)自動(dòng)運(yùn)行。點(diǎn)擊Finish按鈕,再點(diǎn)擊OK按鈕,完成Add-in項(xiàng)目的創(chuàng)建。

3.2保存項(xiàng)目改動(dòng)

在工作區(qū)的ClassView面板上展開樹狀類視圖,可以找到類中類XApplicationEvents的成員函數(shù)BuildFinish()。在該函數(shù)中,當(dāng)其形式參數(shù)nNumErrors為0時(shí)對(duì)源程序中的文件進(jìn)行分析,才符合前述分析時(shí)機(jī)的要求。這是因?yàn)閂C 6.0執(zhí)行Build菜單命令之后才自動(dòng)調(diào)用該函數(shù),而nNumErrors的值為0說(shuō)明沒(méi)有編譯、鏈接錯(cuò)誤。

在分析文件之前通過(guò)數(shù)據(jù)成員m_pCommands調(diào)用成員函數(shù)GetApplicationObject(),獲得指向VC 6.0的Application對(duì)象指針。通過(guò)該指針調(diào)用成員函數(shù)ExecuteCommand()來(lái)執(zhí)行WorkspaceSave命令,讓VC 6.0保存程序員針對(duì)項(xiàng)目的改動(dòng)。

3.3簡(jiǎn)化文件內(nèi)容

通過(guò)上述Application對(duì)象指針調(diào)用成員函數(shù)get_ActiveProject(),獲得指向活動(dòng)項(xiàng)目的指針。通過(guò)活動(dòng)項(xiàng)目指針調(diào)用成員函數(shù)get_FullName(),獲得擴(kuò)展名為dsp的項(xiàng)目信息文件的全名。根據(jù)此文件的內(nèi)容獲得活動(dòng)項(xiàng)目中所有文件的全名。根據(jù)文件的擴(kuò)展名篩選出源文件和頭文件,將其內(nèi)容讀入內(nèi)存,并在內(nèi)存中進(jìn)行簡(jiǎn)化。

(1)將最前面的字符設(shè)為當(dāng)前字符。

(2)如果該字符為單引號(hào)則轉(zhuǎn)到(3),如果該字符為雙引號(hào)則轉(zhuǎn)到(4),如果該字符及其后字符均為斜杠則轉(zhuǎn)到(5),如果該字符為斜杠且其后字符為星號(hào)則轉(zhuǎn)到(6)。除此之外,將下一字符設(shè)為當(dāng)前字符繼續(xù)進(jìn)行判斷,直到處理完所有字符。

(3)說(shuō)明正在處理的字符常量,向后搜索與其配對(duì)的單引號(hào),并將它們之間的內(nèi)容刪除。之后將配對(duì)的單引號(hào)后面的字符設(shè)為當(dāng)前字符并返回(2)。

(4)說(shuō)明正在處理的字符串常量,向后搜索與其配對(duì)的雙引號(hào),并將它們之間的內(nèi)容刪除。之后將配對(duì)的雙引號(hào)后面的字符設(shè)為當(dāng)前字符并返回(2)。

(5)說(shuō)明正在處理的以雙斜杠作為起始標(biāo)記的注釋,刪除雙斜杠及其后被注釋掉的內(nèi)容。之后將注釋內(nèi)容結(jié)束位置所在行的換行符設(shè)為當(dāng)前字符并返回(2)。

(6)說(shuō)明正在處理的以/*作為起始標(biāo)記和以*/作為結(jié)束標(biāo)記的注釋塊,刪除/*和*/以及它們之間的內(nèi)容。之后將注釋結(jié)束標(biāo)記之后的字符設(shè)為當(dāng)前字符并返回(2)。

需要說(shuō)明的是,以上處理中皆不能刪除表示文件內(nèi)容換行的換行符,而字符常量、字符串常量和兩種形式的注釋都可能跨行。

3.4查找問(wèn)題

對(duì)經(jīng)過(guò)上述簡(jiǎn)化處理的內(nèi)存進(jìn)行處理,查找可能存在問(wèn)題的自增、自減運(yùn)算符。

(1)將最前面的字符設(shè)為起始位置。

(2)從起始位置向后搜索自增、自減運(yùn)算符。如果找到了,就記錄其位置并轉(zhuǎn)到(3),否則結(jié)束。

(3)從該運(yùn)算符的左側(cè)字符向前搜索未配對(duì)的左圓括號(hào),遇到分號(hào)或花括號(hào)則停止。如果找到了,就記錄其位置并轉(zhuǎn)到(4),否則說(shuō)明它所處的表達(dá)式不是函數(shù)調(diào)用表達(dá)式,需轉(zhuǎn)到(8)。

(4)提取左圓括號(hào)至該運(yùn)算符左側(cè)字符之間的內(nèi)容,并在提取內(nèi)容中從后向前提取變量名。如果提取成功,說(shuō)明是后置的,則記錄變量名并轉(zhuǎn)到(5),否則需轉(zhuǎn)到(8)。

(5)從該運(yùn)算符的右側(cè)字符向后搜索未配對(duì)的右圓括號(hào),遇到分號(hào)或花括號(hào)則停止。如果找到了,就記錄其位置并轉(zhuǎn)到(6),否則說(shuō)明它所處的表達(dá)式不是函數(shù)調(diào)用表達(dá)式,則轉(zhuǎn)到(8)。

(6)提取上述左圓括號(hào)至右圓括號(hào)之間的內(nèi)容,然后在提取的內(nèi)容中搜索(4)中記錄的變量名并記錄每次出現(xiàn)的位置。搜索時(shí)需要注意它不能是另一個(gè)標(biāo)識(shí)符的一部分。如果變量名出現(xiàn)次數(shù)小于2,則轉(zhuǎn)到(8),否則在任意兩相鄰位置之間搜索逗號(hào)。如果找到了,則轉(zhuǎn)到(7),否則說(shuō)明該變量沒(méi)有在多個(gè)實(shí)際參數(shù)表達(dá)式中同時(shí)出現(xiàn),轉(zhuǎn)到(8)。

(7)在左圓括號(hào)之前提取函數(shù)名。如果提取失敗,說(shuō)明這一對(duì)圓括號(hào)不是函數(shù)調(diào)用運(yùn)算符,需轉(zhuǎn)到(8),否則檢查函數(shù)名前面是否為點(diǎn)運(yùn)算符或箭頭運(yùn)算符。如果是,則說(shuō)明調(diào)用的函數(shù)為成員函數(shù),也轉(zhuǎn)到(8),否則提取完整的函數(shù)調(diào)用表達(dá)式并將其記錄到鏈表,同時(shí)記錄該函數(shù)名所在行的序號(hào)、(4)中記錄的變量名及所處理文件的名字。

(8)將自增或自減運(yùn)算符的右側(cè)字符設(shè)為起始位置,然后返回(2)。

需要說(shuō)明的是,以上所有搜索都必須在有效范圍內(nèi)進(jìn)行,搜索自增或自減運(yùn)算符、提取變量名或函數(shù)名時(shí)皆應(yīng)考慮可能存在續(xù)行問(wèn)題。

3.5輸出警告信息

如果經(jīng)過(guò)上述處理得到的鏈表不為空,則需要先檢查有沒(méi)有相同項(xiàng)。如果有就合并,以免重復(fù)報(bào)告。然后,以對(duì)話框的形式發(fā)出警告,提醒程序員注意。最后,還要清除鏈表,以便在下次執(zhí)行Build菜單命令時(shí)不受以前的影響。

4Add-in的運(yùn)行

對(duì)于Add-in 類型的FindPostfixError項(xiàng)目,執(zhí)行Build菜單命令,生成動(dòng)態(tài)鏈接庫(kù)文件。然后,執(zhí)行Tools/Customize菜單命令,在Add-ins and Macro Files選項(xiàng)卡上點(diǎn)擊Browse按鈕找到該文件,VC 6.0將自動(dòng)地注冊(cè)并啟用它,讓其響應(yīng)VC 6.0的事件。因此,一旦完成Add-in程序的開發(fā),就可以將其應(yīng)用到任何安裝了VC 6.0的計(jì)算機(jī)上,幫助程序員降低程序出錯(cuò)的可能性。

打開控制臺(tái)類型的PostfixError項(xiàng)目,執(zhí)行Build菜單命令,將彈出圖1所示的對(duì)話框。這說(shuō)明所編寫的Add-in程序發(fā)現(xiàn)了PostfixError項(xiàng)目中存在著發(fā)布版運(yùn)行結(jié)果不同于調(diào)試版的可能性,并給出了詳細(xì)信息,包括文件名、函數(shù)調(diào)用表達(dá)式、問(wèn)題變量及其所在行的序號(hào)等。

圖1 發(fā)現(xiàn)問(wèn)題時(shí)彈出的對(duì)話框

運(yùn)行結(jié)果表明,Add-in程序在多數(shù)情況下,能夠發(fā)現(xiàn)使用后置自增、自減運(yùn)算符時(shí)可能存在問(wèn)題的函數(shù)調(diào)用表達(dá)式。

5結(jié)語(yǔ)

所開發(fā)的Add-in程序能夠自動(dòng)地尋找在VC 6.0中使用自增、自減運(yùn)算符時(shí)有可能出現(xiàn)非預(yù)期結(jié)果的地方,有助于及時(shí)發(fā)現(xiàn)問(wèn)題,避免造成不良后果。因此,它可以為廣大學(xué)生和工程技術(shù)人員學(xué)習(xí)、掌握和運(yùn)用VC 6.0,進(jìn)行程序設(shè)計(jì)提供幫助。在實(shí)踐中,需要設(shè)法避免自增、自減運(yùn)算符左側(cè)的作用對(duì)象為變量及數(shù)組元素之外的左值表達(dá)式時(shí)出現(xiàn)的漏報(bào)現(xiàn)象。

參考文獻(xiàn):

[1]王育堅(jiān).Visual C++面向?qū)ο缶幊探坛蘙M].北京:清華大學(xué)出版社,2003.

[2]王華.VC++ 6.0 Release和Debug的不同[J].科技信息,2010(11):475.

[3]譚浩強(qiáng).C程序設(shè)計(jì)(第四版)[M].北京:清華大學(xué)出版社,2010:366-367.

[4]邢莉莉.解析C語(yǔ)言中自增運(yùn)算符問(wèn)題[J].科技風(fēng),2009(20):8.

[5]黃玉蘭.有關(guān)C語(yǔ)言輸出函數(shù)中的自增自減運(yùn)算符在不同編譯環(huán)境中的探討[J].科技致富向?qū)?2013(20):26-27.

[6]張全法,齊永奇.用Add-in提高VC 6.0集成開發(fā)環(huán)境的查錯(cuò)能力研究[J].中原工學(xué)院學(xué)報(bào),2009,20(3):47-50.

[7]張全法,陳倩.用Add-in減少VC 6.0中g(shù)oto語(yǔ)句使用錯(cuò)誤的研究[J].中原工學(xué)院學(xué)報(bào),2013,24(2):57-60.

(責(zé)任編輯:王長(zhǎng)通)

Study on Reducing Unexpected Result of Postfix

Increment or Decrement Operator

ZHANG He-hua1, QI Yong-qi2

(1. Zhengzhou University, Zhengzhou 450001;

2. North China University of Water Resources and Electric Power, Zhengzhou 450045, China)

Abstract:When developing programs with VC 6.0, if postfix increment or decrement operator is used in actual argument expression of function, the running result of release configuration may be unexpectedly different from that of debug configuration. Based on analyzing the conditions under which this kind of problem will appear, chosen Add-in to find this kind of problem for notifying the programmer to modify its program, discussed some special questions in practice, and given the main steps in developing the Add-in. The Add-in can be used to analyze all source files and header files of the active project in VC 6.0 to determine if there is this kind of problems, thus the probability of producing unexpected result is reduced.

Key words:increment operator; decrement operator; debug configuration; release configuration; Add-in; VC 6.0

文章編號(hào):1671-6906(2015)01-0091-04

作者簡(jiǎn)介:朱登雷(1986-),男,河南安陽(yáng)人,碩士生。

基金項(xiàng)目:國(guó)家自然科學(xué)基金項(xiàng)目(51077134)

收稿日期:2014-03-21

中圖分類號(hào):TP311.52

文獻(xiàn)標(biāo)志碼:ADOI:10.3969/j.issn.1671-6906.2015.01.022

猜你喜歡
程序員表達(dá)式字符
為了讓媽媽看懂地圖,一位“野生程序員”做了個(gè)小程序
靈活選用二次函數(shù)表達(dá)式
怎樣成為一名優(yōu)秀程序員
論高級(jí)用字階段漢字系統(tǒng)選擇字符的幾個(gè)原則
表達(dá)式轉(zhuǎn)換及求值探析
字符代表幾
一種USB接口字符液晶控制器設(shè)計(jì)
圖片輕松變身ASCⅡ藝術(shù)畫
淺析C語(yǔ)言運(yùn)算符及表達(dá)式的教學(xué)誤區(qū)
程序員之子