999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

剖析C語言自增運算規(guī)律

2017-11-28 13:07:09李云超
科技創(chuàng)新導報 2017年27期

李云超

摘 要:C語言中提供的自增運算符能讓程序的書寫更加簡便和靈活,但如果運用不當也會使 程序的運行結果與預期大相徑庭,再者,現(xiàn)在的教程中并未從不同編譯器的編譯執(zhí)行角度進行深入剖析,使得初學者對一些語句有諸多困惑。本文通過實驗,利用不同的環(huán)境編寫調試程序,并對運行結果進行反匯編分析,總結出自增運算符在不同編譯環(huán)境中的運算規(guī)律以及在教學過程中的注意事項。

關鍵詞:C語言 自增 反匯編

中圖分類號:TN925 文獻標識碼:A 文章編號:1674-098X(2017)09(c)-0143-03

Abstract: The auto-increasing operator in C language can make writing more convenient and flexible, but it can also make the result different with expected if used undeserved, moreover, the tutorials do not analyze deeply in the angle of different compliers comping and executing, and that makes beginners be confused with some codes. This article analyze the result with disassembling in different compliers, then conclude the rules of auto-increasing and notices in the teaching process.

Key Words: C language; Auto-increasing; Disassemble

C語言歷經(jīng)了幾十年,成為經(jīng)典的編程語言,憑借語句的精煉、語法的靈活、對系統(tǒng)環(huán)境要求低、擁有較高的執(zhí)行效率而風靡整個世界,再經(jīng)過歷代改進,C語言發(fā)展至今非但未被淘汰,更是廣泛的應用于各種生產(chǎn)環(huán)境中,并且早已成為計算機專業(yè)學生的入門語言。

作為語句精煉的語言,比早期的匯編語言簡單了很多,一條語句能表示多個運算步驟或者多次寄存器變化,例如自增語句i++,能夠在參加其他運算的同時對本身值進行增加1而又不用增加額外的語句。但是如此精煉的語句卻在實際生產(chǎn)環(huán)境中會產(chǎn)生歧義導致嚴重的后果,這么說并不是說自增語句是洪水猛獸,而是由于C語言應用的場景太廣泛,早期發(fā)展標準尚未成形,不同編譯器廠商在語句執(zhí)行順序上尤其是復雜語句不盡相同,例如自增語句并列使用的時候,不同編譯器對它的解析方式會有不同:(++i)+(++i)+(++i),在不同的編譯器計算出的結果是不同的:在VC6.0中結果為10;在VC2012中結果為12;在TurboC中結果是9。那為什么會出現(xiàn)如此大的結果差異呢?首先了解一下自增運算符的運算規(guī)則。

1 自增運算符的運算規(guī)則

自增運算的規(guī)則:自增運算符是一元運算符,它的作用是使變量的值增1。運算符出現(xiàn)在變量的前面稱為前綴運算符,運算符出現(xiàn)在變量的后面稱為后綴運算符。前綴自增運算符在程序執(zhí)行過程中遵循“先自增后運算”的規(guī)則,后綴自增運算符遵循“先運算后自增”的規(guī)則。同理,自減運算符也是一樣[1]。下面用兩個簡單的實驗來實際運行一下自增運算符:

實驗1:

int main( ){

int a=8,b;

b=a++; /*后綴形式*/

printf(“a=%d, b=%d ”,a,b);

return 0;

}

實驗2:

int main( ){

int a=8,b;

b = ++a; /*前綴形式*/

printf(“ a=%d,b=%d”,a,b);

return 0;

}

在實驗1中,b = a++; 相當于如下兩條語句:b = a; 和a=a+1; 即先將a的初始值8賦值給b,此時b的值即為8,然后a自增1。執(zhí)行結果是:a=9,b=8。

在實驗2中,b = ++a; 相當于如下兩條語句:a = a+1; 和 b=a; 即a先做自增1操作,然后再將a自增后的值9賦值給b,此時b的值即為9。執(zhí)行結果是:a=9,b=9。

也就是說對于自增符號++在變量后面的操作 a++,是先做其他運算,再對a進行自增運算;而自增符號++在變量前面的操作++a,是先對a進行自增運算,再做其他運算[2]。

上面這兩種自增操作,是自增操作的最基礎版本,而在很多教學資料中會出現(xiàn)類似于求 (i++)+(i++)+(i++) 、++i * ++i / i++ ; 、 (++i)+(++i)+(++i) 等等計算結果的題目分析,由于絕大多數(shù)資料中分析的方法不同,且都從語法的角度來進行解析,而非從編譯器的操作流程入手,從而給出的解釋各異,本文就針對兩個不同的編譯平臺對這段程序進行分析。

在當前的C語言教學中,教師們最常用的編譯器是微軟公司出品的VC6.0,VS2012或者更新的版本,而由于編譯器內部對C語言的語法解析有些不同,導致上例:當i=1的時候,(++i)+(++i)+(++i) 在不同的編譯器上得到的結果完全不同,本文針對這個式子,在VC6.0 和 VS2012 兩個平臺上的具體計算過程做一個對比。

用來做分析的式子為:(++i)+(++i)+(++i),寫一個簡單的示例程序以使其能在上述兩個編譯器中能運行:

int main() {endprint

int i = 1;

int result = (++i)+(++i)+(++i);

printf(“result=%d\n”,result);

return 0;

}

運行結果:

在兩款編譯器中計算得到的結果分別是10和12。

接下來在兩款編譯器中分別啟動單步調試,然后右鍵選擇查看反匯編,我們能看到每一條語句在匯編中的執(zhí)行順序是如何的:

首先看示例程序在VC6.0中的解析過程,我們重點看 int result=(++i)+(++i)+(++i);這條語句下面的反匯編代碼:

通過查看上面的反匯編代碼,可以感受到一個普通的C語言語句:int result=(++i)+(++i)+(++i);在具體的運算過程中會執(zhí)行多少操作,凝練了多少步驟,如果是純粹的機器語言,步驟還會更多,從此可見C語言如此精煉。

言歸正傳,我們通過對上面反匯編代碼的分析,能看出來編譯器是將自增操作執(zhí)行兩次之后(變量i從1變到3),再對這兩個數(shù)進行了相加運算,得到結果為6,之后再對變量i做了一次自增操作(變量i從3變到4),再同之前的結果6進行了相加運算,結果為10。

其中[ebp-4] 代表的是變量i,eax、ecx、edx是寄存器,運算過程簡析:

1:將變量i的值存到寄存器eax中,此時寄存器eax值為1。

2:將寄存器eax中的值加1存到寄存器eax中,此時寄存器eax值為2 。

3:將寄存器eax中的值傳遞給變量i,此時變量i的值是2。

4:將變量i的值存放到寄存器ecx中,寄存器ecx此時為2。

5:將寄存器ecx中的值加1存到寄存器ecx中,此時寄存器ecx值為3。

6:將寄存器ecx中的值傳遞給變量i,此時變量i的值是3。

7:將變量i的值存到寄存器edx中,此時寄存器edx值為3。

8:將變量i的值同寄存器edx中的值相加,存放到寄存器edx中,此時寄存器edx值為6。

9:將變量i的值存到寄存器寄存器eax中,此時寄存器eax值為3。

10:將寄存器eax中的值加1存到寄存器eax中,此時寄存器eax值為4。

11:將寄存器eax中的值傳遞給變量i,此時變量i的值是4。

12:將變量i的值同寄存器edx中的值相加存放到寄存器edx中,此時寄存器edx中的值是10。

13:將寄存器 edx中的值傳遞到變量i中,變量i的值為10,最后再賦值給變量result,變量result的值就是10 。

接下來我們看VS2012中是如何解析的:

在int result=(++i)+(++i)+(++i);這條語句下面的反匯編代碼如下:

通過上面反匯編代碼的查看,能看出來編譯器是將自增操作執(zhí)行三次之后(變量i從1變到4),再對這三個數(shù)進行了相加運算,得到結果為12。

[i]代表的是變量i(同VC6.0中的[ebp–4]是相同的含義),eax、ecx、edx是寄存器,運算過程簡析:

1:將變量i的值存到寄存器eax中,此時寄存器eax值為1。

2:將寄存器eax中的值加1存到eax中,此時寄存器eax值為2 。

3:將寄存器eax中的值傳遞給變量i,此時變量i的值是2。

4:將變量i的值存放到寄存器ecx中,寄存器ecx此時為2。

5:將寄存器ecx中的值加1存到寄存器ecx中,此時寄存器ecx值為3。

6:將寄存器ecx中的值傳遞給變量i,此時變量i的值是3。

7:將變量i的值存到寄存器edx中,此時寄存器edx值為3。

8:將寄存器edx中的值加1存到寄存器edx中,此時寄存器edx值為4。

9:將寄存器edx中的值傳遞給變量i,此時變量i的值是4。

10:將變量i的值傳遞給寄存器eax,此時寄存器eax值為4。

11:將變量i的值同寄存器eax中的值相加存放到寄存器eax中,此時寄存器eax的值是8。

12:將變量i的值同寄存器eax中的值相加存放到寄存器edx中,此時寄存器eax中的值是12。

13:將寄存器eax中的值傳遞到變量result中,變量result的值就是12。

2 結語

通過前面兩個實驗,我們能看出來,不同版本的編譯器,在匯編的過程對程序語法做了不同的解析,這個是我們編程人員無法控制的,并且C語言最主要的應用領域就是硬件程序開發(fā)、驅動程序開發(fā)、編解碼、算法優(yōu)化方向的開發(fā),在這些開發(fā)中,由于程序邏輯相對復雜,如果我們在編寫程序的過程中過分簡化程序行數(shù),使用優(yōu)先級不明確或者是不同編譯器不明確的運算方法,會導致很嚴重的錯誤,類似于上例的程序,在程序出現(xiàn)異常的情況下,開發(fā)人員往往很難定位錯誤出現(xiàn)的位置以及原因,會極大的浪費時間,作為教師應該要求學生養(yǎng)成良好的編程習慣,用科學、嚴謹?shù)膽B(tài)度對待遇到的問題,在熟練掌握基規(guī)律之后,編寫程序之時,有選擇地小心謹慎地使用自增(自減)運算符來簡化程序,在易錯的地方可用其他方法來代替,從而保證程序的執(zhí)行萬無一失[3]。

參考文獻

[1] 張秀建.試析C語言中的自增自減運算符[J].電腦編程技巧與維護,2017(11):22-24,64.

[2] 闞鈿玉.C語言中自增(自減)運算符號的應用于分析[J].現(xiàn)代計算機,2016(15):40-43.

[3] 唐婷,呂浩音.C語言自增(自減)運算符運算規(guī)律的探討[J].隴東學院學報,2016(5):8-11.endprint

主站蜘蛛池模板: 国产精品久久久久无码网站| 亚洲AⅤ永久无码精品毛片| 亚洲日韩Av中文字幕无码| 欧美国产日产一区二区| 超清无码一区二区三区| 91久久青青草原精品国产| 日韩无码真实干出血视频| 成人综合久久综合| 亚洲综合婷婷激情| 亚洲第一中文字幕| 精品精品国产高清A毛片| 亚洲综合国产一区二区三区| 91精品综合| 久久综合干| 亚洲人成在线免费观看| 99免费视频观看| 在线另类稀缺国产呦| 一级成人a毛片免费播放| 91亚洲免费视频| 国产鲁鲁视频在线观看| 国产精品19p| 韩国v欧美v亚洲v日本v| 日韩毛片基地| 久久青草视频| 久久婷婷综合色一区二区| 亚洲av日韩综合一区尤物| 久久99国产综合精品1| 四虎精品国产永久在线观看| 中文字幕在线日韩91| 日韩一级毛一欧美一国产| 国产一级无码不卡视频| 亚洲日韩国产精品综合在线观看| 欧美激情综合| 九九久久99精品| 亚洲天天更新| 国内精品视频| 91外围女在线观看| 乱系列中文字幕在线视频| 成人永久免费A∨一级在线播放| 亚洲婷婷六月| 一级毛片免费播放视频| 91视频青青草| 天天干天天色综合网| 欧美一级特黄aaaaaa在线看片| 日韩欧美中文亚洲高清在线| 99爱在线| 国产成人调教在线视频| 四虎在线观看视频高清无码| 欧美日韩北条麻妃一区二区| 久久综合干| 毛片在线播放a| 一级香蕉视频在线观看| www.91在线播放| 97人人模人人爽人人喊小说| 国产成+人+综合+亚洲欧美| 97综合久久| 国产成人高清亚洲一区久久| 国产小视频a在线观看| 91成人免费观看| 久久天天躁夜夜躁狠狠| 国产精品永久免费嫩草研究院| 亚洲v日韩v欧美在线观看| 久久青草视频| 亚洲h视频在线| 无码中文字幕乱码免费2| 中文字幕无线码一区| 国产成人高清精品免费| 久久人体视频| 欧美日韩专区| 97人妻精品专区久久久久| 老司国产精品视频91| 色综合手机在线| 114级毛片免费观看| 久无码久无码av无码| 国模沟沟一区二区三区| 国产精品专区第1页| 欧美视频在线第一页| 国产精品入口麻豆| 亚洲天堂自拍| 国产成人三级| 大陆国产精品视频| 人与鲁专区|