1. 程式人生 > 實用技巧 >C語言入門經典(第5版)之程式設計初步

C語言入門經典(第5版)之程式設計初步

>>> hot3.png

現在讀者一定很渴望編寫程式,讓計算機與外界進行實際的互動。我們不希望程式只能做打字員的工作,顯示包含在程式程式碼中的固定資訊。的確,程式設計的內涵遠不止此。理想情況下,我們應能從鍵盤上輸入資料,讓程式把它們儲存在某個地方,這會讓程式更具多樣性。程式可以訪問和處理這些資料,而且每次執行時,都可以處理不同的資料值。每次執行程式時輸入不同的資訊正是整個程式設計業的關鍵。在程式中儲存資料項的地方是可以變化的,所以叫做變數(variable),而這正是本章的主題。

本章的主要內容:

●記憶體的用法及變數的概念

●在C中如何計算

●變數的不同型別及其用途

●強制型別轉換的概念及其使用場合

●編寫一個程式,計算樹木的高度

2.1 計算機的記憶體

首先看看計算機如何儲存程式要處理的資料。為此,就要了解計算機的記憶體,在開始編寫第一個程式之前,先簡要介紹計算機的記憶體。

計算機執行程式時,組成程式的指令和程式所操作的資料都必須儲存到某個地方。這個地方就是機器的記憶體,也稱為主記憶體(main memory),或隨機訪問儲存器(Random Access Memory,RAM)。RAM是易失性儲存器。關閉PC後,RAM的內容就會丟失。PC把一個或多個磁碟驅動器作為其永久儲存器。要在程式結束執行後儲存起來的任何資料,都應打印出來或寫入磁碟,因為程式結束時,儲存在RAM中的結果就會丟失。

可以將計算機的RAM想象成一排井然有序的盒子。每個盒子都有兩個狀態:滿為l,空為0。因此每個盒子代表—個二進位制數:0或1。計算機有時用真(true)和假(false)表示它們:1是真,0是假。每個盒子稱為—個位(bit),即二進位制數(binary digit)的縮寫。

注意:

如果讀者不記得或從來沒學過二進位制數,可參閱附錄A。但如果不明白這些內容,不用擔心,因為這裡的重點是計算機只能處理0與1,而不能直接處理十進位制數。程式使用的所有資料(包括程式指令)都是由二進位制陣列成的。

為了方便起見,記憶體中的位以8個為—組,每組的8位稱為一個位元組(byte)。為了使用位元組的內容,每個位元組用一個數字表示,第—個位元組用0表示,第二個位元組用1表示,直到計算機記憶體的最後—個位元組。位元組的這個標記稱為位元組的地址(address)。因此,每個位元組的地址都是唯一的。每棟房子都有一個唯一的街道地址。同樣,位元組的地址唯—地表示計算機記憶體中的位元組。

總之,記憶體的最小單位是位(bit),將8個位組合為一組,稱為位元組(byte)。每個位元組都有唯一的地址。位元組地址從0開始。位只能是0或1,如圖2-1所示。

圖2-1 記憶體中的位元組

計算機記憶體的常用單位是千位元組(KB)、兆位元組(MB)、千兆位元組 (GB)。大型磁碟驅動器使用兆兆位元組(TB)。這些單位的意義如下:

●1KB是1 024位元組。

●1MB是1 024KB,也就是1 048 576位元組。

●1GB是1 024MB,也就是1 073 741 841位元組。

●1TB是1 024GB,也就是1 099 511 627 776位元組。

如果PC有1GB的RAM,位元組地址就是0~1 073 741 841。為什麼不使用更簡單的整數,例如千、百萬或億?因為從0到1023共1024個數字,而在二進位制中,1023的10個位剛好全是l:11 1111 1111,它是一個非常方便的二進位制數。1000是很好用的十進位制數,但是在二進位制的計算機裡就不再那麼方便了,它是111110 1000。因此以KB(1 024位元組)為單位,是為了方便計算機使用。同樣,MB需要20個位,GB需要30個位。

但是硬碟的容量可能出現混亂。磁碟製造商常常宣稱他們生產的磁碟的容量是256GB或1TB,而實際上這兩個數字表示2560億位元組及1萬億位元組。當然,2560億位元組只有231MB,而1萬億位元組只有911GB,所以磁碟製造商給出的硬碟容量有誤導作用。

有了位元組的概念,下面看看如何在程式裡使用這些記憶體。

2.2 什麼是變數

變數是計算機裡一塊特定的記憶體,它是由一個或多個連續的位元組所組成,一般是1、2、4、8或16位元組。每個變數都有一個名稱,可以用該名稱表示記憶體的這個位置,以提取它包含的資料或儲存一個新數值。

下面編寫一個程式,用第1章介紹的printf()函式顯示你的薪水。假設你的薪水是10 000元/月,則很容易編寫這個程式。

// Program 2.1 What is a Variable?

#include <stdio.h>

int main(void)

{

printf("My salary is $10000");

return 0;

}

這個程式的工作方式不需要多做解釋,它和第一章開發的程式差不多。如何修改這個程式,讓它能夠根據儲存在記憶體中的值,定製要顯示的資訊?這有幾種方法,它們有一個共同點:使用變數。

在這個例子裡,可以分配一塊名為salary的記憶體,把值10 000儲存在該變數中。要顯示薪水時,可以使用給變數指定的名稱salary,將儲存在其中的值10 000顯示出來。程式用到變數名時,計算機就會訪問儲存在其中的值。變數的使用次數是不受限制的。當薪水改變時,只要改變salary變數儲存的值,整個程式就會使用新的值。當然,在計算機中,所有的值都儲存為二進位制數。

程式中變數的數量是沒有限制的。在程式執行過程中,每個變數包含的值由程式的指令來決定。變數的值不是固定的,而可以隨時改變,且沒有次數的限制。

注意:

變數可以有一個或多個位元組,那麼,計算機如何知道變數有多少個位元組?下一節會提到,每個變數都有型別來指定變數可以儲存的資料種類。變數的型別決定了為它分配多少個位元組。

變數的命名

給變數指定的名稱一般稱為變數名。變數的命名是很有彈性的。它可以是一個或多個大寫或小寫字母、數字和下劃線( _ )(有時下劃線也算作字母),但要以字母開頭。下面是一些正確的變數名:

Radius diameter Auntie_May Knotted_Wool D678

變數名不能以數字開頭,所以8_Ball和6_pack都是不合法的名稱。變數名只能包含字母、下劃線和數字,所以Hash!及Mary-Lou都不能用作變數名。Mary-Lou是一個常見的錯誤,但是Mary_Lou就是可以接受的。變數名中不能有空格,所以Mary Lou會被視為兩個變數名Mary和Lou。以一或兩個下劃線開頭的變數名常用在標頭檔案中,所以在給變數命名時,不要將下劃線用作第一個字元,以免和標準庫裡的變數名衝突。例如最好避免使用_this和_that這樣的變數名。變數名的另一個要點是,變數名是區分大小寫的,因此Democrat和democrat是不同的。

可以在上述限制內隨意指定變數名,但最好使變數名有助於瞭解該變數包含的內容,例如用變數名x來儲存薪水資訊就不好,而使用變數名salary就好得多,對其用途不會有什麼疑義。

警告:

變數名可以包含的字元數取決於編譯器,遵循C語言標準的編譯器至少支援31個字元,只要不超過這個長度就沒問題。建議變數名不要超過這個長度,因為這樣的變數名比較繁瑣,程式碼也難以理解。有些編譯器會截短過長的變數名。

2.3 儲存整數的變數

變數有幾種不同的型別,每種變數都用於儲存特定型別的資料。有幾種變數可儲存整數、非整數的數值和字元。一些型別儲存特定的資料(例如整數),它們之間的區別是它們佔用的記憶體量和可以儲存的數值範圍。首先看看用於儲存整數的變數。

整數是沒有小數點的數字。下面是一個例子:

123 10,999,000,000 20,000 88 1

這些數值是整數,但這對程式而言並不完全正確。整數是不能包含逗號的,所以第二個值在程式裡應該寫成10999000000,第三個值應寫成20000。

下面是一些不是整數的例子:

1.234 999.9 2.0 –0.0005 3.14159265

2.0一般算作整數,但是計算機不將它算作整數,因為它帶有小數點。在程式裡,必須把這個數字寫作2,不帶小數點。在C程式中,整數總是寫成不帶小數點的數字,如果數字中有小數點,就不是整數,而是浮點數,詳見後面的內容。在詳細討論整型變數之前,先看看程式裡一個簡單的變數,學習變數的用法。

試試看:使用變數

回到輸出薪水的例子。將前面的程式改為使用一個int型變數:

// Program 2.2 Using a variable

#include <stdio.h>

int main(void)

{

int salary; //Declare a variable called salary

salary = 10000; //Store 10000 in salary

printf("My salary is %d.\n", salary);

return 0;

}

輸入這個例子,編譯、連結並執行,會得到下面的結果:

My salary is 10000.

程式碼的說明

前三行和前一個例子相同,下面看看新的語句。用來存放薪水的變數宣告語句如下:

intsalary; //Declare a variable called salary

這個語句稱為變數宣告,因為它聲明瞭變數的名稱。在這個程式中,變數名是salary。

警告:

變數宣告語句以分號結束。如果漏掉分號,程式編譯時會產生錯誤。

變數宣告也指定了這個變數儲存的資料型別,這裡使用關鍵字int指定,salary用來存放一個整數。關鍵字int放在變數名稱之前。這是可用於儲存整數的幾個型別之一。

如後面所述,宣告儲存其他資料型別的變數時,要使用另一個關鍵字指定資料型別,其方式大致相同。

注意:

關鍵字是特殊的C保留字,對編譯器有特殊的意義。不能將它們用作變數名稱或程式碼中的其他實體,否則編譯器會生成錯誤訊息。

變數宣告也稱為變數的定義,因為它分配了一些儲存空間,來儲存整數值,該整數可以用變數名salary來引用。

注意:

宣告引入了一個變數名,定義則給變數分配儲存空間。有這個區別的原因在本書後面會很清楚。

當然,現在還未指定變數salary的值,所以此刻該變數包含一個垃圾值,即上次使用這塊記憶體空間時遺留在此的值。

下一個語句是:

salary= 10000; //Store 10000 in salary

這是一個簡單的算術賦值語句,它將等號右邊的數值儲存到等號左邊的變數中。這裡聲明瞭變數salary,它的值是10 000。將右邊的值10 000儲存到左邊的變數salary中。等號“=”稱為賦值運算子,它將右邊的值賦予左邊的變數。

然後是熟悉的printf()語句,但這裡的用法和之前稍有不同:

printf("My salary is %d.",salary);

括號內有兩個引數,用逗號分開。引數是傳遞給函式的值。在這個程式語句中,傳給printf()函式的兩個引數如下:

●引數1是一個控制字串,用來控制其後的引數輸出以什麼方式顯示,它是放在雙引號內的字串,也稱為格式字串,因為它指定了輸出資料的格式。

●引數2是變數名salary。這個變數值的顯示方式是由第一個引數——控制字串來確定。

這個控制字串和前一個例子相當類似,都包含一些要顯示的文字。但在本例的這個字串中有一個%d,它稱為變數值的轉換說明符(conversion specifier)。

轉換說明符確定變數在螢幕上的顯示方式,換言之,它們指定最初的二進位制值轉換為什麼形式,顯示在螢幕上。在本例中使用了d,它是應用於整數值的十進位制說明符,表示第二個引數salary輸出為一個十進位制數。

注意:

轉換說明符總是以%字元開頭,以便printf()函式識別出它們。控制字串中的%總是表示轉換說明符的開頭,所以如果要輸出%字元,就必須用轉義序列%%。

試試看:使用更多的變數

試試一個稍大的程式:

// Program 2.3 Using more variables

#include <stdio.h>

int main(void)

{

int brothers; //Declare a variable called brothers

int brides; //and a variable called brides

brothers = 7; //Store 7 in the variable brothers

brides = 7; //Store 7 in the variable brides

// Display some output

printf("%d brides for %d brothers\n", brides, brothers);

return 0;

}

執行程式的結果如下:

7 brides for 7 brothers;

程式碼的說明

這個程式和前一個例子相當類似。首先宣告兩個變數brothers和brides,語句如下:

int brothers; //Declare a variable called brothers

int brides; //and a variable called brides

兩個變數都宣告為int型別,都儲存整數值。注意,它們在兩個語句中宣告。由於這兩個變數的型別相同,故可以將它們放在同一行程式碼上宣告:

int brothers, brides;

在一個語句中宣告多個變數時,必須用逗號將資料型別後面的變數名分開,該語句要用分號結束。這是一種很方便的格式,但有一個缺點:每個變數的作用不很明顯,因為它們全放在一行程式碼上,不能加入註釋來描述每個變數。因此可以將它們分成兩行,語句如下:

int brothers, //Declare a variable called brothers

brides; //and a variable called brides

將語句分成兩行,就可以加入註釋了。這些註釋會被編譯器忽略,因此和最初沒加入註釋的語句相同。可以將C語句分成好幾行。分號決定語句的結束,而不是程式碼行的結束。

當然也可以編寫兩個宣告語句。一般最好在一個語句中定義一個變數。變數宣告常常放在函式的可執行語句的開頭,但這不是必須的。一般把要在一塊程式碼中使用的變數宣告放在該起始括號的後面。

之後的兩個語句給兩個變數賦值7:

brothers = 7; // Store 7 in the variable brothers

brides = 7; // Store 7 in the variable brides

注意,宣告這些變數的語句放在上述語句之前。如果遺漏了某個宣告,或把宣告語句放在後面,程式就不會編譯。變數在其宣告之前在程式碼中是不存在的,必須總是在使用變數之前宣告它。

下一個語句呼叫printf()函式,它的第一個引數是一個控制字串,以顯示一行文字。這個字串還包含規範,指定後續引數的值如何解釋和顯示在文字中。這個控制字串中的兩個轉換說明符%d會分別被printf()函式的第二個引數brides和第三個引數brothers的值取代:

printf("%dbrides for %d brothers\n", brides, brothers);

轉換說明符按順序被printf()函式的第二個引數brides和第三個引數brothers的值取代:變數brides的值對應第一個%d,變數brothers的值對應第二個%d。如果將設定變數值的語句改為如下所示,將會更清楚:

brothers = 8; // Store 8 in the variable brothers

brides = 4; // Store 4 in the variable brides

在這個比較明確的例子中,printf()語句會清楚地顯示變數和轉換說明符的對應關係,因為輸出如下所示:

4 brides for 8 brothers

為了演示變數名是區分大小寫的,修改printf()函式,使其中一個變數名以大寫字母開頭,如下所示:

// Program 2.3A Using more variables

#include <stdio.h>

int main(void)

{

int brothers; // Declare a variable called brothers

int brides; // and a variable called brides

brothers = 7; // Store 7 in the variable brothers

brides = 7; // Store 7 in the variable brides

// Display some output

printf("%d brides for %d brothers\n", Brides, brothers);

return 0;

}

編譯這個版本的程式時,會得到一個錯誤資訊。編譯器把brides和Brides解釋為兩個不同的變數,所以它不理解Brides這個變數,因為沒有宣告它。這是一個常見的錯誤,如前所述,打字和拼寫錯誤是出錯的一個主要原因。變數必須在使用之前宣告,否則編譯器就無法識別,將該語句標識為錯誤。

2.3.1 變數的使用

前面介紹瞭如何宣告及命名變數,但這和在第一章學到的知識相比並沒有太多用處。下面編寫另一個程式,在產生輸出前使用變數的值。

試試看:作一個簡單的計算

這個程式用變數的值做簡單的計算:

// Program 2.4 Simple calculations

#include <stdio.h>

int main(void)

{

int total_pets;

int cats;

int dogs;

int ponies;

int others;

// Set the number of each kind of pet

cats = 2;

dogs = 1;

ponies = 1;

others = 46;

// Calculate the total number of pets

total_pets = cats + dogs + ponies + others;

printf("We have %d pets in total\n", total_pets); // Output the result

return 0;

}

執行程式的結果如下:

Wehave 50 pets in total

程式碼的說明

與前面的例子一樣,大括號中的所有語句都有相同的縮排量,這說明這些語句都包含在這對大括號中。應當仿效此法組織程式,使位於一對大括號之間的一組語句有相同的縮排量,使程式更易於理解。

首先,定義5個int型別的變數:

int total_pets;

int cats;

int dogs;

int ponies;

int others;

因為這些變數都用來存放動物的數量,它們肯定是整數,所以都宣告為int型別。

下面用4個賦值語句給變數指定特定的值:

cats = 2;

dogs = 1;

ponies = 1;

others = 46;

現在,變數Total_Pets還沒有設定明確的值,它的值是使用其他變數進行計算的結果:

total_pets= cats + dogs + ponies + others;

在這個算術語句中,把每個變數的值加在一起,計算出賦值運算子右邊的所有寵物數的總和,再將這個總和儲存到賦值運算子左邊的變數Total_Pets中。這個新值替代了儲存在變數Total_Pets中的舊值。

printf()語句顯示了變數Total_Pets的值,即計算結果:

printf("Wehave %d pets in total\n", total_pets);

試著改變某些寵物的值,或增加一些寵物。記住要宣告它們,給它們設定數值,將它們加進變數Total_Pets中。

2.3.2 變數的初始化

在上面的例子,用下面的語句宣告每個變數:

intcats; //The number of cats as pets

用下面的語句設定變數Cats的值:

Cats = 2;

將變數Cats的值設為2。這個語句執行之前,變數的值是什麼?它可以是任何數。第一個語句建立了變數Cats,但它的值是上一個程式在那塊記憶體中留下的數值。其後的賦值語句將變數Cats的值設定為2。但最好在宣告變數時,就初始化它,語句如下所示:

int Cats = 2;

這個語句將變數Cat宣告為int型別,並設定初值為2。宣告變數時就初始化它一般是很好的做法。它可避免對初始值的懷疑,當程式運作不正常時,它有助於追蹤錯誤。避免在建立變數時使用垃圾值,可以減少程式出錯時計算機崩潰的機會。隨意使用垃圾值可能導致各種問題,因此從現在起,就養成初始化變數的好習慣,即使是0也好。

上面的程式是第一個真正做了些事情的程式。它非常簡單,僅僅相加了幾個數字,但這是非常重要的一步。它是運用算術語句進行運算的一個基本例子。下面介紹一些更復雜的計算。

1. 基本算術運算

在C語言中,算術語句的格式如下:

變數名= 算術表示式;

賦值運算子右邊的算術表示式指定使用變數中儲存的值和/或明確給出的數字,以及算術運算子如加(+)、減(-)、乘(*)及除(/)進行計算。在算術表示式中也可以使用其他運算子,如後面所述。

前面例子中的算術語句如下:

total_pets= cats + dogs + ponies + others;

這個語句先計算等號右邊的算術表示式,再將所得的結果存到左邊的變數中。

在C語言中,符號“=”定義了一個動作,而不是像數學中那樣說明兩邊相等。它指定將右邊表示式的結果存到左邊的變數中。因此可以編寫下面的語句:

total_pets= total_pets + 2;

以數學的觀點來看,它是很荒唐的,但對程式設計而言它是正確的。假定重新編寫程式,新增上面的語句。添加了這個語句的程式段如下:

total_pets = cats + dogs + ponies + others;

total_pets =total_pets + 2;

printf("The total number of petsis: %d", total_pets);

在執行完第一個語句後,Total_Pets的值是50。之後,第二行提取Total_Pets的值,給該值加2,再將結果儲存回變數Total_Pets。因此最後顯示出來的總數是52。

注意:

在賦值運算中,先計算等號右邊的表示式,然後將結果存到等號左邊的變數中。新的值取代賦值運算子左邊的變數中的原值。賦值運算子左邊的變數稱為lvalue,因為在這個位置可以儲存一個值。執行賦值運算子右邊的表示式所得的值稱為rvalue,因為它是計算表示式所得的一個值。

計算結果是數值的表示式稱為算術表示式,下面都是算術表示式:

3 1 + 2 total_pets cats + dogs – ponies -data

計算這些表示式,都會得到一個數值。注意,變數名也是一個表示式,它的計算結果是一個值,即該變數包含的值。最後一個例子的值是data的負值,所以如果data包含-5,表示式-data的值就是5。當然,data的值仍是-5。稍後將詳細討論如何構建表示式,並學習運算規則。這裡先用基本算術運算子做一些簡單的例子。表2-1列出了這些算術運算子。

表2-1 基本算術運算子

運 算 符

動 作

+

-

*

/

%

取模(Modulus)

應用運算子的資料項一般稱為運算元,兩邊的運算元都是整數時,所有這些運算子都生成整數結果。前面沒有提到過取模運算子。它用運算子左邊的表示式值去除運算子右邊的表示式值,並求出其餘數,所以有時稱為餘數運算子。表示式12 % 5的結果是2。因為12除以5的餘數是2。下一節將詳細介紹。所有這些運算子的工作方式都與我們的常識相同,只有除法運算子例外,它應用於整數時有點不直觀。下面進行一些算術運算。

注意:

應用運算子的值稱為運算元。需要兩個運算元的運算子(如%)稱為二元運算子。應用於一個值的運算子稱為一元運算子。因此-在表示式a-b中是二元運算子,在表示式-data中是一元運算子。

試試看:減和乘

下面基於食物的程式演示了減法和乘法:

// Program 2.5 Calculations with cookies

#include <stdio.h>

int main(void)

{

int cookies = 5;

int cookie_calories = 125; //Calories per cookie

int total_eaten = 0; //Total cookies eaten

int eaten = 2; // Number to be eaten

cookies = cookies - eaten; // Subtract number eaten fromcookies

total_eaten = total_eaten + eaten;

printf("\nI have eaten %d cookies. There are %d cookies left",

eaten, cookies);

eaten = 3; // New value for cookies eaten

cookies = cookies - eaten; // Subtract number eaten from cookies

total_eaten = total_eaten + eaten;

printf("\nI have eaten %d more. Now there are %d cookiesleft\n", eaten, cookies);

printf("\nTotal energy consumed is %dcalories.\n", total_eaten*cookie_calories);

return 0;

}

這個程式產生如下輸出:

I have eaten 2 cookies. There are 3 cookies left

I have eaten 3 more. Now there are 0cookies left

Total energy consumedis 625 calories.

程式碼的說明

首先宣告並初始化3個int型別的變數:

int cookies = 5;

int cookie_calories =125; //Calories per cookie

int total_eaten = 0; //Total cookies eaten

在程式中,使用變數total_eaten計算吃掉的餅乾總數,所以要將它初始化為0。

下一個宣告並初始化的變數儲存吃掉的餅乾數,如下:

inteaten = 2; // Number to be eaten

用減法運算子從cookies中減掉eaten:

cookies= cookies - eaten; //Subtract number eaten from cookies

減法運算的結果存回cookies變數,所以cookies的值變成3。因為吃掉了一些餅乾,所以要給total_eaten增加吃掉的餅乾數:

total_eaten= total_eaten + eaten;

將eaten變數的當前值2加到total_eaten的當前值0上,結果儲存回變數total_eaten。printf()語句顯示剩下的餅乾數:

printf("\nI have eaten %d cookies. There are%d cookies left",

eaten, cookies);

這個語句在一行上放不下,所以在printf()的第一個引數後的逗號後面,將該語句的其他內容放在下一行上。可以像這樣分拆語句,使程式易於理解,或放在螢幕的指定寬度之內。注意不能用這種方式拆分第一個字串引數。不能在字串的中間放置換行符。需要將字串拆開成兩行或多行時,一行上的每一段字串必須有自己的一對雙引號。例如,上面的語句可以寫成:

printf("\nI have eaten %d cookies. "

" There are %d cookies left",

eaten, cookies);

如果兩個或多個字串彼此相鄰,編譯器會將它們連線起來,構成一個字串。

用整數值的轉換說明符%d將eaten和cookies的值顯示出來。在輸出字串中,eaten的值取代第一個%d, cookies的值取代第二個%d。字串在顯示之前會先換行,因為開頭處有一個\n。

下一個語句將變數eaten的值設為一個新值:

eaten= 3; // New value for cookies to beeaten

新值3取代eaten變數中的舊值2。然後完成和以前一樣的操作序列:

cookies = cookies - eaten; // Subtract numbereaten from cookies

total_eaten =total_eaten + eaten;

printf("\nI have eaten %d more.Now there are %d cookies left\n", eaten, cookies);

最後,在執行return語句,結束程式前,計算並顯示被吃掉餅乾的卡路里數:

printf("\nTotalenergy consumed is %d calories.\n", total_eaten*cookie_calories);

printf()函式的第二個引數是一個算術表示式,而不是變數。編譯器會將表示式total_eaten*cookie_calories的計算結果儲存到一個臨時變數中,再把該值作為第二個引數傳送給printf()函式。函式的引數總是可以使用算術表示式,只要其計算結果是需要的型別即可。

下面看看除法和取模運算子。

試試看:除法和取模運算子

假設你有一罐餅乾(其中有45塊餅乾)和7個孩子。要把餅乾平分給每個孩子,計算每個孩子可得到幾塊餅乾,分完後剩下幾塊餅乾。

// Program 2.6 Cookies and kids

#include <stdio.h>

int main(void)

{

int cookies = 45; //Number of cookies in the jar

int children = 7; //Number of children

int cookies_per_child = 0; //Number of cookies per child

int cookies_left_over = 0; // Number of cookiesleft over

// Calculate how many cookies each child gets when they are divided up

cookies_per_child = cookies/children; //Number of cookies per child

printf("You have %d children and %d cookies\n", children,cookies);

printf("Give each child %d cookies.\n",cookies_per_child);

// Calculate how many cookies are left over

cookies_left_over = cookies%children;

printf("There are %d cookies left over.\n", cookies_left_over);

return 0;

}

執行程式後的輸出:

You have 7 children and 45 cookies

Give each child 6cookies.

There are 3 cookiesleft over.

程式碼的說明

下面一步一步地解釋這個程式。下面的語句宣告並初始化4個整數變數:cookies、children、cookies_per_child、cookies_left_over:

int cookies = 45; // Number of cookies in the jar

int children = 7; // Number of children

int cookies_per_child= 0; //Number of cookies per child

int cookies_left_over = 0; //Number of cookies left over

使用除號運算子“/”將餅乾數量除以孩子的數量,得到每個孩子分得的餅乾數:

cookies_per_child= cookies/children; //Number of cookies per child

下面兩個語句輸出結果,即cookies/children變數的值:

printf("You have %d children and %dcookies\n", children, cookies);

printf("Give each child %dcookies.\n", cookies_per_child);

從輸出結果可以看出,cookies_per_child的值是6。這是因為當運算元是整數時,除法運算子總是得到整數值。45除以7的結果是6,餘3。下面的語句用取模運算子計算餘數:

cookies_left_over= cookies%children;

賦值運算子右邊的表示式計算cookies除以children得到的餘數。最後一個語句輸出餘數:

printf("Thereare %d cookies left over.\n", cookies_left_over);

2. 深入瞭解整數除法

當一個運算元是負數時,使用除法和模數運算子的結果是什麼?在執行除法運算時,如果運算元不同號,結果就是負數。因此,表示式-45/7和45/-7的結果相同,都是-6。如果運算元同號,都是正數或都是負數,結果就是正數。因此45/7和-45/-7結果都是6。至於模數運算子,不管運算元是否同號,其結果總是和左運算元的符號相同。因此45%-7等於3,-45/7等於-3,-45/-7也等於-3。

3. 一元運算子

例如,乘法運算子是一個二元運算子。因為它有兩個運算元,其結果是一個運算元乘以另一個運算元。還有一些運算子是一元運算子,即它們只需一個運算元。後面將介紹更多的例子。但現在看看一個最常用的一元運算子。

4. 一元減號運算子

前面使用的運算子都是二元運算子,因為它們都操作兩個資料項。C語言中也有操作一個數據項的一元運算子。一元減號運算子就是一個例子。若運算元為負,它就生成正的結果,若運算元為正,它就生成負的結果。要了解一元減號運算子的使用場合,考慮一下追蹤銀行賬號。假定我們在銀行存了200元。在簿子裡用兩列記錄這筆錢的收支情況,一列記錄付出的費用,另一列記錄得到的收入,支出列是負數,收入列是正數。

我們決定購買一片價值50元的CD和一本價值25元的書。假使一切順利,從銀行的初始值中減掉支出的75元后,就得到了餘額。表2-2說明這些項的記錄情況。

表2-2 收入與支出記錄

收 入

支 出

存 款 餘 額

支票收入

$200

$200

CD

$50

$150

$25

$125

結餘

$200

$75

$125

如果將這些數字儲存到變數中,可以將收入及支出都輸入為正數,只有計算餘額時,才會把這些數字變成負數。為此,可以將一個負號(-)放在變數名的前面。

要把總支出輸出為負數,可編寫如下語句:

int expenditure = 75;

printf("Your balance has changedby %d.", -expenditure);

這會產生如下結果:

Yourbalance has changed by -75.

負號表示花掉了這筆錢,而不是賺了。注意,表示式-expenditure不會改變expenditure變數的值,它仍然是75。這個表示式的值是-75。

在表示式-expenditure中,一元減號運算子指定了一個動作,其結果是翻轉expenditure變數的符號:將負數變成正數,將正數變成負數。這和編寫一個負數(如-75或-1.25)時使用的負號運算子是不同的。此時,負號不表示一個動作,程式執行時,不需要執行指令。它只是告訴編譯器,在程式裡建立一個負的常量。



小結:C語言是每一位程式設計師都應該掌握的基礎語言。C語言是微軟.NET程式設計中使用的C#語言的基礎;C語言是iPhone、iPad和其他蘋果裝置程式設計中使用的Objective-C語言的基礎;C語言是在很多環境中(包括GNU專案)被廣泛使用的C++語言的基礎。C語言也是Linux作業系統及其很多功能的基礎。學習C語言可以給程式設計職業生涯提供牢固的基礎,也有助於更好地理解更為現代的語言(如Java)。

《C語言入門經典(第5版)》主要介紹最基礎的計算機語言之一——C語言。本書從最基礎的內容開始,步步深入講解作為一位稱職的C語言程式設計師應該具備的知識和技能。





C語言入門經典(第5版)》試讀電子書免費提供,有需要的留下郵箱,一有空即傳送給大家。 別忘啦頂哦!



轉載於:https://my.oschina.net/cjkall/blog/195969