官术网_书友最值得收藏!

2.6 算術運算符和算術表達式

2.6.1 C語言運算符簡介

C語言的運算符十分豐富,且應用非常廣泛,分為以下幾類:

①算術運算符        (+ - * / %)

②關系運算符       ?。?gt; < == >= <= !=)

③邏輯運算符        (! && ||)

④位運算符       ?。?lt;< >> ~ | ^ &)

⑤賦值運算符        (=及其擴展賦值運算符)

⑥條件運算符       ?。??:)

⑦逗號運算符        (,)

⑧指針運算符       ?。?和&)

⑨求字節運算符       ?。╯izeof)

⑩強制類型轉換運算符       ?。ǎ愋停?/p>

 分量運算符       ?。? ->)

 下標運算符       ?。ǎ?nbsp;])

 其他       ?。ㄈ绾瘮嫡{用運算符())

本節只介紹算術運算符和強制類型轉換符,在后面各章節中將陸續介紹其他的運算符。

2.6.2 基本算術運算符和算術表達式

(1)基本算術運算符

基本算術運算符有:-(取負)、+(取正)、+(加)、-(減)、*(乘)、/(除)、%(模運算符或稱求余運算符)。

其中-(取負)、+(取正)稱為單目運算符,即需要一個運算對象,如-5,+3;+(加)、-(減)、*(乘)、/(除)、%(模運算符或稱求余運算符)稱為雙目運算符,即需要兩個運算對象,如5+5,9%6等。

使用算術運算符要注意以下幾點:

①除法運算符“/”的運算結果和其運算對象有關,如果兩個符號相同的整數相除則結果是整數,如5/3的結果為1,2/3的結果為0,舍去小數部分,并且不進行四舍五入。兩個運算對象中只要有一個是實數,則運算結果就是實數。如1.0/2的結果0.5。如果兩個運算對象中有一個是負數,則舍入的方向是不固定的。例如,-5/3在有的系統中結果為-1,有的系統結果為-2。多數C編譯系統一般采用“向零取整”原則,即按其絕對值相除后再加負號,因此-5/3=-1。還要注意,除數不能為0。

②求余運算符“%”要求其運算對象必須是整數,但可正可負。對于有負數的情況一般采用以下規則:即先按其絕對值進行求余運算,然后取被除數的符號作為余數的符號。例如,-5%3=-2,5%-3=2。

③對于乘方運算。C語言的算術運算符中沒有乘方運算符,例如計算23,應寫成2*2*2,高次冪時要使用pow(x,n)函數,其含義是:xn

(2)算術表達式

由算術運算符和運算對象構成的表達式稱為算術表達式。圓括號“()”允許出現在任何表達式中。例如:

-a*(x+y-1.5)+25/9%6

(x+y)/z+sin(x*y)

sqrt(b*b-4*a*c)

fabs(x)

2*a

其中sin()和sqrt()和fabs()是C語言提供的標準函數,用于完成數學上的正弦運算、平方根運算和求絕對值運算,最后一個表達式2*a不能寫成2a。

(3)算術運算符的優先級

算術運算符的優先級從高到低為:

()→-(取負)→*(乘)、→/(除)、→%(模運算符或稱求余運算符)→+(加)、→-(減)。

其中,乘法、除法和求余運算的優先級相同,加法、減法的運算優先級相同。

例如,有下列算術表達式:

-3*2/4+2.5-3*(2/4)+25/9%3

其運算結果為:3.5

(4)算術運算符的結合性

在算術運算符中,只有單目運算符“+”“-”的結合性是從右到左的,其余的運算符都是從左到右。

例如,計算下列表達式的值:

-x/(y+1.5)-19%6*2

求值過程如下:

①求-x的值;

②求y+1.5的值;

③求①/②的值;

④求19%6;

⑤求④*2的值;

⑥求③-⑤的值。

2.6.3 復合賦值運算符及表達式

在賦值運算符之前加上其他運算符可以構成復合賦值運算符,在C語言中共有10種復合賦值運算符,其中與算術運算符有關的復合賦值運算符有:+=、-=、*=、/=、%=(注意:兩個符號之間不可以有空格)。復合賦值運算符的優先級與賦值運算符的優先級相同,運算方向自右向左。

+=  a+=b  等價于  a=a+b

-=  a-=b  等價于  a=a-b

*=  a*=b  等價于  a=a*b

/=  a/=b  等價于  a=a/b

%=  a%=b  等價于  a=a%b

例如,a-=b+3等價于a=a-(b+3)。

 【例2.8】  復合賦值運算符的應用舉例。

已知變量a的值為6,計算表達式a+=a-=a+a的值。

分析:

①先計算“a+a”,因為a的初值為6,所以該表達式的值為12,注意a的值未變。

②再計算“a-=12”,相當于“a=a-12”,因為a的值仍為6,所以表達式的值為-6,注意此時a的值已為-6。

③最后計算“a+=-6”,相當于“a=a+(-6)”,因為此時a的值已為-6,所以表達式的值為-12。

由此可知,表達式a+=a-=a+a的值為-12。

 【例2.9】  分析下面程序的運行結果。

#include<stdio.h>

void main()

{ int n=4; 

  n+=n-=n*n;

  printf("n=%d \n",n); 

}

輸出結果:

n=-24

2.6.4 各類數值型數據之間的混合運算

C語言允許在一個表達式中出現多種數據類型,在進行運算時,不同類型的數據首先按規則進行類型轉換,再進行運算,轉換的方法有兩種,一種是自動轉換,一種是強制類型轉換。

(1)自動轉換(隱式轉換)

在C語言中,整型、實型、字符型的數據都可以混在一起進行運算。例如:

2.5*2+5/3+6*'c'-'2'

在C語言中是合法的表達式。字符型數據是以它對應的ASCII碼值參與運算的,上面的表達式相當于2.5*2+5/3+6*99-50。

那么上面表達式的值是多少呢?是整型數?還是實型數?這就涉及不同數據類型的自動轉換了。自動轉換發生在不同數據類型混合運算時,由編譯系統自動完成。自動轉換遵循下面的規則:

①若參與運算的數據類型不一致,則先轉換成同一類型,然后進行運算。

②轉換按數據長度增加的方向進行,以保證精度不降低。例如,int 型和long型運算時,先把int型轉換成long型后再計算。

③所有的實數運算都以雙精度進行,即使含有float單精度量運算的表達式,也要先轉換成double型,再進行運算。

④char 型和 short型參與運算時,必須先轉換成int型。

⑤在賦值運算中,賦值號兩側運算量的數據類型不同時,賦值號右邊運算量的類型將轉換為左側變量的類型。當右側運算量的數據類型長度比左側長時,會降低精度。

圖2.4表示了各數據類型自動轉換的規則。

圖2.4 各數據類型自動轉換規則

圖2.4中向上的箭頭表示必定的轉換:char 型、short型在運算時一律先轉換為int型;float型數據在運算時一律先轉換為double型,以提高運算精度。

橫向向右的箭頭表示當運算對象為不同類型時轉換的方向。例如,int 型與double型數據在一起運算時,先將int型數據轉換成double型,然后進行兩個同類型(double型)數據的運算,結果為double型。

現在我們再來分析一下表達式2.5*2+5/3+6*'c'-'2'的運算和類型轉換過程:

①進行2.5*2的運算,先將2.5和 2轉換成double型(小數點后加若干個0),運算結果為double型。

②進行5/3的運算,由于運算對象一致,故結果為1。

③進行①和②的加運算,先將②轉換成double型,再進行運算,運算后的結果為double型。

④進行6*'c'的運算,先將'c'轉換成整數99,運算結果為594。

⑤進行③和④的加運算,先將④轉換成double型,再進行運算,運算后的結果為double型。

⑥進行⑤與'2'的減運算,先將'2'轉換成整數50,再將50轉換成double型,再進行運算,運算后的結果為double型。

 【例2.10】  不同類型數據間的算術運算。

#include<stdio.h>

void main()

{ float a,b,c;

  a=9/2;

  b=9/2*1.0;

  c=1.0*9/2;

  printf("a=%f,b=%f,c=%f\n",a,b,c); 

}

程序運行結果:

  a=4.000000,b=4.000000,c=4.500000

(2)強制類型轉換

有時C編譯系統無法實現自動轉換時就需要強制轉換。利用強制類型轉換運算符可以將一個表達式的值轉換成所需要的類型。其一般形式如下:

(類型名)(表達式)

“類型名”稱為強制類型轉換運算符。

例如,表達式(double)(x+y)的功能就是將(x+y)的值轉換成double型的;表達式(float)(5%3)的功能就是將5%3的值轉換成float型的。

假設整型變量a 值為25,則表達式(float)(a)的值為25.0。

使用強制類型轉換要注意以下幾個方面:

①強制類型轉換運算符一定要用一對小括號括起來。

例如,int(x+y)就是不合法的強制類型轉換。

②強制類型轉換中的表達式一定要用括號括起來,否則僅對緊跟強制類型轉換運算符的量進行類型轉換。而對單一數值或變量進行強制類型轉換時,則可不要括號。例如:

(int)a+b       /*將變量a的值轉換成int型再與變量b相加*/

(int)(a+b)       /*將a+b的值轉換成int型*/

(float)a/5       /*將變量a的值轉換float型再除以5*/

(float)(a/5)       /*將a/5的值轉換成float型*/

③強制類型轉換運算符只是對其后面的表達式的值進行轉換,而不改變表達式中變量的類型和變量的值。例如:

float a=3.69;

int b;

b=(int)a;

則變量b的值為整數3,而變量a的值還是3.69,a的類型仍然是float型。

④將一個實型數據強制轉換成整型數據時只是舍去小數部分,不需進行四舍五入。

如上例中的變量b的值為3,而不是4。

2.6.5 自增與自減運算符

在C語言中有兩個特殊的算術運算符,即自增、自減(++、--)。這兩個運算符屬于單目運算符,可以放在運算對象的前和后,形成前綴形式和后綴形式,但不論放在運算對象的前與后,其結果都是將運算對象的值增1或減1。如設有整型變量i,則++i、i++都使i值增1,--i、i--都使i值減1。

前綴形式和后綴形式的區別在于對它所作用的變量值的使用。

前綴形式:++i、--i,它的功能是,先使i的值增1或減1(即先進行i=i+1或i=i-1運算),再使用i。

后綴形式:i++、i--,它的功能是,先使用i,再使i的值增1或減1(即后進行i=i+1或i=i-1運算)。

例如:

int i=3,a,b,c,d;

a=i++;  /*先將i的值賦給a,然后將i自增1,即i=i+1,此時a=3,i=4*/

b=++i;  /*先將i的值增1,即i=i+1,然后再將i的值賦給b,此時i=4,b=4*/

c=i--;  /*先將i的值賦給c,然后將i自減1,即i=i-1,此時c=3,i=2*/

d=--i;  /*先將i的值減1,即i=i-1,然后將i的值賦給d,此時i=2,d=2*/

使用自增、自減運算符應注意以下幾個方面:

①自增或自減運算符“++”或“--”的運算結果是使運算對象增1或減1。

②自增或自減運算符的對象只能是變量,即可以是整型變量、字符型變量、實型變量、指針型變量,但不能是常量或表達式。所以像++3、(i+j)++、--(a=3)、--(-i)等都是不合法的。

③自增或自減運算符的結合性為:前綴時是自右向左,后綴時是自左向右。

例如:i=-j++等價于i=-(j++),這個表達式的含義是:先把j當前值加上負號賦給i,即i=-j,然后j自增1。注意該表達式并不等價于i=(-j)++,因為這樣就使++作用于表達式了,這是不允許的。

④程序設計時盡量不要在兩個運算對象中間出現多個自增或自減運算符。如表達式i+++j、i+++i++等雖然在C語言中是允許的,但是讀者很難理解。

 【例2.11】  自增或自減運算舉例。

#include<stdio.h>

void main()

 { int a=3,b=6,c,d,e,f;

 c=b+a++;

 d=a+(--b);

 e=-a++;

 f=a+b+c;

 printf("a=%d,b=%d,c=%d,d=%d,e=%d,f=%d\n",a,b,c,d,e,f);

}

程序運行結果:

a=5,b=5,c=9,d=9,e=-4,f=19

【例2.12】  自增或自減運算舉例。

#include<stdio.h>

void main()

 { int i=3,j=-5;

 printf("i=%d,j=%d\n",i,j);

 printf("i=%d,j=%d\n",i++,--j);

 printf("i=%d,j=%d\n",--i,j++);

}

程序運行結果:

i=3,j=-5

i=3,j=-6

 i=3,j=-6

主站蜘蛛池模板: 江都市| 恩平市| 建宁县| 东乡族自治县| 瓦房店市| 永靖县| 三门峡市| 赤峰市| 醴陵市| 阿巴嘎旗| 克东县| 连州市| 同仁县| 海阳市| 建阳市| 高要市| 永济市| 泌阳县| 怀宁县| 赤城县| 康乐县| 东阳市| 南城县| 沂南县| 栾川县| 修水县| 东阳市| 宁远县| 合阳县| 新源县| 积石山| 称多县| 金华市| 隆尧县| 罗定市| 堆龙德庆县| 阿克陶县| 桃源县| 新乡市| 绥德县| 招远市|