亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        剖析C語(yǔ)言自增運(yùn)算規(guī)律

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

        李云超

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

        關(guān)鍵詞:C語(yǔ)言 自增 反匯編

        中圖分類號(hào):TN925 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):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語(yǔ)言歷經(jīng)了幾十年,成為經(jīng)典的編程語(yǔ)言,憑借語(yǔ)句的精煉、語(yǔ)法的靈活、對(duì)系統(tǒng)環(huán)境要求低、擁有較高的執(zhí)行效率而風(fēng)靡整個(gè)世界,再經(jīng)過(guò)歷代改進(jìn),C語(yǔ)言發(fā)展至今非但未被淘汰,更是廣泛的應(yīng)用于各種生產(chǎn)環(huán)境中,并且早已成為計(jì)算機(jī)專業(yè)學(xué)生的入門語(yǔ)言。

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

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

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

        實(shí)驗(yàn)1:

        int main( ){

        int a=8,b;

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

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

        return 0;

        }

        實(shí)驗(yàn)2:

        int main( ){

        int a=8,b;

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

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

        return 0;

        }

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

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

        也就是說(shuō)對(duì)于自增符號(hào)++在變量后面的操作 a++,是先做其他運(yùn)算,再對(duì)a進(jìn)行自增運(yùn)算;而自增符號(hào)++在變量前面的操作++a,是先對(duì)a進(jìn)行自增運(yùn)算,再做其他運(yùn)算[2]。

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

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

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

        int main() {endprint

        int i = 1;

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

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

        return 0;

        }

        運(yùn)行結(jié)果:

        在兩款編譯器中計(jì)算得到的結(jié)果分別是10和12。

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

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

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

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

        其中[ebp-4] 代表的是變量i,eax、ecx、edx是寄存器,運(yùn)算過(guò)程簡(jiǎn)析:

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

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

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

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

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

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

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

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

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

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

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

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

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

        接下來(lái)我們看VS2012中是如何解析的:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        2 結(jié)語(yǔ)

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

        參考文獻(xiàn)

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

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

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

        欧美嫩交一区二区三区| 亚洲国产精品久久久天堂不卡海量 | 男女男生精精品视频网站| 在线观看二区视频网站二区| 在线观看女同一区二区| 极品夫妻一区二区三区| 亚洲熟女av在线观看| 国产激情一区二区三区在线| 蜜臀av在线观看| 亚洲国产天堂一区二区三区| 一本久久a久久精品亚洲| 性xxxx视频播放免费| 国产精品一区二区电影| 人妖精品视频在线观看| 久草91这里只有精品| 国产精品夜色视频久久| 精品国产亚洲亚洲国产| 欧美人牲交| 欧美激情内射喷水高潮| 最新亚洲人AV日韩一区二区| 91精品亚洲一区二区三区| 国产成人自拍小视频在线| 伊人久久亚洲综合av影院| 中文字幕乱码熟女人妻在线| 亚洲av无码国产综合专区| 黄色a级国产免费大片| 性久久久久久久| 国产中文aⅴ在线| 激情人妻中出中文字幕一区| 久久精品亚洲一区二区三区画质| 人妻少妇偷人精品免费看| 亚洲a∨国产av综合av下载| 中文字幕美人妻亅u乚一596| 久久香蕉免费国产天天看| 日韩精品久久久中文字幕人妻| 蜜桃色av一区二区三区麻豆| 日本久久久免费观看视频| 精品一区二区三区免费视频| 天堂一区人妻无码| 国产AⅤ无码久久丝袜美腿| 日本精品久久久久中文字幕1|