Transcript C語言教學投影片
outline
安裝環境
Hello world
Data type
Printf & scanf
運算子
條件運算式
loop
Break , continue , goto
Function
Pointer
Struct
stack
http://download.eclipse.org/tools/cdt/releases/
galileo.
#include <stdio.h>
這一條並非C語言的命令,而是屬於C語言前置處理程式
(preprocessor)所管理的指令(Directive),#define也是
這類指令。簡單地說,這條假指令的目的就是於該處引進
(include)檔案stdio.h的全部內容,其結果正如同我們於
該處鍵入stdio.h檔案內容一般。
檔案stdio.h乃系統所附的檔案,這類檔案泛稱為標頭檔
(Header file),由其附加檔案.h即可看出它的意義。
stdio.h的實際意義為標準輸入輸出標頭檔,檔案中定
義了許多重要的常數(Constant)以及函式原型宣告
(Function prototype declaration)或語法(Syntax)
的宣告,譬如程式中使用到的printf( )函式的語法,
是放在stdio.h的標頭檔裏,而system()庫存函式的語
法則放在stdlib.h標頭檔中。
外圍是unsigned short int所表
示的範圍從0到65535。
Printf & scanf
脫逸序列
符號
\a
\b
\f
\n
\r
\t
\v
\\
\"
\0oo
\xhh
意義
警告聲(ANSI C)
退格
換頁
換列
游標回頭(Carriage Return)
水平跳位(tab)
垂直跳位(tab)
反斜線
雙引號
八進位數值
十六進位數值
函式scanf()
printf()函式主要功能是作為輸出之用,而相對應的輸入函式則為
scanf(),它的參數型態與printf()差不多。
scanf(format,item1,item2,....,itemN);
format仍然是一個控制字串,其中還是由%和轉換字元組合而成,
後面的每一項資料都要與前面的轉換規格吻合。
17
18
和printf()間最重要的一點差異是scanf()中的資料項都必須是變
數的位址;目前我們所知的作法就是在單純變數前加入&運算子。
請看底下的範例:
int num;
我們宣告了int型態的變數num,若想由鍵盤讀入num的數值,就該
這麼做:
scanf("%d", &num);
19
單引號內的%d意謂著程式將等待一個十進位整數的輸入,至於輸
入的資料則放在&num這個位址上,從此之後,變數便擁有剛剛輸
入的數值。千萬別寫成
scanf("%d", num);
這是初學者常犯的錯誤。
scanf()的控制字串與printf()十分類似,都允許具有選擇性的欄位。
算術運算子
表4-1 算術運算子
運算子
運作
+
加法
-
減法
*
乘法
/
除法
餘數運算子
餘數運算子(modular operator)的表示記號為'%',同樣是二元運
算子:
a % b
該運算子可取得a除以b後所留下的餘數,特別注意的是:本運算子
僅能作用於整數型態;換句話說,a和b這兩個運算元都必須是整數
資料。
遞增與遞減運算子
遞增運算子可依運算子的位置不同而有兩種形式:第一種是++出現
於運算元前面,即所謂的“前置”(prefix)模式;另一種則為++位
於運算元之後,即“後繼”(postfix)模式。
++num;
前置模式
num++;
後繼模式
位元運算子
C語言共擁有四種位元運算子(bitwise operator):
~(NOT), &(AND),|(OR),以及^(XOR),它們均運作於
整數型態的資料上。另外還有兩個位移運算子(shift
operator):<<(左移)與>>(右移),它們能將位元內容
分別向左或向右遞移指定的次數。
7
6
5
4
3
2
1
0
當我們說位元0時即代表最右邊的低次位元,而位元7則
為最左方的高次位元
if敘述與關係運算子
if敘述又稱為“分支敘述 (branching statement)”
if後面至少有個小括號,小括號裡面乃為一般的運算式,譬如(a>b)(a大於b)
或是(x == y)(x等於y)等等。
關係運算子便可組成關係運算式。C語言共提供六種關係運算子,
它們都是二元運算子
表 5-1
運算子
關係運算子
<
<=
==
意義
小於
小於等於
等於
>=
大於等於
>
!=
大於
不等於
28
If & else if & else
執行情形
What's your score ? 114
It's impossible !
What's your score ? 91
Score 91 ===> A
What's your score ? 14
You are down !
29
Switch
while迴圈
while迴圈的工作原理:
首先對expression運算式加以求值,若結果
為真(即非零值),那麼statement部分便會執
行;一旦執行完畢後,控制權又回到
expression測試
這種過程一直持續到expression的求值結果
變成假(即0)為止,然後才結束while敘述。
在邏輯上,整個while迴圈乃為單一敘述。
以流程圖可將while結構列示於下:
do....while迴圈
首先執行statement敘述(不論是單一的或是複合的),然後再對expression
進行求值,如果為假,迴圈敘述便就此結束,否則還要回到statement繼續
執行:
整個do....while同樣被視為單一敘述,別忘記while (expression)後
面的分號。在迴圈本體中,應該要有某些敘述可使最後的測試條件
變為假,否則就會陷入"無窮迴圈"(infinite loop)的狀況。
for迴圈
initial:此敘述僅在第一次進入迴圈時執行一次,往後便不再執
行。
test:即一般的測試運算式,在進入迴圈本體前,test敘述將先行
求值;若求值結果為假,就立即跳出for迴圈;否則便執行
statement敘述(單一或是複合)。
update:凡是執行完statement本體敘述後,update敘述將接著
執行,以改變某些測試條件。然後再回到test測試,重複同樣的循
環。
這三個敘述分別可以省略,也可以有多個敘述,若省略initial或test,
其後面的「;」還是要寫出來。
for迴圈的示意圖如下:
逗號運算子
逗號(,)除了在變數宣告時用來分隔同類型的變數名稱外,它本身
還是一種運算子,稱作逗號運算子(comma operator)。
多於一個以上的運算式可用逗號加以分隔,它有兩種重要的特性。
1.所有被逗號分隔的運算式將按由左向右的方向依序加
以求值。
2.整個逗號運算式的值乃為最右邊之運算式的值。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x, y, z;
printf("
x
y\n\n");
for(x=1, y=10; x<=6 && y<=60; x++, y=y+10)
printf("
%d
%d\n", x, y);
printf("\n");
}
z = (x=100, (y = 1000) +14);
printf("x = %d
y = %d z = %d\n", x, y, z);
x
y
1
2
3
4
5
6
10
20
30
40
50
60
x = 100 y = 1000 z = 1014
Break & Continue
break可以離開目前switch、for、while、do while的區塊,並前進至區塊
後下一個陳述句,在switch中主要用來結束陳述句進行至下一個case的比
對,在for、while與do while中,主要用於中斷目前的迴圈執行,如果
break出現並不是內含在for、while迴圈中或switch陳述中,則會發生編譯
錯誤, break的例子我們之前看過不少,這邊不再舉例。
continue的作用與break類似,主要使用於迴圈,所不同的是break會結束
區塊的執行,而continue只會結束接下來區塊中的陳述句,並 跳回迴圈區
塊的開頭繼續下一個迴圈,而不是離開迴圈
goto是一個很方便,但是最不被建議使用的語法,濫用它的話會破壞程式的架
構、使得程式的邏輯難以trace,事實上,在完全不使用goto的情況下, 您也
可以使用結構化的語法來撰寫程式。
goto可以在程式中任意跳躍,跳躍前必須先設定好目的地,跳躍時必須指定目
的地,例如:
start:
....
....
goto start;
變數儲存種類
C語言主要提供四種變數儲存種類:自動(auto)、靜態(static)、外
部(extern)、以及暫存器(register)等等。宣告這些儲存種類的時
候,只要在一般的變數宣告敘述前加上明確的關鍵字即可:
auto int num, value;
static char ch = 'A';
extern double ary[20];
register int cache;
auto:只使用在 function 中的本地變數,以下兩行宣告,結果一樣,所以
一般都會省略 auto 宣告。
register:宣告變數存儲在 register 而不是 RAM,可以加快存取速度。
static:維持變數值存在於程式執行過程。
extern:宣告變數為全域變數,也就是程式中的任何檔案都看得到這個變數。
Static
指標
所謂的指標(Pointer),就是記憶體的地址。換句話說,把記憶體比喻成大樓,
大樓裡每層都有其位址,而指標變數主要就是儲存某個東西在「第xxxxx樓」。
開始的時候。變數num位於0x7fffcdc3361c的地方,而其內含值
為10;至於此時的指標變數ptr_num則是未定義的:
&num=
0x7fffcdc3361c
10
&ptr_num =
0x7fffcdc33610
程式中有條極為重要的敘述:
ptr_num = #
於是會造成底下的結果:
&num=
0x7fffcdc3361c
10
&ptr_num = 0x7fffcdc33610
0x7fffcdc3361c
int a[6];
記憶體位址→ 0012FF68
0012FF6C 0012FF70 0012FF74 0012FF78
0012FF7C
指標記號→
a
a+1
a+2
a+3
a+4
a+5
陣列元素→
a[0]
a[1]
a[2]
a[3]
a[4]
a[5]
程式中
int *ptr[3]
由於[]比*的運算優先順序來得高,因此ptr[3]是一個陣列,此陣列
有3個元素,每一個元素都是指向int的指標。
1
ptr
ptr+1
ptr[0]
ptr[1]
2
3
4
5
6
7
ptr+2
ptr[2]
8
9
10
11
12
malloc()、free()、calloc() 與 realloc()
到目前為止,都是事先宣告好所要使用的變數,當程式開始執行時,這些變
數就會自動被配置記憶體空間。
然而有些變數並不知道何時會被使用,您希望在使用到的時候再配置空間給
變數,並在變數不使用的時候,將變數所佔有的空間清掉,這時候我們可以
使 用malloc()與free()函式。
舉個簡單的例子來說,您可以在程式中以動態的方式來配置一個int型態大小
的記憶體
realloc
如果要改變先前配置的記憶體大小,則可以使用realloc(),您必須先使用
malloc()、calloc()或realloc()配置記憶體,而後使用所得到的位址來使用
realloc()重新配置記憶體大小
struct
struct 是C中用來包裝資料的關鍵字,使用struct來包資料時,會考慮這些
資料的相關性,將它包在一起,
例如學生會有學號、姓名、住址、電話等, 您可以使用struct來定義一個
Student型態,這個型態中包括了學號、姓名、住址、電話等資訊,接著您
可以使用Student來宣告新的資料,進行資料指定或取出等。
union
union為早期 C 語言為了解決記憶體不足而有的資料型態,其定義與宣告與
結構類似,不同之處為union的所有成員佔用相同的記憶體空間,因此儲存
到聯合的值會以該成員具有儲存範圍最大的資料型態為優先,也就是佔用到
最多位元組數的資料型態
Stack
makefile
Makefile在許多中大型的程式專案中時常被使用,主要原因是沒有了它,開
發程式會很沒效率,它可以用來加速程式編譯的過程,原理是它會很聰明地
只挑修改過的檔案加以重新編譯連結,上次已編譯過且其原始碼並無更動過
的檔案,它便會略過重新編譯的步驟。