- 零基礎學C語言程序設計
- 宋娟編著
- 4886字
- 2022-05-06 19:49:52
3.2 數值處理
在C語言中,數值處理包括整數、小數的各種運算處理,如算術運算、擴展賦值、增量/減量運算、正/負運算等。本節將詳細講解這些運算處理方式,以及對運算時所出現的各種問題的處理。
3.2.1 算術運算

算術運算又稱四則運算,包括加法、減法、乘法和除法。在數學中,我們會通過加號、減號、乘號和除號實現這幾種運算。在C語言中,提供了對應的運算符,如加法運算符(+)、減法運算符(-)、乘法運算符(*)、除法運算符(/),以及其他運算符。下面依次講解這幾種運算符的使用。
1. 加法運算符
加法運算符(+)是二目運算符,擁有兩個操作數。該運算符可以讓兩個數值或變量進行相加運算。
加法運算符的語法如下:

2. 減法運算符
減法運算符(-)是二目運算符,擁有兩個操作數。該運算符可以讓兩個數值或變量進行相減運算。
減法運算符的語法如下:

3. 乘法運算符
乘法運算符(*)是二目運算符,擁有兩個操作數。該運算符可以讓兩個數值或變量進行相乘運算。
乘法運算符的語法如下:

【示例3-9】將兩個變量進行加法、減法及乘法運算后的結果賦給變量。
程序如下:

運行程序,輸出以下內容:

在進行運算時,如果運算結果超出了對應變量可存儲數值的最大范圍后,就會出現溢出錯誤。一旦出現溢出錯誤后,輸出的運算結果將變成一個隨機數。
【示例3-10】將兩個整型變量進行乘法運算,而運算結果超出整型變量的范圍。
程序如下:

運行程序,輸出以下內容:

4. 除法運算符
除法運算符(/)屬于雙目運算符,擁有兩個操作數。該運算符可以讓兩個數字或變量進行相除運算。除法運算符的語法如圖3.4所示。

圖3.4 除法運算符的語法
【示例3-11】將兩個變量相除的運算結果賦給變量。
程序如下:

運行程序,輸出以下內容:

注意:由于除法運算不一定是整除運算,所以存放除法運算的結果變量,一般會聲明為小數類型。
另外,在除法運算中,要注意操作數2,也就是除數不能為0;特別要注意當除數為一個變量時,該變量的取值一定不能為0;如果操作數2為0,程序運行時會出現錯誤。
【示例3-12】驗證在除法運算中,當操作數2為0時,運行程序時會出現錯誤信息。
程序如下:

運行程序,輸出以下錯誤信息:

5. 求余運算符
求余運算符(%)屬于二目運算符,擁有兩個操作數,且兩個操作數只能為整數。該運算符可以讓兩個數字或變量進行求余運算。求余運算符的語法如圖3.5所示。

圖3.5 求余運算符的語法
求余運算在生活中十分常用。
【示例3-13】770個員工去旅游,每輛大客車上能坐48人,為了節約資源,利用求余運算計算出除了坐滿人的大客車外,還要雇用一個幾人座的小汽車以使剩余的人坐下。
程序如下:

運行程序,輸出以下內容:

(1)在求余運算時,如果操作數1為正整數,操作數2為負整數,則運算結果為正整數。
【示例3-14】將正整數與負整數進行求余運算。
程序如下:

運行程序,輸出以下內容:

(2)在求余運算時,如果操作數1為負整數,操作數2為正整數,則運算結果為負數。
【示例3-15】將負整數與正整數進行求余運算。
程序如下:

運行程序,輸出以下內容:

(3)在求余運算時,如果兩個操作數都為負整數,則運算結果為正整數。
【示例3-16】將負整數與負整數進行求余運算。
程序如下:

運行程序,輸出以下內容:

注意:編譯器不同,會導致求余運算結果的符號位不同。
3.2.2 擴展賦值運算

可以發現,在進行算數運算時,有些表達式中操作數1與表達式結果相同,如圖3.6所示。

圖3.6 操作數1與表達式結果相同
顯然,a=a*b這種寫法有些重復。在C語言中,為了提高運算效率和簡化書寫,提供了擴展賦值運算符,又稱復合賦值運算符。擴展賦值運算符如表3.2所示。
表3.2 擴展賦值運算符

【示例3-17】使用加法賦值運算符進行求和運算。
程序如下:

運行程序,輸出以下內容:

3.2.3 增量/減量運算

老師在點名時一般是按照學號的順序進行的。如果想要在程序中按照學號讀取學生時,那么指向學號的變量就會不斷加一。如果使用加法運算符,程序會十分麻煩。為了對應這種問題,C語言提供了專門的運算符號,將其稱為增量運算符與減量運算符。
1. 增量運算符
增量運算符(++)屬于一目運算符,擁有一個操作數,且操作數必須是整數和小數類型的變量。該運算符可以讓變量進行自加運算。根據運算符使用的位置,該運算符有以下兩種語法形式。
(1)前綴增量運算符會讓操作數自增1后再參與其他運算,其語法如下:

【示例3-18】使用前綴增量運算符進行運算。
程序如下:

運行程序,輸出以下內容:

對于printf("運算后i的值為:%d",++i);這行代碼,首先i變量會進行自增,然后才會參與輸出,所以輸出結果為101,如圖3.7所示。

圖3.7 printf("運算后i的值為:%d",++i);這行代碼的分步運行
(2)后綴增量運算符會讓操作數參與運算后,操作數的值再自增1,其語法如下:

【示例3-19】使用后綴增量運算符進行運算。
程序如下:

運行程序,輸出以下內容:

對于printf("運算后i的值為:%d",i++);這行代碼,首先輸出變量i,然后進行變量i的自加運算,所以第一次輸出結果為100,第二次輸出結果為101,如圖3.8所示。

圖3.8 printf("運算后i的值為:%d",i++);這行代碼的分步運行
2. 減量運算符
減量運算符(-)屬于一目運算符,擁有一個操作數,且操作數必須是整數和小數類型的變量。該運算符可以讓變量進行自減運算。根據運算符使用的位置,該運算符有兩種語法形式。
(1)前綴減量運算符會讓操作數自減1后再參與其他運算,其語法如下:

【示例3-20】使用前綴減量運算符進行運算。
程序如下:

運行程序,輸出以下內容:

對于printf("運算后i的值為:%d",++i);這行代碼,首先i變量會進行自減,然后才會參與輸出,所以輸出結果為99,如圖3.9所示。

圖3.9 printf("運算后i的值為:%d",++i);這行代碼的分步運行
(2)后綴減量運算符會讓操作數參與其他運算后,操作數的值再自減1,其語法如下:

【示例3-21】使用后綴增量運算符進行運算。
程序如下:

運行程序,輸出以下內容:

對于printf("運算后i的值為:%d",i-);這行代碼,首先輸出變量i,然后進行變量i的自減運算,所以第一次輸出結果為100,第二次輸出的結果為99,如圖3.10所示。

圖3.10 printf("運算后i的值為:%d",i-);這行代碼的分步運行
3. 增量/減量運算符的使用建議
由于增量/減量運算符會涉及多個加號或減號的使用,所以在一個表達式中要盡量避免多次出現同一類運算。
【示例3-22】使用多個增量運算符的運算。
程序如下:

運行程序,輸出以下內容:

對于i=i+++i++;這行代碼,就多次使用了自增運算符,而且還與加法運算符混用。這種書寫方法不但可讀性極低,而且經不同編譯器的運算,其結果會不同。所以,一定要盡量避免這種書寫方法。
3.2.4 正/負運算

生活中所接觸的數據會有盈虧之分。例如,對于公司來說,花費的金額就是負數,而盈利的金額就屬于正數。在C語言中,使用正/負運算符用于數字的正/負運算。正/負運算符包含兩個符號“+”與“-”。
1. 正運算符
正運算符(+)屬于一目運算符,擁有一個操作數。該運算符一般用于格式上的對齊,并不能讓負數變為正數。
正運算符的語法如下:

【示例3-23】驗證使用正運算符無法改變數的值。
程序如下:

運行程序,輸出以下內容:

從程序運行結果可以看出,正運算符并沒有改變變量a的值。所以,正運算符一般用于格式上的對齊,如下所示:

2. 負運算符
負運算符(-)屬于一目運算符,擁有一個操作數。負運算符可以讓數字進行負運算。
負運算符的語法如下:

【示例3-24】使用負運算符改變值的正/負。
程序如下:

運行程序,輸出以下內容:

從程序運行結果可以看出,負運算符將變量a、b的值進行了正/負改變。
3.2.5 數據類型不一致的處理

在捐款時,有人會捐100元(整數),而有人會捐1.5元(小數)。如果讓計算機計算這些捐款,就會涉及整數與小數的相加問題。也就是說,兩個數據類型的數字進行相加,涉及了數據類型不一致問題。對此,在C語言中,規定了以下3種針對數據類型不一致的處理方式。
1. 自動轉換
在生活中,我們會先把大米放入袋子中,再將多袋大米放入汽車中,最后將幾車的大米放到火車車廂中。這都是根據大米的量放置到合適的容器中,如圖3.11所示。

圖3.11 大米的容器
C語言的自動轉換過程也是一樣的。在C語言中,規定在表達式中如果出現數據類型不同的情況,都必須轉換為同一類型數據才能進行運算,而自動轉換的方向是由所占存儲單元少的數據類型向所占存儲單元多的數據類型轉換。自動轉換規則如圖3.12所示。

圖3.12 自動轉換規則
【示例3-25】輸出表達式的值占幾個字節。
程序如下:

運行程序,輸出以下內容:

從程序運行結果可以看出,表達式a+b的值占4個字節,這說明數值在計算時被自動轉換為int類型。
注意:當賦值運算符(=)左、右兩側操作數的數據類型不同時,一定是將右側操作數的數據類型轉換為左側操作數的數據類型。如果左側操作數所占存儲單元少于右側操作數所占存儲單元,則會出現數據丟失的情況。
【示例3-26】演示當賦值運算符左側操作數所占存儲單元少于右側操作數所占存儲單元時發生數據丟失的情況。
程序如下:

運行程序,輸出以下內容:

從程序運行結果可以看出,程序運行輸出的值明顯是錯誤的,這是因為在存儲數據時發生了溢出的情況,即發生了數據丟失的情況。
2. 小數運算
在C語言中,雙精度類型是小數的默認存儲方式。在表達式中如果出現了單精度和雙精度兩種類型的小數時,計算機會默認將其全部轉換為雙精度類型來進行運算和保存。
【示例3-27】輸出表達式的值占幾個字節。
程序如下:

運行程序,輸出以下內容:

從程序運行結果可以看出,表達式a+b的值占8個字節,這說明數值在計算時自動轉換為double類型。
3. 強制轉換
強制轉換又稱手動轉換。有時為了節約存儲空間或其他目的,程序員要將數值手動轉換為指定的數據類型。例如,表達式3.2+3.3的值會被自動存儲為雙精度類型,而為了節約空間,程序員可以將其強制轉換為單精度類型,這樣將節省很多存儲空間。
強制轉換的語法如下:

在該語法中,類型說明符的小括號是必須存在的,而表達式的小括號是可以不加的,但一定不要因為不寫小括號而產生歧義,如圖3.13所示。

圖3.13 產生歧義
【示例3-28】輸出表達式的值占幾個字節。
程序如下:

運行程序,輸出以下內容:

從程序運行結果可以看出,表達式a+b的值占4個字節,這說明數值在計算時被強制轉換為int類型。
注意:如果將所占存儲單元多的數據類型轉換為所占存儲單元少的數據類型,可能會導致溢出問題。
3.2.6 運算優先等級

在小學數學中,我們都知道算數的運算優先規則。在C語言中也一樣,當遇到復雜的帶有多個運算符的表達式時,就要注意遵守運算符的運算規則,該規則包含優先級與結合性兩部分。
1. 優先級
在算術運算中,當遇到不同優先級的運算符時要遵循運算符優先級的先后順序來進行運算。++與-的優先級是最高的;+與-的優先級是最低的;使用()可以改變運算的順序。運算符優先級如圖3.14所示。

圖3.14 運算符優先級
【示例3-29】輸出表達式的值。
程序如下:

運行程序,輸出以下內容:

在上面程序中,表達式的運算順序如圖3.15所示。

圖3.15 表達式的運算順序
2. 結合性
在表達式中,如果所有的運算符優先級相同時,就要遵循運算符結合性來進行運算。運算符結合性分為左結合與右結合。左結合的執行順序是從左向右,如四則運算符都是左結合的。右結合的執行順序是從右向左,如增量運算符是右結合的。
【示例3-30】輸出表達式的值。
程序如下:

運行程序,輸出以下內容:

在上面程序中,表達式的運算順序如圖3.16所示。

圖3.16 表達式的運算順序
注意:在書寫表達式時一定要注意運算符優先級問題,這樣才能讓計算機正確表示表達式的運算順序。
3.2.7 數值比較

在上體育課時,同學們會按照個子高低進行排隊。在這里,就涉及了身高的比較問題。在C語言中,提供數值比較的專用運算符-數值比較運算符。
數值比較運算符屬于二目運算符,擁有兩個操作數,可以用于兩個操作數的比較。將使用數值比較運算符構建的表達式稱為關系表達式。
關系表達式的語法如下:

在C語言中,提供了6個數值比較的運算符,如表3.3所示。
表3.3 數值比較運算符

【示例3-31】比較兩個數的大小。
程序如下:

運行程序,輸出以下內容:

在上面程序中,返回值為1,表示8確實小于10。
注意:由于小數類型的數值有保留小數點后精確位位數的問題,所以對有些值的判斷會出現誤差。
【示例3-32】比較兩個小數的大小。
程序如下:

運行程序,輸出以下內容:

在上面程序中,變量a的值3.000 000 008明顯是比變量b的值3.000 000 009小,返回值應該為1,但返回值卻為0,表示變量a是大于或等于變量b的。這里就是因為單精度類型小數只精確保留小數點后6~7位,從而出現判斷錯誤。
- iOS Game Programming Cookbook
- JavaScript前端開發模塊化教程
- UML+OOPC嵌入式C語言開發精講
- Learning ArcGIS for Desktop
- Scala程序員面試算法寶典
- 精通MATLAB(第3版)
- Android系統級深入開發
- Mastering C++ Multithreading
- Flask Web開發:基于Python的Web應用開發實戰(第2版)
- TypeScript High Performance
- Game Development Patterns and Best Practices
- 現代JavaScript編程:經典范例與實踐技巧
- jBPM6 Developer Guide
- Learning Scrapy
- 匯編語言程序設計教程