1.編輯 |
利用文書編輯器(editor)撰寫或修改C程式碼(source code)。 |
2.前置處理 |
前置處理器(preprocessor)在編譯前自動執行,依據程式碼#標示的指令(preprocessor
directives)進行代換或插入。例如:#include <stdio.h>指示編譯器在編譯前,將程式庫的標頭檔stdio.h插入該位置。 |
3.編譯 |
編譯器(compiler)將程式碼編譯為目的碼(object code)。 |
4.連結 |
連結器(linker)將一個或多個目的檔(.obj)與靜態程式庫檔(.lib)連結,產生可執行檔(.exe)。 |
5.載入 |
載入器(loader)將可執行檔(.exe)載入記憶體,並與動態程式庫檔(.dll)連結。 動態程式庫可減少執行檔占用硬碟與記憶體的空間。 |
6.執行 |
在CPU控制下,執行載入程式。 |
15-9.2變數與資料型態
15-9.2.1變數與常數
變數(variable) |
值會因程式執行而變動。 |
常數(constant) |
值不會隨程式處理過程而變動。 |
15-9.2.2資料型態
資料型態 |
儲存空間(Bytes) |
值範圍 |
int |
4 |
-2,147,483,648
~ 2,147,483,647 |
unsigned int |
4 |
0
~ 4,294,967,295 |
short |
2 |
-32,768
~ 32,767 |
unsigned short |
2 |
0
~ 65,535 |
long |
4 |
-2,147,483,648
~ 2,147,483,647 |
unsigned long |
4 |
0
~ 4,294,967,295 |
char |
1 |
-128
~ 127 |
unsigned char |
1 |
0
~ 255 |
float |
4 |
10-38
~ 1038 |
double |
8 |
10-308
~ 10308 |
bool |
1 |
false或true |
15-9.2.3變數的命名原則:變數必須在使用前宣告
1.不能使用保留字
2.只有前8個字元為有效字元
3.可使用英文字母、數字或底線
4.變數名稱中間不可以有空白
5.第一個字元不可為數字
6.變數名稱要有意義,且長短適中
7.大小寫有別
15-9.2.4保留字
auto |
break |
case |
char |
const |
continue |
default |
do |
double |
else |
enum |
extern |
float |
for |
goto |
if |
inline |
int |
long |
register |
restrict |
return |
short |
signed |
sizeof |
static |
struct |
switch |
typedef |
union |
unsigned |
void |
volatile |
while |
|
15-9.2.5資料型態轉換
指派轉換 |
x = 123; |
算術轉換 |
y = i * 4 + 5 / 6; |
模式轉換 |
i = int(x + 0.7); |
函數轉換 |
s = sum(a, b); |
15-9.2.6亂數
#include <stdlib.h> #include <time.h> srand((unsigned) time
(NULL)); /* 函數srand():設定亂數種子 */ int num = a + rand() % b; /* 函數rand():取亂數 */ /* a:起始值 b:亂數個數 */ |
15-9.3格式化的輸入與輸出
15-9.3.1標準輸入指令
語法 |
scanf("格式化字串", &var1,
&var2, …); |
說明 |
1.&是位址運算子 2.字元陣列不需加&位址運算子 |
輸入格式 |
%d:十進位整數 → int %f:浮點數 → float, double %c:字元 → char %s:字串 → 字元陣列 |
15-9.3.2標準輸出指令
語法 |
printf("格式字串", var1, var2,
…); |
15-9.3.3跳脫字元(Escape Sequence)
跳脫字元 |
功能 |
跳脫字元 |
功能 |
\a |
響鈴 |
\d |
ASCII碼(8進位) |
\b |
倒退鍵 |
\x |
ASCII碼(16進位) |
\f |
換頁 |
\/ |
輸出斜線 |
\n |
換列(Enter鍵) |
\\ |
輸出反斜線 |
\r |
歸位 |
\? |
輸出問號 |
\t |
定位字元(Tab鍵) |
\' |
輸出單引號 |
\v |
垂直定位 |
\" |
輸出雙引號 |
\0 |
空字元(Null) |
|
|
15-9.3.4格式指定字(Format
Specifier)
格式指定字 |
功能 |
格式指定字 |
功能 |
- |
向左靠齊 |
%d |
10進位整數 |
+ |
正負號 |
%u |
無號10進位整數 |
%% |
% |
%x、%X |
16進位整數 |
%c |
字元 |
%l |
長整數,加在d、u…之前 |
%s |
字串 |
%e、%E |
浮點數(指數e型式) |
%o |
8進位整數 |
%f |
浮點數(小數點型式) |
15-9.3.5格式化輸出
資料 |
格式 |
執行結果 |
|||||||||
123456 |
%d |
|
1 |
2 |
3 |
4 |
5 |
6 |
|
|
|
123456 |
%+d |
+ |
1 |
2 |
3 |
4 |
5 |
6 |
|
|
|
123456 |
%10d |
|
|
|
|
1 |
2 |
3 |
4 |
5 |
6 |
123456 |
%-10d |
1 |
2 |
3 |
4 |
5 |
6 |
|
|
|
|
123456 |
%010d |
0 |
0 |
0 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
123.456 |
%7.2f |
|
1 |
2 |
3 |
. |
4 |
6 |
|
|
|
123.456 |
%010.3f |
0 |
0 |
0 |
1 |
2 |
3 |
. |
4 |
5 |
6 |
123.456 |
%+10.4f |
|
+ |
1 |
2 |
3 |
. |
4 |
5 |
6 |
0 |
15-9.4運算子與運算式
15-9.4.1算術運算子
運算子 |
意義 |
int a = 7, b = 3 |
執行結果 |
運算子 |
運算式 |
原式 |
+ |
加法 |
a + b |
10 |
+= |
a +=
b |
a =
a + b |
- |
減法 |
a - b |
4 |
-= |
a -=
b |
a =
a - b |
* |
乘法 |
a * b |
21 |
*= |
a *=
b |
a =
a * b |
/ |
除法 |
a / b |
2 |
/= |
a /=
b |
a =
a / b |
% |
取餘數 |
a % b |
1 |
%= |
a %= b |
a =
a % b |
15-9.4.2關係運算子
運算子 |
意義 |
範例 |
執行結果 |
運算子 |
意義 |
範例 |
執行結果 |
> |
大於 |
1 > 2 |
False |
>= |
大於等於 |
4 >= 5 |
False |
< |
小於 |
2 < 3 |
True |
<= |
小於等於 |
5 <= 6 |
True |
== |
等於 |
3 == 4 |
False |
!= |
不等於 |
6 != 7 |
True |
15-9.4.3邏輯運算子
運算子 |
意義 |
a |
b |
a && b |
a||b |
&& |
AND, 且 |
0 |
0 |
0 |
0 |
|| |
OR, 或 |
0 |
1 |
0 |
1 |
! |
NOT, 否 |
1 |
0 |
0 |
1 |
|
|
1 |
1 |
1 |
1 |
15-9.4.4遞增/遞減運算子
運算子 |
說明 |
int i = 5; int a; |
執行結果 |
|
i |
a |
|||
++ |
變數值加1 |
i++ |
6 |
|
-- |
變數值減1 |
i-- |
4 |
|
i++ |
執行敘述後,i加1 |
a = i++ |
6 |
5 |
++i |
i加1後,執行敘述 |
a = ++i |
6 |
6 |
i-- |
執行敘述後,i減1 |
a = i-- |
4 |
5 |
--i |
i減1後,執行敘述 |
a = --i |
4 |
4 |
15-9.5選擇敘述句
15-9.5.1if敘述
if敘述 |
if…else |
巢狀if |
if…else if…else |
if (判斷條件) 敘述; |
if (判斷條件) 敘述1; else 敘述2; |
if (判斷條件1) {
敘述主體1;
if (判斷條件2)
{ 敘述主體2;
}
… } |
if (判斷條件) {
敘述主體1; } else if (判斷條件) {
敘述主體2; } … else {
敘述主體n; } |
if (判斷條件) {
敘述1;
…
敘述n; } |
if (判斷條件) {
敘述主體1; } else {
敘述主體2; } |
15-9.5.2switch敘述
switch (運算式)
{
case 選擇值1: → 選擇值只能是「字元」或「常數」
敘述主體1;
break; → break用於跳離switch區塊
case 選擇值2:
敘述主體2;
break;
…
case 選擇值n:
敘述主體n;
break;
default: → 當選擇值皆不成立時
敘述主體; → 執行敍述主體
}
15-9.6迴圈敘述句
15-9.6.1比較for / while / do…while
for敘述 |
while敘述 |
do…while敘述 |
for (初值; 判斷條件; 增減量) {
敘述1;
敘述2;
…
敘述n; } |
設初值; while (判斷條件) {
敘述1;
敘述2;
…
敘述n;
設增減量; } |
設初值 do {
敘述1;
敘述2;
… 敘述n;
設增減量; } while (判斷條件); |
15-9.6.2無窮迴圈
while (1)
{
敘述主體;
}
15-9.6.3空迴圈
for (設初值; 判斷條件; 設增減量) { } |
for (設初值; 判斷條件; 設增減量); |
15-9.6.4巢狀迴圈
for巢狀迴圈 |
while巢狀迴圈 |
for (初值1; 條件1; 增減量1) {
for (初值2; 條件2; 增減量2)
{ …
}
… } |
初值1; while (條件1) {
初值2;
while (條件2)
{ … 增減量2;
}
…
增減量1; } |
15-9.6.5跳離迴圈
break(跳離迴圈) |
continue(返回迴圈起始處) |
|
|
15-9.7函式
15-9.7.1定義函式(Function)
語法 |
回傳值型態 函式名稱(參數列) {
變數宣告;
陳述句;
return 回傳值; } |
15-9.7.2函式原型(Prototype)
語法 |
傳回值型態 函式名稱(參數型態); |
範例 |
int sum(int, int); int sum(int a, int b); |
說明 |
1.函式原型通常置於main()函式外,或是標頭檔內。 2.在原始程式檔中,以#include將標頭檔含括進來。 |
15-9.7.3函式呼叫
傳值呼叫(call by value) |
複製參數值傳給函式,不會影響原來的變數值。 |
傳參考呼叫(call by reference) |
將參數位址傳給函式,會影響原來的變數值。 |
15-9.7.4遞迴函式(Recursive Function)
1.自己呼叫自己,須注意終止條件的設定。
2.使用大量的堆疊(stack)空間,容易造成記憶體不足。
3.可以改寫成迴圈形式。
15-9.7.5儲存類別(Storage Class)
儲存類別 |
保留字 |
宣告位置 |
持久性 |
有效範圍 |
備註 |
自動變數 |
auto |
函式內或區塊內 |
暫時 |
區域 |
預設 |
暫存器變數 |
register |
函式內或區塊內 |
暫時 |
區域 |
|
靜態變數 |
static |
函式內或區塊內 |
持續 |
區域 |
數值預設為0 指標預設為null |
外部靜態 |
static |
函式外 |
持續 |
全域(一個檔案) |
|
外部變數 |
extern |
函式外 |
持續 |
全域(所有檔案) |
|
15-9.7.6範圍規則(Scope)
分類 |
說明 |
包含 |
檔案範圍 |
可在整個檔案中使用 |
1.全域變數(Global Variable) 2.函式定義 3.函式原形 |
區塊範圍 |
可在區塊內使用, 也就是{ }包起來的範圍 |
1.區域變數(Local Variable) 2.巢狀區塊中的變數 3.函式的參數 |
函式範圍 |
只能在函式範圍內使用 |
1.goto陳述句的標名 2.switch結構的case |
函式原型範圍 |
|
函式原型參數列中的識別字 |
15-9.8前置處理器
15-9.8.1#define前置處理器
1.增加程式的易讀性。
2.增加程式執行效率。
3.簡化修改常數或字串內容的複雜度。
4.可使用巨集(Macro)取代簡單函數。
15-9.8.2#include前置處理器
語法 |
#include <stdio.h> /* 到系統設定的目錄尋找標頭檔 */ |
#include
"C:\exam\score.h" /* 依指定的目錄尋找標頭檔 */ |
15-9.9陣列
15-9.9.1一維陣列
語法 |
型態 陣列名稱[個數]; |
範例 |
int a[6] = {16, 41, 10, 48, 26, 28}; |
說明 |
a[0] = 16; a[1] = 41; a[2] = 10; a[3]
= 48; a[4] = 26; a[5] = 28 每個元素占一個int型態大小(4Bytes) sizeof(a) → 4 * 6 = 24Bytes |
初值設定 |
int data[5] = {1}; /* 所有元素值都設為1 */ int num[] = {1, 3, 5, 7, 9}; /* 依照初值設定的個數決定陣列的大小 */ int qty[9] = {1, 2, 3, 4, 5}; /* 初值個數少於宣告元素個數,剩餘空間填0 */ |
15-9.9.2二維陣列
語法 |
型態 陣列名稱[列數][行數]; |
範例 |
int b[2][4] = {{27, 36, 42, 40},
{29, 5, 35, 16}}; |
說明 |
b[0][0] = 27; b[0][1] = 36; b[0][2]
= 42; b[0][3] = 40; b[1][0] = 29; b[1][1] = 5; b[1][2]
= 35; b[1][3] = 16; sizeof(b) → 4 * (2 * 4) =
32Bytes |
初值設定 |
int c[][5] = { {1, 2, 3, 4, 5}, /* 未定長度之二維陣列的初值設定 */ {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15} }; |
15-9.9.3陣列與函數
1.陣列元素(下標變數)作為函數傳入參數
與普通變數無區別。將陣列元素的值傳給參數,是單向傳送,兩者的終值是不同的。
2.陣列名稱作為函數參數
(1)函數收到的是陣列位址的指標(Pointer),兩者為同一陣列,共同擁有記憶體空間。
(2)和相對應的傳入參數必須是相同型態的陣列,否則會發生錯誤。
(3)和相對應的傳入參數的長度可以不一致,但執行結果會與實際不符。
(4)在函數參數表中,允許不給參數的長度,或用一個變數來表示陣列元素的個數。
(5)多維陣列也可作為函數參數。在函數定義時,對參數可以指定每一維的長度,也可省去第一維的長度。
15-9.10字串
15-9.10.1字元變數
語法 |
char 字元變數名稱[字串長度]; |
範例 |
char a[] = "Dennis
Ritchie"; sizeof(a) → 14個字元 + 字串結束字元\0 = 15Bytes |
char b = 'c'; sizeof(b) → 1個字元 = 1Byte |
|
char d[] = "e"; sizeof(d) → 1個字元 + 加上字串結束字元\0 = 2Bytes |
|
說明 |
1.字串變數要宣告為字元陣列。 2.字串常數儲存於記憶體時,最後會加上字串結束字元\0。 |
15-9.10.2字串的輸入函數/輸出函數
語法 |
scanf("%s", 字元陣列名稱); printf("%s", 字元陣列名稱); |
gets(字元陣列名稱); puts(字元陣列名稱); |
說明 |
scanf()讀到Enter或空白時就結束讀取動作,並在字串結尾處加上\0。 |
gets()讀到Enter時才結束讀取動作,並在字串結尾處加上\0。 puts()會將\0轉換成換行字元,在輸出字串時自動換行。 |
15-9.10.3字串陣列
語法 |
char 字元陣列名稱[陣列大小][字串長度]; |
範例 |
char name[3][10] =
{"David", "Jany Chang", "Mary Lin"}; |
說明 |
常用的字串函數放在string.h中。 |
15-9.11指標(Pointer)
15-9.11.1指標變數
語法 |
型態 *指標變數; |
範例 |
int *ptrin; /* 整數型態之指標變數 */ char *ptrch; /* 字元型態之指標變數 */ |
說明 |
指標變數:存放變數在記憶體的位址。 指標變數占4Bytes。 sizeof(ptrin) → 4Bytes sizeof(ptrch) → 4Bytes |
15-9.11.2指標運算子
& |
位址運算子:用來取得變數或陣列元素在記憶體的位址。 |
* |
依址取值運算子:用來取得指標指向記憶體位址的內容。 |
15-9.11.3指標的運算
設定運算 |
將等號右邊的值設定給左邊的指標變數。 p = &a; /* 將a的位址存放於p */ |
加減運算 |
針對各個資料型態的長度來計算位址。 x++; /* 將x的位址值加4Bytes(int型態的大小) */ y--; /* 將y的位址值減1Byte(char型態的大小) */ |
差值運算 |
計算兩個指標間的距離,單位為資料型態的長度。 sub = m - n; /* 計算m和n的距離(以int為單位的距離) */ |
15-9.11.4指標與函數
說明 |
函數的return敘述只能有一個回傳值。 利用指標可在函數間傳遞多個回傳值。 |
15-9.11.5指標與陣列的關係
陣列可視為指標的分身,陣列元素的排列可利用指標運算來存取。
int a[3] = {5, 7, 9};
※陣列a以指標方式表示時,a被視為指標常數,不可寫成a++。
15-9.11.6指標陣列
語法 |
型態 *陣列名稱[個數]; |
說明 |
陣列中存放的變數為指標變數。 |
15-9.11.7雙重指標:指向指標的指標
語法 |
型態 **指標變數; |
說明 |
指標變數中,存放另一個指標變數的位址。 |
15-9.12結構與其他資料型態
15-9.12.1結構(Structure)
語法 |
struct 結構名稱 {
資料型態 欄位名稱1;
資料型態 欄位名稱2;
… }; |
15-9.12.2巢狀結構
struct date /* 結構名稱 */ {
int month;
int day; }; struct newdata /* 結構名稱 */ {
char name[15];
struct date birthday; /* 結構變數 */
int score; }; |
15-9.12.3結構陣列
struct mydata student[10]; for(i=0; i<10; i++)
printf("%s got %d points! \n", student[i].name,
student[i].score); |
15-9.12.4結構指標
struct mydata student[10]; /* 結構陣列 */ struct mydata *ptr =
student; /* 結構指標,初值為student陣列的起始位址 */ |
15-9.12.5結構與函數
void get_data(struct mydata
*p); /* 函式原型,參數為結構指標 */ void print_data(struct mydata
a); /* 函式原型,參數為結構變數 */ |
15-9.12.6自訂型態(typedef)
typedef |
#define |
由編譯器執行 |
由前置處理器主導 |
typedef int clock; clock hour, second; |
#define CLOCK int CLOCK hour, second; |
15-9.13檔案
15-9.13.1檔案儲存在記憶體的類型
類型 |
儲存方式 |
儲存單位 |
檔案大小 |
檔案類型 |
文字檔 text file |
ASCII碼 |
1個字元占1Byte,數值132956占6Bytes |
較大(資料相同時) |
文字資料 |
二進位檔 binary file |
二進位格式 |
以資料型態的長度為儲存單位,整數132956占4Bytes |
較小(資料相同時) |
圖形檔、聲音檔、影像檔 |
15-9.13.2檔案存取模式
代碼 |
存取模式 |
代碼 |
存取模式 |
代碼 |
存取模式 |
r |
讀取舊檔 |
r+ |
讀取、覆寫舊檔 |
rb |
讀取二進位檔 |
w |
覆寫新舊檔 |
w+ |
讀取、覆寫新舊檔 |
wb |
覆寫二進位檔 |
a |
附加新舊檔 |
a+ |
讀取、附加新舊檔 |
ab |
附加二進位檔 |
15-9.13.3檔案處理函數(有緩衝區)
變數宣告 |
FILE *file; char ch; char buffer[128]; |
|
函數 |
功能 |
範例 |
exit |
立即終止執行 |
void
exit(int status) |
fclose |
關檔 |
fclose(file); |
feof |
檢查結束 |
int feof(FILE *fp) 傳回值:0表示檔案未結束。1表示檔案結束。 |
ferror |
檢查錯誤 |
int ferror(FILE *fp); 傳回值:0表示無錯誤。1:表示錯誤。 |
fgetc |
讀取字元 |
ch = fgetc(file); |
fgets |
讀取字串 |
fget(buffer, 128, file); |
fopen |
開檔 |
file = fopen(“C:\abc.txt”, “r”); |
fprintf |
格式化輸出 |
fprintf(file,
“%c \n”, ch); |
fputc |
寫入字元 |
fputc(ch, file); |
fputs |
寫入字串 |
fputs(buffer, file); |
fread |
區塊輸入 |
fread(buffer, sizeof(char), 128,
file); |
fscanf |
格式化輸入 |
fscanf(file,
“%c”, &ch); |
fseek |
移動檔案指標位置 |
int fseek(FILE *fp, long offset,
int base); offset是相對於base位置的位移量,正數表示往檔案相對於base的下幾筆移動,負數表示往檔案相對於base的上幾筆移動。 base的傳回值: 0:SEEK_SET,檔案開頭 1:SEEK_CUR,目前游標所在位置 2:SEEK_END,檔案結尾 |
fwrite |
區塊輸出 |
fwrite(buffer, sizeof(char), 128,
file); |
rewind |
重新指向檔案開頭 |
void rewind(FILE *fp) |
15-9.13.4命令列參數的使用
語法 |
main(argc, argv) int argc; char *argv[]; {
... } |
main(int argc, char* argv[]) {
... } |
說明 |
argc:記錄參數個數 argv:記錄參數值 |
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。