闞鈿玉(廣東南方職業(yè)學院信息技術(shù)系,江門 529040)
?
C語言中自增(自減)運算符的應(yīng)用與分析
闞鈿玉
(廣東南方職業(yè)學院信息技術(shù)系,江門529040)
摘要:
關(guān)鍵詞:
C語言;運算符;自增(自減)運算符
C語言程序設(shè)計中,若合理使用自增(自減)運算符,則可以減少代碼編寫,提高編程效率;若不能正確掌握和運用,則容易出錯[1]。通常初學者對自增(自減)運算符很是費解,但是,在C語言的眾多教材和參考書中,對C語言中的自增(自減)運算符介紹非常簡略,而實踐操作中,使用頻率較高,教學中,有必要對其進行詳細分析,讓學生理解并掌握不同使用形式中的不同解題思路和方法。
通常C語言教材中把自增(自減)運算符歸納于算是運算符中,其符號分別為“++”或“--”,
其作用是使變量的值自己增1或減1,而運算結(jié)果仍保存在該變量的存儲單元中,所以通常也稱為增1或減1運算符[2]。自增(自減)運算符的操作對象只能是變量,而不能是常量或表達式,例如:m++、k--是合法的,而3++、(a+b)--是非法的,因為常量的值無法改變,所以不能自增1,若是表達式(a+b)--,假如a+b=7,自減后的值為6,而6是保存在a的存儲單元中還是保存在b的存儲單元中呢?無法確定,所以(a+b)--是非法的[1]。
自增(自減)運算符有兩種形式:一種“++”或“--”在變量之前,稱為前置運算,如++a;
一種是“++”或“--”在變量之后,稱為后置運算,如b--[2]。前置后后置兩種不同的表示方法最終會使自增(自減)運算方式不同,++a或--a指在使用之前先是a的值加1或減1,然后再參與別的運算,即“先變后用”;a++或a--指先用a原來的值去參與運算,然后再是a的值加1或減1,即“先用后變”[3]。當自增(自減)表達式作為單一語句出現(xiàn)時,二者沒有區(qū)別,但把它們引用在表達式中則有明顯區(qū)別。例如:
(1)a=m++,等價于:a=m;m=m+1;如果開始m=3,則執(zhí)行a=m++后,a=3,m=4。
(2)a=++m,等價于:m=m+1;a=m;如果開始m=3,則執(zhí)行a=++m后,a=4,m=4。
自增(自減)運算符是單目運算符,優(yōu)先級為2,高于其他的雙目運算符和三目運算符的優(yōu)先級,但其結(jié)合性為右結(jié)合,即是按照“自右向左”的順序來進行運算的。例如:
#include<stdio.h>
main()
{int m,n=5;
m=-n++;
printf(“m=%d,n=%d”,m,n);
}
此例m=-n++表達式中,程序是執(zhí)行m=(-n)++,還是執(zhí)行m=-(n++)呢?遇到運算符,我們就從“優(yōu)先級”和“結(jié)合性”這兩方面分析,這里“-”負號運算符和“++”自增運算符的優(yōu)先級都是2,結(jié)合性都是右結(jié)合,C語言中規(guī)定:相同優(yōu)先級的運算符的運算次序由結(jié)合性決定。而這兩個運算符的結(jié)合性都是有結(jié)合,那么表達式m=-n++應(yīng)該理解為m=-(n++),所以此程序的運行結(jié)果為:m=-5,n=6。對于初學者來說,編程是可以多加括號來避免出錯。
大部分學生在學習自增(自減)運算符時,都能夠理解前置運算是“先變后用”,而后置運算是“先用后變”的運算規(guī)則,但當遇到具體實例或比較復(fù)雜的運算表達式時,則不知所措,很難靈活運用“先變后用”或“先用后變”這個規(guī)則,下面以實例逐一分析。
2.1自增(自減)運算符組在的復(fù)雜表達式語句中的應(yīng)用
大家知道,C程序中計算模塊的代碼大部分由表達式語句組成,而這些表達式就是運算符和操作數(shù)連接起來的式子。我們在計算這些表達式時要從運算符的“優(yōu)先級”和“結(jié)合性”這兩方面討論,自增(自減)運算符是單目運算符,優(yōu)先級為2,而且是右結(jié)合,那么,在復(fù)雜表達式中,我們怎么運用“先變后用”和“先用后變”這個原則呢?
例1閱讀以下程序,分析運行結(jié)果
#include<stdio.h>
void main()
{int m,n=8;
m=(n++)+(n++)+(n--);
printf(“m=%d,n=%d ”,m,n);
n=8;
n=(n++)+(n++)+(n++);
printf(“n=%d ”,n);
n=8;
m=(++n)+(++n)+(--n);
printf(“m=%d,n=%d ”,m,n);
n=8;
n=(++n)+(++n)+(--n);
printf(“n=%d ”,n);
}
分析:第4行m=(n++)+(n++)+(n--)中,由于自增(自減)運算符是后置運算,應(yīng)執(zhí)行“先用后變”的原則,則m=8+8+8=24,然后n的值在自增兩次,自減1次,即n=8+1+1-1=9;這里很多初學者誤解為m=8+8+ 10=26,我們一定要深入理解“先用后變”這個原則,雖然m=(n++)+(n++)+(n--)中前面兩個n++相加得18,此時“先用后變”中的“用”還沒用完,所以n的值不能改變,我們應(yīng)該理解為m=8+8+8=24,所以第5行輸出的結(jié)果為:m=14,n=9。
第7行n=(n++)+(n++)+(n--)中也是后置運算,道理與第4行代碼相同,只是此時左邊變量是n而不是m,所以計算出來的n=24后再自增2次,自減1次,則n=24+1+1-1=25,所以第6行的輸出結(jié)果為n=25。
第10行m=(++n)+(++n)+(--n)中,由于前置運算,應(yīng)該執(zhí)行“先變后用”的原則,而內(nèi)存是從左至右掃描,在VC6.0中,內(nèi)存是掃描一段就計算一段,所以n應(yīng)先自增兩次變?yōu)?0再相加,即m=10+10+(--n)=20+ (--n),然后n再先自減變?yōu)?,最后再參與算術(shù)“加法”運算,即m=20+9=29,所以第11行輸出的結(jié)果為:m=29,n=9。第13行n=(++n)+(++n)+(--n)中,運算原理與第10行相同,只是左邊的變量由m換成了n,所以第14行輸出的結(jié)果為n=29。
例2閱讀以下程序,分析運行結(jié)果
#include<stdio.h>
void main()
{int a,b,c;
a=b=c=1;
++a&&--b&&++c;
printf(“a=%d,b=%d,c=%d ”,a,b,c);
a=b=c=0;
++a||++b&&++c;
printf(“a=%d,b=%d,c=%d ”,a,b,c);
}
此例第5行表達式++a&&--b&&++c中有自增(自減)運算符和邏輯運算符,而自增(自減)運算符的優(yōu)先級高于邏輯符,所以應(yīng)該計算++a和--b,得出2&&0&&++c;此時要注意C語言中邏輯與和邏輯或運算都有短路特性,即如果在一個復(fù)雜的表達式中前一部分的值能夠決定整個表達式的值,那么后面的表達式則不進行掃描計算,在2&&0&&++c中,無論++c的值是多少,表達式2&&0&&++c的值都是0,后面的++c沒被執(zhí)行,所以第6行的輸出結(jié)果為:a=2,b=0,c=1。第9行表達式++a||++b&&++c中,由于計算機是從左只有掃描的,所以先執(zhí)行++a得出1,此時表達式為1||++ b&&++c,而此表達式無論++b&&++c的結(jié)果是多少,整個表達式1||++b&&++c的值始終是1,后面的++b 和++c不被執(zhí)行,b,c的結(jié)果還是1,所以第10行的輸出結(jié)果為:a=1,b=0,c=0。
2.2自增(自減)運算符在循環(huán)結(jié)構(gòu)中的應(yīng)用
C語言中的循環(huán)結(jié)構(gòu)有三種語句:while語句,do……while語句,for語句。無論哪種循環(huán)語句,都必須有改變循環(huán)變量而使循環(huán)條件不成立的語句,而這樣的語句經(jīng)常是循環(huán)變量自增(自減)表達式語句,若i為循環(huán)變量,則經(jīng)常被用來使循環(huán)趨于結(jié)束的語句是i++或i--,最常見的for語句就是這樣的,例如for(i=1,s=1;i<=10;i++)s=s*i;當i=11時,循環(huán)條件不成立,循環(huán)結(jié)束,所以在循環(huán)結(jié)構(gòu)中,自增(自減)運算符一般是改變循環(huán)變量的作用。
2.3自增(自減)運算符在printf()函數(shù)中的應(yīng)用
在VC6.0運行環(huán)境下,printf()函數(shù)執(zhí)行過程是將函數(shù)實際參數(shù)表達式的值按照從右至左的順序入棧,入棧前就將printf()函數(shù)實際參數(shù)表達式的值計算完畢,被調(diào)函數(shù)從棧中取出參數(shù)使用,如果printf()函數(shù)有多個參數(shù),則它們是按照從右至左的順序計算,但是printf()函數(shù)輸出結(jié)果的順序仍是從左至右,與計算機掃描順序一致。
例3閱讀以下程序,分析運行結(jié)果
#include<stdio.h>
void main()
{int i=8;
printf(“%d,%d,%d,%d,%d,%d ”,i++,i++,i++,i++,i++,i++);
printf(“%d ”,i);
i=8;
printf(“%d,%d,%d,%d,%d,%d ”,++i,++i,++i,++i,++i,++i);
printf(“%d ”,i);
}
第4行代碼中,printf()函數(shù)的輸出表列是多個表達式,而且都是自增運算符的后置運算,還是遵循“先用后變”的原則,只是這里的“先用”是一直計算完printf()函數(shù)的所有輸出列表,“后變”則是指printf()函數(shù)輸出結(jié)果后再改變i的值,所以第4行的輸出結(jié)果為:8,8,8,8,8,8。而第5行i的值應(yīng)是從8自增6次后的值14,所以第5行的輸出結(jié)果為14。第7行代碼中,printf()函數(shù)的輸出表列是多個前置運算表達式,我們遵循“先用后變”的原則,但這時要注意printf()函數(shù)的計算參數(shù)順序是從右至左,而輸出時則是從左至右輸出,所以第7行輸出結(jié)果是:14,13,12,11,10,9。第8行輸出結(jié)果為14。
從這個例子分析得出:printf()函數(shù)的參數(shù)中若有自增(自減)運算符的表達式,我們一定要注意:若是前置運算,例如i++或i--時,i的值是在printf()函數(shù)執(zhí)行之后才被刷新,所以在printf()函數(shù)中,i++或i--對i的值暫時不產(chǎn)生影響;若是前置運算,例如++i或--i時,i的值在printf()函數(shù)執(zhí)行之前改變,但計算順序是從右至左,輸出時仍按從左至右輸出結(jié)果。
2.4自增(自減)運算符在指針中的應(yīng)用
C語言中規(guī)定,當指針p指向一串連續(xù)的存儲單元時,可以對指針p進行自增或自減運算,這種操作稱為指針的移動,例如p++或p--,都可以使指針移動,p++是表示指針下移一個數(shù)據(jù),即指向下一個元素,p--是表示指針上移一個數(shù)據(jù),即指向上一個元素,而不是將p的值直接增1或減1,既然是表示指向下一個元素或上一個元素,那么就要求這一系列元素必須在內(nèi)存中連續(xù)存儲,所以通常p++或p--只能在數(shù)組中討論,而且我們還要小心p++,p--不能超出數(shù)組的上下限[4]。
例4閱讀以下程序,分析運行結(jié)果
#include<stdio.h>
void main()
{int *p,a[10]={1,2,3,4,5,6,7,8,9,10};
for(p=&a[9];p>=a;p--)
printf(“%d,”,*p);
}
第4代碼中,p的初值是指向a[9]這個元素,然后輸出a[9],接著p指向上一個元素a[8],然后又輸出a [8],直到輸出a[0]為止,所以以上程序結(jié)果為:10,9,8,7,6,5,4,3,2,1。
自增(自減)運算符在C語言編程過程中運用頻率很高,對于初學者來說既是重點又是難點,在不同的使用形式中,分析思路略有不同,要求使用者倍加小心,靈活運用。
參考文獻:
[1]周偉.C語言中自增(自減)運算符教學探究[J].軟件導刊,2012(12).
[2]董漢麗.C語言程序設(shè)計[M].第6版.大連:大連理工出版社,2013.
[3]李彩玲.C語言中自增自減運算符的應(yīng)用與解析[J].晉城職業(yè)技術(shù)學院學報,2013(3).
[4]譚浩強.C程序設(shè)計[M].第4版.北京:清華大學出版社,2010.
The operators of C language are rich,its increment(decrement)operator is distinctive and frequently used in C language,for new leaners and beginners,it is most difficult part to get understood and easy to make mistake.Considering the basic characteristics of the increment (decrement)operator,and followed by many years of experience from teaching and practical application in VC6.0 environment,start from the real and alive example,go through from easy to difficult and step by step,and summarize a variety of different solving problem solution,which can bring the help to new leaners and beginners great help to understand and know well of increment(decrement)operator.
Keywords:
C Language;Operators;Increment(Decrement)Operators
Application and Analysis of Increment(Decrement)Operator in C Language
KAN Tian-yu
(Department of Information Technology,Guangdong Nanfang Vocational College,Jiangmen 529000)
Abstract:
C語言中運算符非常豐富,自增(自減)運算符是C語言中比較有特色而且使用頻率較高的運算符之一,對于初學者來說,也是最難理解而又最容易出錯的運算符。根據(jù)自增(自減)運算符的基本特點,再結(jié)合多年教學和使用經(jīng)驗,以VC6.0為運行環(huán)境,從示例入手,由淺入深,總結(jié)出多種不同使用形式中的不同解題思路,希望為初學者學習自增(自減)運算符帶來幫助。
文章編號:1007-1423(2016)15-0040-04
DOI:10.3969/j.issn.1007-1423.2016.15.011
作者簡介:
闞鈿玉(1979-),女,湖北通山人,碩士,研究方向為軟件工程、電子商務(wù)及高職教育學理論
收稿日期:2016-03-15修稿日期:2016-05-10