第一周:簡單的計算程序
1.1 第一個程序 Hello World!
集成開發環境(IDE)
下載Dev C++的地方是:
http://sourceforge.net/projects/orwelldevcpp/?source=directory
提示:Dev C++只能在windows操作系統下安裝
由於做c語言的編譯軟件的廠家很多,不同的廠家又有不同的方言。
因此我們統一用Dev C++軟件(集成開發環境),在上面的地址下載默認安裝即可。
提示:Dev C+= 是一款集成開發環境的軟件,包括編輯器、編譯器、調試器和圖形用戶界面等功能。
程序框架
#include <stdio.h>
int main(){
//你的代碼
return 0;
}
輸出
- printf("Hello World!\n");
- ""里面的內容叫做字符串,printf會把其中的內容原封不動的輸出
- \n表示需要在輸出的結果后面換一行
第一個Hello World
程序
#include <stdio.h>
int main(){
printf("Hello World!\n");
return 0;
}
執行結果:
Hello World!
程序語句及符號
- c語言每條語句以英文輸入狀態下的分號結束
- 大括號、小括號等其他的符號也是需要在英文狀態下輸入,換句話說只有雙引號里可以輸入中文或中文狀態下的各種符號。
- 分號和語句間可以隔空格字符或者換行等空白字符,編譯器一樣可以識別,但是不能缺少分號,否則程序就會報錯。
1.2 變量
如何輸入
- 輸入也在終端窗口中
- 輸入是以行為單位進行的,行的結束標志就是按下了回車鍵。在按下回車之前程序不會讀到任何東西。
變量賦值和初始化
- int price = 0;
- 這一行,定義了一個變量。變量的名字是price,類型是int,初始值是0.
- 變量是一個保存數據的地方,當我們需要在程序里保存數據時,就需要一個變量來保存它。
- price = 0 是一個式子,這個的
"="
是一個賦值運算符,表示將"="
右邊的值賦給左邊的變量。
變量定義
- 變量定義的一般形式:
- <類型名><變量名>;
- 例如
- int price;
- int amout;
- int price,amount; //等價於int price; int amount;
變量的名字
- 變量需要一個名字,變量的名字是一種
“標識符”
,意思是它是用來識別這個和那個的不同的名字。 - 標識符有標識符構造的規則,基本的原則是:
- 標識符只能由字母、數字和下划線組成
- 數字不可以出現在第一個位置上
- C語言的關鍵字(有的地方叫他們保留字)不可以用作標識符
賦值運算符"="
和數學的'"="'差異
- 和數學不同,a=b在數學中表示關系,即a和b的值一樣
- 而在程序設計中,a=b表示要求計算機做一個動作:將b的值賦給a
- 關系是靜態的,而動作是動態的。
- 在數學中,a=b和b=a是等價的,而在程序設計中,兩者的意思完全相反。
初始化
- 定義:當賦值發生在程序定義變量的時候就是變量的初始化。(定義變量並賦值)
- 所有變量在第一次使用之前都應該被賦值一次。
- 在c語言中如果變量沒有做初始化,變量會隨機指向內存中的某一個值,因此建議在聲明變量時就先初始化,否則可能導致程序運行出意外的結果。
變量初始化
- <類型名稱><變量名稱> = <初始值>;
- int price = 0;
- int amount = 100;
- 組合變量定義的時候,也可以在這個定義中單獨給單個變量賦初值,如:
- int price = 0,amount = 100;
變量類型
- C語言是一種有類型的語言,所有的變量在使用之前必須定義或聲明,所有的變量必須具有確定的數據類型。
- 數據類型表示在變量中可以存放什么樣的數據,變量中也只能存放指定類型的數據,程序運行過程中也不能改變變量的類型。
ANSI C
標准和C99
標准的定義變量的區別
ANSI C
只能在代碼開頭的地方定義變量。C99
在使用變量前定義變量即可。
讀取整數
- scanf("%d",&price);
- 要求scanf這個函數讀入下一個整數,讀到的結果賦值給變量price
常量
- int change = 100 - price;
- 固定不變的數,是常數。直接寫在程序里,我們稱作直接量(literal)
- 更好的方式,是定義一個常量:
- const int AMOUNT = 100; //
C99
- 常量的命名通常使用全大寫的方式命名,便於區分。
- 常量可以增加程序可讀性(見名知義)
- 常量便於修改,比如我們要修改上面的100就只需要修改初始化的地方就可以,而寫成直接量就需要修改每一個用到的地方。
- const int AMOUNT = 100; //
- const是一個修飾符,加在int的前面,用來給這個變量加上一個const(不變的)的屬性。這個const的數學表示這個變量的值一旦初始化,就不能再修改了。
- 如果你試圖對常量做修改,把它放在賦值運算符的左邊,就會被編譯器發現,指出為一個錯誤。
找零程序
假設有一個雜貨鋪,顧客有一張面額100的鈔票,要求設計一個程序給店主,輸入購買商品的總額並,並且計算出應該找零給顧客多少錢。
(假設金額都為整數且商品總額小於100)
#include <stdio.h>
int main(int argc, char *argv[]) {
const int AMOUNT = 100;
int change = 0;
int price = 0;
printf("請輸入金額(元):");
scanf("%d",&price);
change = AMOUNT - price;
printf("找您%d元。\n",change);
return change;
}
執行結果:
請輸入金額(元):98
找您2元。
附錄:C語言常見的保留字
auto,break,case,char,const,
continue,default,do,double,
else,enum,extern,float,for,
goto,if,int,long,register,return,
short,signed,sizeof,static,
struct,switch,typedef,union,
unsigned,void,volatile,while,
inline,restrict
1.3 計算
整數之間的運算
- 兩個整數的運算結果只能是整數
- 例如
10/3
在c語言中的運行結果為3
,c語言會自動抹掉小數后的部分(.3333...
)。
- 例如
10
和10.0
在C中是完全不同的數10.0
是浮點數,10
是整數
浮點數
- 帶小數點的數值
- 浮點這個詞的本意就是指小數點是浮動的(小數點在數字中出現的位置是可變的),是計算機內部表達非整數(包含分數和無理數)的一種方式。與浮點對應的計算機內部表達非整數的方式還有一種稱作定點數。
- 當浮點數和整數放到一起運算時,C會先將整數轉換成浮點數,然后再進行浮點數的運算
double
- double的意思是"雙",它本來是
“雙精度浮點數”
的第一個單詞,人們用來表示浮點數類型。 - 除了double,還有float(意思就是浮點!)表示單精度浮點數
整數和小數的輸入輸出
- 整數
- int
- printf("%d",...);
- scanf("%d",...);
- 帶小數點的數
- double
- printf("%f",...);
- scanf("%lf",...);
身高轉換程序
設計一個程序將英尺和英寸表達的升高轉換為米表達,例如5英尺7英寸表示1.701800
米。
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("請分別輸入身高的英尺和英寸,"
"如輸入\"5 7\"表示5英尺7英寸:");
double foot = 0;
double inch = 0;
scanf("%lf %lf",&foot,&inch);
printf("身高是%f米。\n",((foot + inch / 12) * 0.3048));
return 0;
}
執行結果:
請分別輸入身高的英尺和英寸,如輸入"5 7"表示5英尺7英寸:5 7
身高是1.701800米。
表達式
- 一個表達式是一系列運算符和算子的組合,用來計算一個值。
- 運算符(operator)是指進行運算的動作,比如加法運算符
"+"
,減法運算符"-"
- 算子(operand)是指參與運算的值,這個值可能是常數,也可能是變量,還可能是一個方法的返回值。
- 例如在表達式: change = AMOUNT - price; 中,change、AMOUNT和price全都是算子,"="和"-"則是算子。
時間差計算程序
#include <stdio.h>
// 計算第一個時間段和第二個時間之前的時間差,例如3點10分和1點30分 的時間差為1個小時40分鍾
int main(int argc, char *argv[]) {
int hour1, minute1;
int hour2, minute2;
printf("請輸入第一個時間,分別輸入小時和分鍾."
"輸入\"3 10\"表示3點10分:");
scanf("%d %d", &hour1, &minute1);
printf("請輸入第二個時間,分別輸入小時和分鍾."
"輸入\"1 30\"表示1點30分:");
scanf("%d %d", &hour2, &minute2);
int t1 = hour1 * 60 + minute1;
int t2 = hour2 * 60 + minute2;
int t= t1 - t2;
printf("時間差是%d小時%d分。",t / 60, t % 60);
return 0;
}
執行結果:
請輸入第一個時間,分別輸入小時和分鍾.輸入"3 10"表示3點10分:3 10
請輸入第二個時間,分別輸入小時和分鍾.輸入"1 30"表示1點30分:1 30
時間差是1小時40分。
算術符優先級
賦值運算符
- 賦值也是運算,也有結果
- a=6的結果是a被賦予的值,也就是6
- a=b=6 等價於 a=(b=6) 單目自右向左計算
嵌入式賦值
int a = 6;
int b;
int c = 1 + (b = a);
不建議使用嵌入式賦值,因為嵌入式賦值有以下兩個缺點:
- 不利於閱讀
- 容易產生錯誤
結合關系
- 一般自左向右
- 單目
"+"
、"-"
和賦值"="
自右向左
1.4 編程作業及課后討論
題目內容:
程序每次讀入一個正三位數,然后輸出逆序的數字。注意,當輸入的數字含有結尾的 0 時,
輸出不應帶有前導的 0。比如輸入 700,輸出應該是 7。
輸入格式:
每個測試是一個 3 位的正整數。
輸出格式:
輸出逆序的數。
輸入樣例:
123
輸出樣例:
321
解題思路:
- 首先我們需要兩個變量A和B,A存儲用戶的輸入數字,B存儲逆序的數字。(當然也可以只要一個變量A,逆序的數字直接輸出即可,這里為了便於理解聲明了兩個變量)
- 獲取用戶輸入的整數放入變量A
- 將變量A逆序放入變量B
- 輸出變量B
進一步分析,步驟三還需要做拆分。我們知道一個三位數由個位、十位和百位組成,因此我們需要做的就是將A的百位放到B的個位再將A的個位放到B的百位,最后得到的就是A的倒序的一個三位數了,列如123
將百位和十位互調的結果就是321
。
3.將變量A逆序放入變量B
3.1 取A的百位放到B的個位。
3.2 取A的十位放到B的十位。
3.3 取A的個位放到B的百位。
反轉數字
#include <stdio.h>
int main(int argc, char *argv[]) {
int a;
int b;
printf("請輸入一個三位的整數:");
scanf("%d",&a);
// 個位 + 十位 + 百位
b = a / 100 + a % 100 / 10 * 10 + a % 10 * 100;
printf("%d\n",b);
return 0;
}
執行結果:
請輸入一個三位的整數:123
321
擴展思考:到這里我們的程序算是符號題目要求了,但它還不是一個健壯的、好的程序。試想當用戶輸入的不是整數而是小數結果會怎么樣呢? 又或者用戶輸入的根本就不是數字呢? 並且我們的程序只能反轉三位數,如何反轉四位數、五位數甚至n位數呢?
討論題
標題:不好的表達式
內容:
看看如何分析這個表達式:
a=5;
b=0;
c = (b=a+2) - (a=2);
看看這個表達式的結果,會使得 c 是什么?為什么說這是個不好的表達式?
題目分析:
單目和賦值運算符自右向左,加、減、乘、除和取余運算符自左向右。
因此c = (b=a+2) - (a=2)
表達式的計算順序為:
- (b=a+2) -> 7
- (a=2) -> 2
- (b=a+2) -(a=2) -> 5
- c = (b=a+2) - (a=2) -> 5
通過計算我們知道最后的結果是5,
為什么說嵌套賦值是不要的表達式呢?
- 表達式不容易理解,一眼看不出這個表達式的計算順序,需要仔細的分析。
- 由於是嵌套表達式,a和b的值在運算的過程中是會發生變化的,比如我們要搞清楚b被我們賦值的那個值最后是否是我們希望的那個值就要格外小心,稍不留神就容易出錯。
我們可以試着把以上表達式拆分成下面的表達式。
a = 5;
b = a + 2;
a = 2;
c = b - a;
這樣是不是一目了然了呢?