算術運算子按運算元個數可分為一元運算子(含一個運算元)和二元運算子(含兩個運算元)。
一元運算子的優先順序一般高於二元運算子。
一元運算子:+(正號)、-(負號)、++(增1)、--(減1)。
二元運算子:+(求和)、-(求差)、*(求積)、/(求商)、%(求餘)。
符號運算子:+(正號)、-(負號)
'+'(正號)表示不改變運算元的值及符號,如 23 也可表示為 +23,編譯器不報錯。而 '-'(負號)可用於得到一個數的相反數。例如:
int a=-5;
int b=-a;
在變數 a 前加 -(負號)後賦值給 b,即把 a 的相反數賦給 b。
自增量運算子:++(增1)、--(減1)
自增量運算子均有兩種使用形式,++a、a++ 及 --a、a--,也稱為
字首形式和
字尾形式。
在講解自增量運算子的兩種形式之前,先介紹下左值(lvalue)和右值(rvalue)的概念。
計算機記憶體中可修改的儲存物件,一般稱為左值或 lvalue。例如:
int a; //整型變數a可以作為左值使用
float b; //單精度浮點型變數b也可作為左值使用
const int c; //因為常變數c的值不允許改變,故不可作為左值使用
把可賦值給左值的量稱為右值或 rvalue。右值可以是常數、變數或者表示式。例如:
int a,b; //定義整型變數a和b
a=2; //把常數2作為右值,賦給左值a
b=a; //把變數a作為右值,賦給左值b
b=a+3; //把表示式a+3的值作為右值,賦給左值b
字首形式:如 ++a 為字首加形式的增 1 表示式,表示把變數 a 的值加 1 後的值作為該表示式的值,同時變數 a 本身的值加 1; --a 類似,表示把變數 a 的值減 1 後的值作為該表示式的值,同時變數 a 本身的值減 1。
例如:
int a=5,b;
則語句 b=a++; 與 b=++a; 的含義不同。若採用第一條賦值語句,則直接把 a 的原值 5 賦給變數 b。若採用第二條賦值語句,則把 a 的原值 5 加 1 後的值 6 賦給變數 b。相同的是,這兩種賦值方式均使變數 a 自身的值增了1,即執行完後,a 均為6。
字尾形式:如 a++為字尾加形式的增 1 表示式,表示先直接把變數 a 原來的值作為該表示式的值,然後變數 a 本身的值加 1; a-- 類似,表示先直接把變數 a 原來的值作為該表示式的值,然後變數 a 本身的值減 1。
注意,浮點型變數也同樣支援自增量運算操作。例如:
float a=3.2f;
a++;
printf("a=%fn",a);
執行完自增量運算後,輸出 a=4.200 000。
建議在實際程式設計中,應儘量避免對浮點型變數進行自增量運算操作。通過下面的例子,掌握字首增1 與字尾增 1 兩種使用形式的異同。
【例 1】分析以下程式,輸出其執行結果。
#include<stdio.h>
int main (void)
{
int a=2,b,c,d;
b=++a+4;
c=3*a++;
d=a--*3;
printf ("a=%d,b=%d,c=%d,d=%d",a,b,c,d);
return 0;
}
程式碼分析:
1) b=++a+4;該語句中運用到三個運算子:字首增 1 運算子 ++、加法運算子 + 和賦值運算子 =,三個運算子的優先順序是一元運算子 ++ 最高,其次是求和,最低的是賦值運算子。
該語句等價於 b=(++a)+4; 先取變數 a 的值 2 加 1 後的結果 3 作為 ++a 表示式的值,然後把該表示式的值 3 與 4 求和的值 1 賦值給變數 b,即 b 值為 7。執行完該語句後變數 a 自身值增 1,其值變為 3。
2) c=3*a++; 等價於 c=3*(a++); 表示把 3 與 a++ 求積的結果賦給 c,而 a++ 表示式表示先把變數 a 的值 3 作為該表示式的值,即 c=3*3; 同時變數 a 自身值增 1,變為 4。
3) d=a--*3; 先取變數 a 的值 4 作為表示式 a-- 的值,把 4*3 的值 12 賦給變數 d。同時變數 a 自身減 1,變為 3。
4) printf("a=%d,b=%d,c=%d,d=%d", a,b,c,d); 雙引號中有 4 個輸出格式控制符,依次使用輸出列表中 4 個輸出項 a、b、c、d 的值替換。
執行結果為:
a=3,b=7,c=9, d=12
增1、減1運算子的副作用
注意,增1、減1運算子是具有副作用的運算子,即不僅能改變表示式的值,也改變了變數自身的值。使用時要慎重,尤其以下兩種情況,要避免使用。
1) 當一個變數多次出現在某表示式中時,建議不要將增 1 或減 1 運算子應用於該變數。例如:
int a=1; //定義整型變數a,並賦初值1。
int b; //定義整型變數b,未初始化。
b=a++ + a++; //杜絕編寫類似的表示式
a++ + a++ 該表示式的值到底是兩次取 a 的原值 1 相加的結果 2 賦給 b,即 b=2=1+1,還是按從左到右取 a 原值 1 作為第一個 a++ 表示式的值,同時變數 a 增 1 變為 2。第二個表示式的值為取 a 的值 2 作為表示式的值,同時變數 a 增 1,變為 3,這樣 b=3=1+2,還是從右到左依次運算。C 標準沒有對此進行統一規定,不同的編譯器可能得到不同的結果。
死記硬背這類操作的規則毫無意義。為了增強程式碼的可讀性及可移植性,並避免產生歧義性,這種非標準的語法一定要慎用或不用。
2) 多參函數呼叫時,如果一個變數出現在多個實參中時,不要對該變數使用增 1 或減 1 運算子。原因同上,即不同編譯器可能得到不同結果,出現歧義性。
相除運算子 /
當運算子 / 的運算元(被除數和除數)均為整數時,結果為取商(取整)。
例如:16/5 結果為兩數相除的商 3。
當運算子 / 的運算元中有一個或兩個浮點數時,結果與數學中除法運算相同,包含整數部分和小數部分。
例如:8/2.5 結果為 3.2。
取餘運算子%
當運算子 % 的運算元(被除數和除數)均為整數時,結果為取餘。
例如:16%5 結果為兩數相除的餘數 1。
當運算子 % 的運算元中有一個或兩個浮點數時,語法錯誤。
例如:8%2.5 語法錯誤。
即運算子%兩運算元都必須為整數,否則語法錯誤。
在程式設計中,經常使用求商和求餘運算子分解整數的各位數位。例如,分解十進位制整數 123 的個位、十位和百位數位,可以有多種不同的分解方案,下面是其中一種方案。
int a=123,g,s,b; //g:個位 s:十位 b:百位
g=a%10; //g=3
s=a/10%10; //s=2
b=a/100; //b=l