21.01.2015 Views

程式語言

程式語言

程式語言

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

01 環 境<br />

1.1 C 語 言 的 發 展 歷 史<br />

1.2 C 語 言 特 性<br />

1.3 電 腦 的 組 成<br />

1.4 作 業 系 統<br />

1.5 C 的 環 境<br />

1.6 Dev-Cpp 整 合 發 展 環 境<br />

1.7 為 什 麼 要 學 習 程 式 設 計<br />

C 語 言 與 電 腦 的 生 命 力<br />

• 電 腦 的 表 現 令 多 數 人 覺 得 不 可 思 議 …<br />

– 電 腦 的 硬 體 是 死 的 、 沒 有 生 命 的<br />

– 電 腦 的 軟 體 是 活 的 , 讓 它 動 起 來 的<br />

• 目 前 使 用 最 多 的 軟 體 發 展 工 具 非 C 語 言 莫 屬<br />

• 本 書 提 供 「ANSI C」 語 言 的 程 式 設 計 理 念<br />

• 「ANSI C」 版 本 是 在 公 元 一 九 八 九 年 由 美 國<br />

「American National Standards Institute」 簡 稱<br />

「ANSI」 以 及 「International Standards Organization」<br />

簡 稱 「ISO」, 所 製 定 的 。<br />

• 公 元 一 九 九 九 年 更 新 過 , 稱 為 「C99」 版 , 其 標 準<br />

文 件 可 參 考 「ISO/IEC 9899:1999」, 其 網 址 如 下 :<br />

http://www.ansi.org<br />

01 C/C++ Common sense<br />

1.1 C 語 言 的 發 展 歷 史<br />

1.2 C 語 言 特 性<br />

年 代<br />

1963<br />

1967<br />

1970<br />

1972<br />

1978<br />

1979<br />

1983<br />

1999<br />

記 事<br />

Combridge 發 展 出 CPL 語 言 。<br />

Martin Richards 發 展 出 BCPL 語 言 。<br />

美 國 AT&T 公 司 貝 爾 實 驗 室 的 Ken Thompson 將 BCPL 語 言 改 良 成 B 語 言 。<br />

Kenighan 及 Ritchic 以 PDP-11 電 腦 為 基 礎 , 在 UNIX 作 業 系 統 下 將 B 語<br />

言 改 為 C 語 言 ,C 語 言 提 供 各 種 資 料 型 態 。<br />

由 Brian W.Kernighan 及 Dennis W.Ritchie( 簡 稱 K&R) 合 著 一 本 C 語 言 的 書 ,<br />

「THE C PROGRAMMING LANGUAGE」, 為 C 語 言 的 經 典 。<br />

各 單 位 陸 續 推 出 各 種 不 同 版 本 之 C 語 言 , 如 C86、MS C、 Run C、Quick<br />

C、... 等 等 。<br />

為 了 統 合 各 種 C 語 言 , 美 國 國 家 標 準 協 會 ANSI, 成 立 「ANSI 委 員<br />

會 」, 定 義 了 一 套 ANSI 的 C 語 言 標 準 。<br />

更 新 ANSI 的 C 語 言 標 準 , 稱 為 C99 版 。<br />

01 C/C++ Common sense<br />

1. 高 階 架 構 , 低 階 功 能<br />

2. 可 攜 性 高<br />

3. 函 式 導 向<br />

4. 指 標 運 算 系 統 程 式 設 計 大 部 份 使 用 C 語 言<br />

5. 遞 迴 呼 叫<br />

6. 動 態 資 料 結 構<br />

7. 結 構 化 程 式 設 計<br />

8. 自 由 格 式<br />

9. 函 式 不 允 許 巢 狀 結 構<br />

01 C/C++ Common sense<br />

1.3 電 腦 的 組 成 VS Programming<br />

1.4 C and Operating systems<br />

Programming<br />

skill<br />

Prompt (hint/ notation)<br />

Input (read)<br />

Retrieve from file<br />

Process (calculation/mapping/transfer)<br />

Output (report from/ tabularization)<br />

Store into file<br />

01 C/C++ Common sense<br />

• 作 業 系 統 有 很 多 種 , 如 UNIX、Linux、Windows<br />

95/98/2000/NT/XP/2003 等 等 , 您 要 安 裝 那 一 種 作 業<br />

系 統 , 要 看 您 的 需 求 而 定 , 大 體 上 Windows 作 業 系<br />

統 偏 向 個 人 單 機 使 用 ,NT、UNIX、 以 及 Linux 等<br />

提 供 多 人 同 時 使 用 。<br />

• 本 書 使 用 的 「ANSI C」 語 言 這 些 作 業 系 統 都 支<br />

援 , 因 此 您 安 裝 那 一 個 作 業 系 統 都 沒 有 關 係 。<br />

01 C/C++ Common sense<br />

1


1.5.1 Windows 環 境<br />

編 輯 編 譯 及 執 行<br />

1.5.2 Linux 環 境 的 編 輯 編 譯 及 執 行<br />

您 使 用 vi 編 輯 hello.c, 然 後 編 譯 、 執 行 , 其 步 驟 如 下 :<br />

$ vi test.c [ 註 ] 步 驟 1<br />

/********** hello.c *********/<br />

int main()<br />

{<br />

printf("Hello, world!!");<br />

return 0;<br />

}<br />

$ cc hello.c [ 註 ] 步 驟 2、3、4<br />

$ ./a.out [ 註 ] 步 驟 5、6<br />

Hello world!!<br />

01 C/C++ Common sense<br />

01 C/C++ Common sense<br />

1.6 C 語 言 的 程 式 設 計<br />

1. 啟 動 Dev-C++ 軟 體 。<br />

2. 編 輯 / 載 入 / 除 錯 hello.c 程 式 。<br />

3. 編 譯 hello.c 程 式 。<br />

4. 執 行 hello.exe 程 式 。<br />

5. 關 閉 hello.c 視 窗 (DOS emulation)。<br />

Dev-Cpp 整 合 發 展 環 境<br />

01 C/C++ Common sense<br />

Phases of a Typical C Program<br />

Development Environment<br />

1. Edit<br />

2. Preprocess<br />

3. Compile<br />

4. Link<br />

5. Load<br />

6. Execute<br />

Editor<br />

Preprocessor<br />

Compiler<br />

Linker<br />

Loader<br />

Disk<br />

CPU<br />

© Copyright 1992–2004 by Deitel & Associates, Inc.<br />

and Pearson Education Inc. All Rights Reserved.<br />

Disk<br />

Disk<br />

Disk<br />

Disk<br />

Primary Memory<br />

.<br />

.<br />

.<br />

Primary Memory<br />

.<br />

.<br />

.<br />

Program is created in<br />

the editor and stored<br />

on disk.<br />

Preprocessor program<br />

processes the code.<br />

Compiler creates<br />

object code and stores<br />

it on disk.<br />

Linker links the object<br />

code with the libraries<br />

Loader puts program<br />

in memory.<br />

CPU takes each<br />

instruction and<br />

executes it, possibly<br />

storing new data<br />

values as the program<br />

executes.<br />

01 C/C++ Common sense<br />

1.6 C 語 言 的 程 式 設 計 (Cont.)<br />

How to develop a workable<br />

program<br />

1. Problem analysis<br />

2. Algorithm design<br />

3. Coding<br />

Structural programming<br />

Object oriented programming<br />

4. Program validation/verification<br />

檔 案 註 解<br />

1.5 The 前 端 structure 處 理 部 份 of C program<br />

© Copyright 1992–2004 by Deitel & Associates, Inc.<br />

and Pearson Education Inc. All Rights Reserved.<br />

變 數 宣 告<br />

Prompt (hint/ notation)<br />

Input (read)<br />

Retrieve from file<br />

Process 演 算 法 , 資 料 處 理<br />

(calculation/mapping/transfer)<br />

Output (report from/ tabularization)<br />

Store into file<br />

01 C/C++ Common sense<br />

01 C/C++ Common sense<br />

2


Textbook for C/C++<br />

programming<br />

林 邦 傑 ,C/C++ 程 式 語 言 , 全 華 書 局 。<br />

References for C/C++<br />

programming (Cont.)<br />

References for C/C++<br />

programming (Cont.)<br />

楊 建 貴 , C 入 門 與 Turbo 系 統<br />

蔡 明 志 譯 ,C 語 言 詳 論 , 東 華 書 局 。<br />

吳 明 哲 等 人 , 最 新 C&C++ 學 習 範 本 , 松 崗 書 局<br />

莊 益 瑞 , 吳 權 威 ,C 語 言 程 式 設 計 , 碁 峰 資 訊 。<br />

陳 錦 輝 ,C/C++ 初 學 指 引 , 上 奇 書 局 。<br />

陳 會 安 ,C/C++ 程 式 設 計 範 例 教 本 , 學 貫 書 局 。<br />

吳 國 樑 , C: 程 式 設 計 藝 術 ( 第 四 版 ), 全 華 書 局 。<br />

01 C/C++ Common sense<br />

01 C/C++ Common sense<br />

Valuable Web sites for<br />

C/C++ learning<br />

http://www.cci.pu.edu.tw/~ychu/class962/962-C-<br />

Programming.htm#4<br />

http://www2.lssh.tp.edu.tw/~lib/teach/note/c/c.htm<br />

http://csuweb.csu.edu.tw/~k0024/cclass/c.htm<br />

http://www.tcgs.tc.edu.tw/~sagit/cpp/<br />

http://dhcp.tcgs.tc.edu.tw/c/<br />

http://www.cppreference.com/<br />

1.7 為 什 麼 要 學 習 程 式 設 計<br />

1. 了 解 智 慧 型 設 備 的 運 作 ,<br />

2. 讓 自 己 的 邏 輯 概 念 更 清 晰 完 整 ,<br />

3. 培 養 開 發 智 慧 型 設 備 的 基 本 準 備 功 夫 ,<br />

4. 透 過 程 式 設 計 的 訓 練 , 了 解 物 質 世 界 運<br />

作 的 道 理 ,<br />

5. 賺 錢 , 改 善 生 活 ; 創 業 , 造 福 人 群 。<br />

Learning from experience.<br />

01 C/C++ Common sense<br />

01 C/C++ Common sense<br />

3


程 式 設 計 風 格<br />

(Programming Styles)<br />

非 結 構 化 程 式 設 計<br />

(Unstructured<br />

Programming)<br />

結 構 化 程 式 設 計<br />

(Structured<br />

Programming)<br />

模 組 化 程 式 設 計<br />

(Modular<br />

Programming)<br />

物 件 導 向 程 式 設 計<br />

(Object-Oriented<br />

Programming)<br />

02 程 式 設 計 簡 介<br />

2.0 純 粹 DOS 環 境 下 的 程 式 設 計<br />

2.1 顯 示 字 串 程 式<br />

2.2 兩 數 相 加 程 式<br />

Naming rules<br />

2.3 變 數 與 記 憶 體<br />

2.4 運 算 式 計 值<br />

2.5 邏 輯 判 斷<br />

2.0 純 粹 DOS 環 境 下 的 程 式 設 計<br />

文 字 型 嵌 入 式 電 子 設 備<br />

‧ 電 子 字 典<br />

‧ 手 機 選 單 選 項<br />

‧ 跑 馬 燈 字 幕 機<br />

‧ 學 生 成 績 管 理 系 統<br />

‧ 收 銀 機<br />

‧ 倉 庫 管 理 系 統<br />

‧ 點 菜 機<br />

‧ 警 察 查 詢 贓 車 系 統<br />

‧ 跳 舞 機<br />

‧ 俄 羅 斯 方 塊 遊 戲 機<br />

‧ 數 位 電 話 機 管 理<br />

‧ 簡 易 型 計 算 機<br />

‧ 電 視 機 遙 控 器<br />

‧ ㄅㄧㄅㄧ 叩 呼 叫 器 ‧ 運 動 健 身 器 材<br />

‧ 火 車 列 車 長 補 票 機<br />

‧ 火 車 站 班 次 出 發 時 間<br />

‧ 車 廂 廂 號 班 次 啟 程 站 終 點 站<br />

02- 程 式 設 計 簡 介<br />

模 組 化 程 式 設 計<br />

‧ C 語 言 的 功 能 都 大 部 分 是 由 函 式 庫 提 供 , 模 組 可 以<br />

將 實 際 處 理 的 程 式 碼 和 資 料 隱 藏 起 來 達 成 「 資 訊<br />

隱 藏 」(Information Hiding)。<br />

Tips for C program writing<br />

• 程 式 碼 要 正 確 縮 排 , 有 益 於 程 式 內 容 的 了 解<br />

• 程 式 註 解 有 益 於 程 式 內 容 的 了 解 及 設 計 理 念<br />

的 追 蹤<br />

• 程 式 區 塊 (Blocks) 是 程 式 的 基 本 單 元<br />

– 由 「{」 和 「}」 符 號 包 圍 , 是 由 多 個 敘 述 所 組 成<br />

陳 會 安 ,C/C++ 程 式 設 計 範 例 教 本 , 學 貫 書 局<br />

02- 程 式 設 計 簡 介<br />

• main() 是 C 語 言 第 一 個 執 行 的 函 數 名 稱<br />

• 函 數 是 可 再 用 的 程 式 基 本 單 元 ( reusable<br />

function unit)<br />

• 演 算 法 必 須 留 意<br />

輸 入 (Input)<br />

輸 出 (Output)<br />

明 確 性 (Definiteness)<br />

有 限 性 (Finiteness)<br />

有 效 性 (Effectiveness)<br />

02- 程 式 設 計 簡 介<br />

2.1 顯 示 字 串 程 式<br />

C 語 言 逸 出 符 號<br />

// filename: first.cpp<br />

// purpose: A first program in C<br />

// Authors / ID code: Ping-Sung Liao/A123456<br />

// Date: 2008/03/01, Version: 1.00<br />

#include <br />

#include <br />

int main()<br />

{ printf(“ 歡 迎 到 阿 拉 丁 魔 幻 世 界 !\n");<br />

system("pause");<br />

return 0; /* indicate that program ended successfully */<br />

} /* end function main */<br />

02- 程 式 設 計 簡 介<br />

02- 程 式 設 計 簡 介<br />

1


C 語 言 逸 出 符 號 範 例<br />

printf(" 我 的 ");<br />

printf(" 第 一 個 C 程 式 !\n");<br />

2.2 兩 數 相 加 程 式<br />

// Filename: add2number.cpp<br />

// Purpose: 兩 數 相 加 程 式<br />

// Authors: Ping-Sung Liao/A123456<br />

// Date: 2008/03/01, Version: 1.00<br />

#include <br />

#include <br />

printf(" 我 的 ");<br />

printf(" 第 一 個 ");<br />

printf("C 程 式 !\n");<br />

printf(" 我 的 \n 第 一 個 \nC 程 式 !\n");<br />

02- 程 式 設 計 簡 介<br />

int main()<br />

{<br />

int a, b, sum;<br />

printf(“ 請 輸 入 第 一 個 整 數 :”);<br />

scanf(“%d”, &a);<br />

printf(" 請 輸 入 第 二 個 整 數 :");<br />

scanf("%d", &b);<br />

sum=a+b;<br />

printf(“ 兩 數 之 和 為 %d\n”, sum);<br />

system(“pause”);<br />

return 0;<br />

}<br />

// 提 示 使 用 者<br />

// 使 用 者 輸 入 資 料<br />

// 提 示 使 用 者<br />

// 使 用 者 輸 入 資 料<br />

// 資 料 處 理 中<br />

// 列 印 資 料 處 理 結 果<br />

// 程 式 暫 停 一 下<br />

// 程 式 執 行 完 畢 , 回 到 視 窗 作 業 系 統<br />

02- 程 式 設 計 簡 介<br />

Naming rules for variable/function (1)<br />

‧ 名 稱 是 一 個 合 法 的 「 識 別 字 」(Identifiers)<br />

– 第 一 個 字 母 必 須 是 底 線 _ 或 字 母 a - z, A - Z<br />

– 第 二 個 字 母 可 以 是 英 文 字 母 、 數 字 和 底 線 「_」 字 元 組 成 的 名 稱 。<br />

–C 語 言 的 識 別 字 至 少 前 31 個 字 元 是 有 效 字 元<br />

‧ 名 稱 區 分 英 文 字 母 的 大 小 寫 :<br />

–count、Count 和 COUNT 屬 於 不 同 的 識 別 字 。<br />

‧ 名 稱 不 能 使 用 C 語 法 的 「 關 鍵 字 」(Keywords)<br />

– 關 鍵 字 對 於 編 譯 程 式 而 言 , 擁 有 特 殊 意 義 。<br />

‧ 名 稱 必 須 是 有 意 義 : 建 議 採 用 匈 牙 利 命 名 ; 例 如<br />

myStudentNumber, classIdentifier;<br />

‧ 名 稱 擁 有 其 有 效 「 範 圍 」(Scope)<br />

– 在 有 效 範 圍 的 程 式 碼 中 名 稱 必 需 是 唯 一 的<br />

02- 程 式 設 計 簡 介<br />

Naming rules for variable/function (2)<br />

合 法 名 稱<br />

不 合 法 名 稱<br />

T、c 1、2<br />

Size、test123、count、_hight 1count、hi!world<br />

Long_name、helloWord Long…name、hello World<br />

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.<br />

auto break case char const<br />

continue default do double else<br />

enum extern float for goto<br />

if inline int long long long<br />

register retstrict return short signed<br />

sizeof static struct switch typedef<br />

union unsigned void volatile while<br />

02- 程 式 設 計 簡 介<br />

C 語 言 關 鍵 字<br />

‧ 識 別 字 對 C COMPILER 來 講 有 其 特 別 的 意 義 ,<br />

‧ 我 們 取 變 數 名 稱 時 不 能 跟 C 語 言 關 鍵 字 相 同 ,C 語 言<br />

關 鍵 字 如 下 表 所 示 。<br />

2.3 變 數 與 記 憶 體<br />

02- 程 式 設 計 簡 介<br />

02- 程 式 設 計 簡 介<br />

2


2.4 運 算 式 計 值<br />

• 許 多 C 程 式 都 會 使 用 算 術 計 算 ,C 語 言 的 算 術 運 算<br />

子 有 加 ‘+’、 減 ‘-’、 乘 ‘*’、 除 ‘/’、 及 餘 數 ‘%’, 如 下 表<br />

所 示 。<br />

表 2.2 C 語 言 算 術 運 算 子<br />

C 語 言 數 學 運 算 子 優 先 順 序<br />

C 語 言 運 算 式 計 值 是 依 運 算 子 優 先 順 序 的 規 則 計 算 的 , 這 一 點 與<br />

數 學 上 的 計 算 是 一 樣 的 。 規 則 如 下 :<br />

1. 在 括 號 內 的 運 算 式 優 先 計 值 。<br />

若 括 號 有 好 幾 組 , 則 最 內 層 的 括 號 優 先 計 值 。<br />

2. 乘 、 除 、 餘 數 第 二 優 先 計 值 。<br />

乘 、 除 、 餘 數 是 同 一 等 級 , 無 所 謂 誰 先 誰 後 ,<br />

以 左 邊 的 運 算 子 優 先 計 值 。<br />

3. 加 與 減 第 三 優 先 計 值 。<br />

加 與 減 是 同 一 等 級 , 無 所 謂 誰 先 誰 後 ,<br />

以 左 邊 的 運 算 子 優 先 計 值 。<br />

02- 程 式 設 計 簡 介<br />

02- 程 式 設 計 簡 介<br />

Operators precedence<br />

Operators Associativity Type<br />

() [] left to right highest<br />

+ - ++ -- ! * & (type) right to left unary<br />

* / % left to right multiplicative<br />

+ - left to right additive<br />

< >= left to right relational<br />

== != left to right equality<br />

&& left to right logical and<br />

|| left to right logical or<br />

: right to left conditional<br />

= += -= *= /= %= right to left assignment<br />

, left to right comma<br />

Fig. 7.5 Operator precedence.<br />

2.5 邏 輯 判 斷 --- if 控 制 結 構<br />

‧if 控 制 敘 述 可 以 改 變 程 式 的 流 程 , 其 語 法<br />

如 下 :<br />

if ( 條 件 ) 敘 述 1<br />

「 條 件 」 若 成 立 則 執 行 其 後 的 「 敘 述 1」,<br />

「 條 件 」 若 不 成 立 則 不 執 行 。<br />

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.<br />

02- 程 式 設 計 簡 介<br />

02- 程 式 設 計 簡 介<br />

【 程 式 ifscore.c】<br />

/*********** ifscore.c ***********/<br />

#include <br />

int main()<br />

{<br />

int score;<br />

printf(" 請 輸 入 成 績 :");<br />

scanf("%d", &score);<br />

if (score >= 60)<br />

printf(" 恭 喜 , 您 及 格 了 !");<br />

return 0;<br />

}<br />

【 執 行 於 Windows 環 境 】<br />

ifscore.exe <br />

請 輸 入 成 績 :88 <br />

恭 喜 , 您 及 格 了 !<br />

1. 自 由 格 式<br />

2. 易 於 了 解 的 編 排 格 式 為 佳<br />

3. 在 適 當 處 作 註 解<br />

02- 程 式 設 計 簡 介<br />

【 程 式 ifblock.c】<br />

/************** ifblock.c **************/<br />

#include <br />

int main()<br />

1. 自 由 格 式<br />

{<br />

2. 易 於 了 解 的 編 排 格 式 為 佳<br />

int a, b, c, d;<br />

3. 在 適 當 處 作 註 解<br />

printf(" 請 輸 入 a,b,c 之 值 :"); 4. 敘 述 結 尾 以 ; 收 尾<br />

scanf("%d %d %d", &a, &b, &c);<br />

5. 徹 底 了 解 敘 述 的 組 成<br />

d = b * b - 4 * a * c;<br />

if (d > 0)<br />

{<br />

printf(" 判 別 式 d 的 值 = %d\n", d);<br />

printf(" 方 程 式 有 兩 個 不 同 的 實 根 ");<br />

} ;<br />

return 0;<br />

} 【 執 行 於 Windows 環 境 】<br />

請 輸 入 a,b,c 之 值 :1 2 -3 <br />

判 別 式 d 的 值 = 16<br />

方 程 式 有 兩 個 不 同 的 實 根<br />

02- 程 式 設 計 簡 介<br />

3


3.0 Requirement and Description<br />

03 流 程 圖 與 演 算 法<br />

3.0 Requirement & Description<br />

3.1 流 程 圖 符 號<br />

3.2 演 算 法<br />

• 在 使 用 電 腦 解 決 您 的 問 題 之 前 , 您 總 要 對 問 題 做<br />

一 個 完 整 的 了 解 , 然 後 仔 細 的 規 劃 解 決 問 題 的 步<br />

驟 , 將 這 些 步 驟 轉 換 為 電 腦 的 程 式 , 最 後 執 行 這<br />

些 程 式 , 就 可 得 到 結 果 .<br />

• 演 算 法 (algorithm)<br />

– 解 決 問 題 的 步 驟<br />

– 通 常 要 藉 助 流 程 圖 (flow chart) 或 虛 擬 碼 (pseudo code)<br />

來 說 明<br />

03 流 程 圖 與 演 算 法<br />

3.1 流 程 圖 符 號<br />

3.2 演 算 法<br />

演 算 法 是 指 使 用 有 限 的 指 令 以 解 決 某 一 特 定 問 題 的<br />

步 驟 . 演 算 法 有 下 列 幾 個 特 性 :<br />

1. 輸 入 (input): 可 以 有 零 個 或 多 個 輸 入 資 料 .<br />

2. 輸 出 (output): 至 少 有 一 個 輸 出 資 料 .<br />

3. 明 確 性 (definiteness): 每 個 指 令 必 須 明 確 , 不<br />

可 模 稜 兩 可 .<br />

4. 有 限 性 (finiteness): 演 算 法 必 須 經 過 有 限 步 驟<br />

後 停 止 .<br />

5. 有 效 性 (effectiveness): 可 以 在 紙 上 作 業 追 蹤<br />

其 結 果 .<br />

03 流 程 圖 與 演 算 法<br />

03 流 程 圖 與 演 算 法<br />

【 例 一 】 輸 入 三 個 整 數 ( 變 數 名 稱 a、b 及 c),<br />

求 其 平 均 值 ( 變 數 名 稱 ave).<br />

【 例 二 】 重 複 輸 入 一 個 整 數 a, 若 a 為 正 數 則 累 加 起 來 ,<br />

否 則 輸 出 總 和 , 之 後 停 止 。<br />

【 以 文 字 敘 述 說 明 演 算 法 】<br />

1. 輸 入 三 個 整 數 a、b 及 c.<br />

2. 總 和 sum 為 a、b 及 c 之 和 .<br />

3. 平 均 avg 為 總 和 sum 除 於 3 之 商 .<br />

4. 輸 出 平 均 值 ave.<br />

5. 結 束 .<br />

【 以 演 算 法 語 言 說 明 演 算 法 】<br />

1. input a, b, c<br />

2. sum = a + b + c<br />

3. avg = sum / 3<br />

4. output avg<br />

5. end<br />

【 以 文 字 敘 述 說 明 演 算 法 】<br />

【 以 演 算 法 語 言 說 明 演 算 法 】<br />

1. 設 總 和 為 0.<br />

2. 輸 入 一 個 整 數 a.<br />

3. 若 a 為 正 數 則<br />

4. 將 a 加 至 總 和 .<br />

5. 輸 入 一 個 整 數 a.<br />

6. 輸 出 總 和 .<br />

7. 結 束 .<br />

1. sum = 0<br />

2. input a<br />

3. while a > 0<br />

4. sum = sum + a<br />

5. input a<br />

6. output sum<br />

7. end<br />

03 流 程 圖 與 演 算 法<br />

指 定 運 算 子 「=」 可 以 將 右 邊 的 運 算 式 值 指 定 給 左 邊 的 變 數 .<br />

03 流 程 圖 與 演 算 法<br />

1


指 定 運 算 子 「=」<br />

指 定 運 算 子 「=」 可 以 將 右 邊 的 運 算 式 值 指 定 給 左 邊 的 變 數 .<br />

指 定 敘 述 的 語 法 如 下 :<br />

變 數 = 運 算 式 ;<br />

• 變 數<br />

變 數 名 稱 , 為 合 乎 規 定 的 識 別 字 .<br />

• 運 算 式<br />

為 運 算 元 (operand) 與 運 算 子 (operator) 及 小 括 號 的 結 合 ,<br />

運 算 結 果 只 產 生 一 個 值 , 這 個 值 指 定 給 左 邊 的 變 數 .<br />

03 流 程 圖 與 演 算 法<br />

03 流 程 圖 與 演 算 法<br />

【 例 三 】 由 1 加 至 100.<br />

【 例 三 】 由 1 加 至 100.<br />

【 以 文 字 敘 述 說 明 演 算 法 】<br />

1. 設 定 二 個 整 數 i=1 及 sum=0.<br />

2. i 小 於 或 等 於 100 繼 續 下 一 步 , 否 則 跳 到 步 驟 6<br />

3. 將 i 加 到 總 和 sum.<br />

4. 印 出 i 及 總 和 sum<br />

5. i 增 加 1, 回 到 步 驟 2 .<br />

6. 結 束 .<br />

【 以 演 算 法 語 言 說 明 演 算 法 】<br />

1. set i=1, sum=0<br />

2. While i


【 例 三 】 求 一 元 二 次 多 項 式 的 根<br />

1<br />

2<br />

3<br />

4a<br />

4b<br />

4c<br />

Start<br />

Input a,b,c<br />

tempNum=b*b-4.0*a*c;<br />

denominator=2.0*a;<br />

(a==0.0 &&<br />

b!=0.0)<br />

y<br />

x=-c/b;<br />

print x<br />

n<br />

5a<br />

7a<br />

(a==0.0 && 6a<br />

b=0.0) n<br />

tempNum>0<br />

n<br />

tempNum=0<br />

n<br />

y 6b<br />

y 7b y 8a<br />

實 數 解 = -b<br />

實 數 解 = 複 數 解 = -b<br />

± i sqrt ( -tempNum)) /denominator<br />

± sqrt (tempNum)) /denominator -b /denominator<br />

5b<br />

print 無 解<br />

6c<br />

print x<br />

7c<br />

print x<br />

8b<br />

print x<br />

// Filename: completeRootPolynominal_.cpp<br />

// Purpose: 求 一 元 二 次 多 項 式 的 根<br />

// Authors: XXXX Liao/A123456<br />

// Date: 2010/03/12, 17:25, Version: 1.00<br />

// 圖 形 流 程 圖 的 重 要 性 , 及 文 字 縮 排 型 演 算 法 描 述<br />

// 非 常 完 整 地 解 決 一 元 二 次 多 項 式 的 根 ( 實 根 , 重 根 , 複 數 根 )<br />

// (a,b,c)= (1, 0, 2) / (1,8,10) / (2, 8, 10);<br />

#include <br />

#include <br />

#include //necessary for sqrt() function<br />

int main()<br />

{ float a, b,c;<br />

float tempNumber,number, numerator,denominator;<br />

printf(" 完 整 地 解 決 一 元 二 次 多 項 式 的 根 ( 實 根 , 重 根 , 複 數 根 ) 之 求 解 演 算 法 \n");<br />

printf(" 一 元 二 次 多 項 式 的 模 型 : ax^2+bx+c=0\n\n" );<br />

printf(" 請 輸 入 第 一 個 整 數 (a): "); // 提 示 使 用 者<br />

scanf("%f", &a); // 使 用 者 輸 入 資 料<br />

printf(" 請 輸 入 第 二 個 整 數 (b):"); // 提 示 使 用 者<br />

scanf("%f", &b); // 使 用 者 輸 入 資 料<br />

printf(" 請 輸 入 第 三 個 整 數 (c):");<br />

scanf("%f", &c);<br />

tempNumber=b*b-4.0*a*c;<br />

denominator=2.0*a;<br />

end<br />

03 流 程 圖 與 演 算 法<br />

printf("-b=%f b^2-4ac=%f\n", -b,tempNumber);<br />

printf("2a=%f\n", denominator);<br />

03 流 程 圖 與 演 算 法<br />

if(a==0.0 && b!=0.0)<br />

printf("x= %d \n",c/b);<br />

else if(a==0.0 && b==0.0)<br />

printf("x 無 解 \n");<br />

else<br />

{ if( tempNumber>0.0 )<br />

{printf(" 兩 個 實 數 解 \n");<br />

printf("the first root is %f \n", ( -b + sqrt (tempNumber)) /denominator ) ; //bsliao<br />

printf("the second root is %f \n", ( -b - sqrt (tempNumber)) /denominator ) ; //bsliao<br />

}<br />

else if( tempNumber==0.0 )<br />

{printf(" 重 根 \n");<br />

printf("the first root is %f\n", -b/denominator) ;<br />

printf("the second root is %f\n", -b/denominator) ;<br />

}<br />

else // (tempNumber < 0.0)<br />

{printf(" 兩 個 複 數 解 \n");<br />

printf("the first root is %f + %f i\n", -b/denominator, sqrt (- tempNumber) /denominator ); //bsliao<br />

printf("the second root is %f + %f i\n", -b/denominator, - sqrt (- tempNumber) /denominator ); //bsliao<br />

printf("the second root is %f %f i\n", -b/denominator, - sqrt (- tempNumber) /denominator ); //bsliao<br />

}<br />

}<br />

system("pause");<br />

return 0;<br />

}<br />

// 程 式 暫 停 一 下<br />

// 程 式 執 行 完 畢 , 回 到 視 窗 作 業 系 統<br />

03 流 程 圖 與 演 算 法<br />

3


結 構 化 程 式 設 計 的 基 本 結 構<br />

04 程 式 結 構<br />

4.1 循 序 結 構<br />

4.2 選 擇 結 構<br />

4.3 重 複 結 構<br />

4.4 運 算 式 敘 述<br />

4.5 if 敘 述<br />

4.6 if … else 敘 述<br />

4.7 switch & case 敘 述<br />

4.8 while 敘 述<br />

4.9 do/while 敘 述<br />

4.10 for 敘 述<br />

• 循 序 結 構<br />

– 依 您 撰 寫 程 式 的 順 序 一 個 接 一 個 的 執 行 , 稱 為 循 序 執 行<br />

• 選 擇 結 構<br />

– 簡 單 控 制 轉 向<br />

– if/else, switch … case (default, break)<br />

• 重 複 結 構<br />

– 帶 有 重 複 性 的 控 制 轉 向<br />

– for, while, do … while, break, continue<br />

04 程 式 結 構<br />

結 構 化 程 式 設 計 優 點<br />

4.1 循 序 結 構<br />

1. 架 構 清 楚 明 白 ,<br />

2. 容 易 除 錯 及 修 改 ,<br />

3. 設 計 速 度 快 速 ,<br />

4. 設 計 費 用 相 對 的 降 低 。<br />

結 構 化 程 式 設 計<br />

絕 對 要 排 除 使 用 goto 的 敘 述 在 程 式 裡 跳 來 轉 去 , 讓<br />

您 撰 寫 程 式 的 順 序 一 個 敘<br />

述 接 一 個 敘 述 執 行<br />

• 首 先 執 行<br />

sum=a+b+c;<br />

• 然 後 執 行<br />

avg=sum/3;<br />

看 程 式 的 人 眼 花 撩 亂 , 增 加 程 式 維 護 的 困 難 。<br />

04 程 式 結 構<br />

04 程 式 結 構<br />

4.2 選 擇 結 構<br />

4.2 選 擇 結 構 -if …else<br />

C 語 言 提 供 三 種 選 擇 結 構 :if、if/else、switch。<br />

if 敘 述 的 語 法<br />

if (expression) statement;<br />

或<br />

if (expression)<br />

{ statement 1;<br />

statement 2;<br />

statement i;<br />

}<br />

expression 表 示 條 件 運 算 式 ,<br />

statement 表 示 敘 述 。<br />

04 程 式 結 構<br />

if …else 敘 述 的 語 法<br />

if (expression) statement 1;<br />

else statement 2;<br />

或<br />

if (expression)<br />

{ statement 1;<br />

statement i;<br />

}<br />

else<br />

{ statement 2;<br />

statement k;<br />

}<br />

expression 表 示 條 件 運 算 式 ,<br />

statement i 表 示 敘 述<br />

04 程 式 結 構<br />

1


4.2 選 擇 結 構 -switch (1)<br />

4.2 選 擇 結 構 -switch (2)<br />

switch (expression)<br />

{ case 1: statement_1;<br />

break;<br />

case 2: statement_2;<br />

break;<br />

case 3: statement_3;<br />

break;<br />

…<br />

case n: statement_n;<br />

• expression break; 表 示 條 件 運 算<br />

式 ,statement 表 示 敘 述 。<br />

default: statement;<br />

}<br />

switch (expression)<br />

{ case 1: statement_1;<br />

case 2: statement_2;<br />

case 3: statement_3;<br />

break;<br />

…<br />

case n: statement_n;<br />

• expression break; 表 示 條 件 運 算<br />

式 ,statement 表 示 敘 述 。<br />

default: statement;<br />

}<br />

04 程 式 結 構<br />

04 程 式 結 構<br />

4.3 重 複 結 構 - while<br />

• C 語 言 提 供 三 種 重 複 結<br />

構 :while、do/while、<br />

for。<br />

while 敘 述 的 語 法 如 下 ,<br />

while (expression)<br />

statement;<br />

或<br />

while (expression)<br />

{ statement 1;<br />

…<br />

statement i;<br />

}<br />

4.3 重 複 結 構 - do/while<br />

do<br />

statement<br />

while (expression);<br />

或<br />

do<br />

{ statement 1;<br />

…<br />

statement i;<br />

} while (expression) ;<br />

04 程 式 結 構<br />

04 程 式 結 構<br />

4.3 重 複 結 構 - for<br />

for (expression1; expression2; expression3)<br />

statement<br />

或<br />

for (expression1; expression2; expression3)<br />

{ statement 1;<br />

…<br />

statement i;<br />

}<br />

4.4.1 指 定 敘 述<br />

指 定 運 算 子 「=」 可 以 將 右 邊 的 運 算 式 值 指 定 給 左 邊 的 變 數 。<br />

指 定 敘 述 的 語 法 如 下 :<br />

變 數 = 運 算 式 ;<br />

• 變 數<br />

變 數 名 稱 , 為 合 乎 規 定 的 識 別 字 。<br />

• 運 算 式<br />

為 運 算 元 (operand) 與 運 算 子 (operator) 及 小 括 號 的 結 合 ,<br />

運 算 結 果 只 產 生 一 個 值 , 這 個 值 指 定 給 左 邊 的 變 數 。<br />

04 程 式 結 構<br />

04 程 式 結 構<br />

2


等 號 為 指 定 運 算 子 中 的 一 個 運 算 子<br />

符 號<br />

=<br />

*=<br />

/=<br />

%=<br />

+=<br />

-=<br />

=<br />

&=<br />

|=<br />

^=<br />

名<br />

簡 單 指 定 運 算 子<br />

乘 複 合 指 定 運 算 子<br />

除 複 合 指 定 運 算 子<br />

餘 數 複 合 指 定 運 算 子<br />

加 複 合 指 定 運 算 子<br />

減 複 合 指 定 運 算 子<br />

稱<br />

左 移 複 合 指 定 運 算 子<br />

右 移 複 合 指 定 運 算 子<br />

位 元 AND 指 定 運 算 子<br />

位 元 OR 指 定 運 算 子<br />

位 元 XOR 指 定 運 算 子<br />

舉 例 說 明<br />

y=x*2+3;<br />

將 右 邊 運 算 式 計 值 後 指 定 給 左 邊 之 變 數 y。<br />

y*=x; 相 當 於 y=y*x;<br />

y/=2; 相 當 於 y=y/2;<br />

y%=5; 相 當 於 y=y%5;<br />

y+=x*4+6; 相 當 於 y=y+x*4+6;<br />

y-=x%3+8; 相 當 於 y=y-x%3+8;<br />

yn;<br />

i&=j; 相 當 於 i=i&j;<br />

i|=j; 相 當 於 i=i|j;<br />

i^=j; 相 當 於 i=i^j;<br />

Logical Operators (1)<br />

• && ( logical AND )<br />

– Returns true if both conditions are true<br />

• ||( logical OR )<br />

– Returns true if either of its conditions are true<br />

• ! ( logical NOT, logical negation )<br />

– Reverses the truth/falsity of its condition<br />

– Unary operator, has one operand<br />

• Useful as conditions in loops<br />

Expression<br />

Result<br />

true && false<br />

false<br />

true || false<br />

true<br />

!false<br />

true<br />

04 程 式 結 構<br />

04 程 式 結 構<br />

Logical Operators (2)<br />

expression1 expression2 expression1 && expression2<br />

0 0 0<br />

0 nonzero 0<br />

nonzero 0 0<br />

nonzero nonzero 1<br />

Fig. 4.13 Truth table for the && (logical AND) operator.<br />

expression1 expression2 expression1 || expression2<br />

0 0 0<br />

0 nonzero 1<br />

nonzero 0 1<br />

nonzero nonzero 1<br />

Fig. 4.14 Truth table for the logical OR (||) operator.<br />

expression<br />

0 1<br />

! expression<br />

nonzero 0<br />

Fig. 4.15 Truth table for operator ! (logical negation).<br />

Logical Operators (3)<br />

Operators Associativity Type<br />

++ -- + - ! (type) right to left unary<br />

* / % left to right multiplicative<br />

+ - left to right additive<br />

< >= left to right relational<br />

== != left to right equality<br />

&& left to right logical AND<br />

|| left to right logical OR<br />

: right to left conditional<br />

= += -= *= /= %= right to left assignment<br />

, left to right comma<br />

Fig. 4.16 Operator precedence and associativity.<br />

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All 04 Rights 程 Reserved. 式 結 構<br />

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All 04 Rights 程 Reserved. 式 結 構<br />

Confusing Equality (==) and<br />

Assignment (=) Operators (1)<br />

• Dangerous error<br />

– Does not ordinarily cause syntax errors<br />

– Any expression that produces a value can be<br />

used in control structures<br />

– Nonzero values are true, zero values are false<br />

– Example using ==:<br />

if ( payCode == 4 )<br />

printf( "You get a bonus!\n" );<br />

• Checks payCode, if it is 4 then a bonus is awarded<br />

Confusing Equality (==) and<br />

Assignment (=) Operators (2)<br />

– Example, replacing == with =<br />

if ( payCode = 4 )<br />

printf( "You get a bonus!\n" );<br />

• This sets payCode to 4<br />

• 4is nonzero, so expression is true, and<br />

bonus awarded no matter what the<br />

payCode was<br />

– Logic error, not a syntax error<br />

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All 04 Rights 程 Reserved. 式 結 構<br />

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All 04 Rights 程 Reserved. 式 結 構<br />

3


4.4.2 遞 增 與 遞 減 運 算 子<br />

4.5 if 敘 述<br />

問 題 描 述 :<br />

我 想 從 電 腦 的 鍵 盤 輸<br />

入 張 三 的 成 績 若 張 三<br />

的 成 績 大 於 或 等 於 60<br />

分 則 請 電 腦 顯 示 " 及<br />

格 " 兩 個 字<br />

程 式 虛 擬 碼 如 下 :<br />

input grade<br />

if grade >= 60<br />

output " 及 格 "<br />

流 程 圖 如 右 圖 所 示<br />

04 程 式 結 構<br />

04 程 式 結 構<br />

【 程 式 ifgrade.c】<br />

/*************** ifgrade.c ****************/<br />

#include <br />

int main()<br />

{<br />

int grade;<br />

printf(“ 輸 入 成 績 grade: ”); /* 步 驟 2 提 示 語 */<br />

scanf(“%d”, &grade); /* 步 驟 2 讀 取 資 料 */<br />

if (grade >= 60) printf(“ 及 格 ”); /* 步 驟 3 及 4 執 行 及 輸 出 */<br />

return 0;<br />

}<br />

【 執 行 】<br />

gcc iftest.c -o ifgrade.exe <br />

ifgrade.exe <br />

輸 入 成 績 grade: 55 <br />

ifgrade.exe <br />

輸 入 成 績 grade: 66 <br />

及 格<br />

問 題 描 述 :<br />

我 想 從 電 腦 的 鍵 盤 輸 入<br />

一 個 整 數 若 該 整 數 為 偶<br />

數 , 則 請 電 腦 顯 示 " 偶<br />

數 " 兩 個 字<br />

程 式 虛 擬 碼 如 下 :<br />

input number<br />

even = number % 2<br />

if even == 0<br />

output " 偶 數 "<br />

流 程 圖 如 右 圖 所 示<br />

04 程 式 結 構<br />

04 程 式 結 構<br />

【 程 式 ifeven.c】<br />

/**************** ifeven.c ***************/<br />

#include <br />

int main()<br />

{<br />

int number;<br />

int even;<br />

printf(" 輸 入 整 數 number: "); /* 步 驟 2*/<br />

scanf("%d", &number); /* 步 驟 2*/<br />

even = number % 2; /* 步 驟 3*/<br />

if (even == 0) printf(" 偶 數 "); /* 步 驟 4 及 5*/<br />

return 0;<br />

}<br />

【 執 行 】<br />

gcc ifeven.c -o ifeven.exe <br />

ifeven.exe <br />

輸 入 整 數 number: 5 <br />

ifeven.exe <br />

輸 入 整 數 number: 6 <br />

偶 數<br />

04 程 式 結 構<br />

4.6 if/else 敘 述<br />

問 題 描 述 :<br />

拿 張 三 的 成 績 來 講 , 成 績 若<br />

超 過 ( 含 ) 60 分 , 就 輸 出 “ 及<br />

格 " 兩 個 字 , 否 則 的 話 並 沒<br />

有 處 理 。 現 在 加 上 否 則 就 輸<br />

出 “ 不 及 格 " 三 個 字 。<br />

程 式 碼 虛 擬 如 下 :<br />

if (grade >= 60)<br />

printf(" 及 格 ");<br />

else<br />

printf(" 不 及 格 ");<br />

流 程 圖 如 右 圖 所 示<br />

04 程 式 結 構<br />

4


【 程 式 ifpass.c】<br />

/**************** ifpass.c **************/<br />

#include <br />

int main()<br />

{<br />

int grade;<br />

printf(" 輸 入 成 績 grade: "); /* 步 驟 2*/<br />

scanf("%d", &grade); /* 步 驟 2*/<br />

if (grade >= 60) /* 步 驟 3*/<br />

printf(" 及 格 "); /* 步 驟 4*/<br />

else<br />

printf(" 不 及 格 "); /* 步 驟 5*/<br />

return 0;<br />

}<br />

4.7 switch & case 敘 述<br />

• switch 選 擇 結 構 讓 您 可 在 多 種 情 況 中 選 一 種 ,<br />

• 例 如 您 可 從 鍵 盤 輸 入 一 個 大 寫 的 英 文 字 母 到 電 腦 記 憶 體<br />

中 的 ch 位 置 , 那 麼 ch 位 置 的 內 含 值 就 有 26 種 之 多 , 但 是<br />

您 想 將 這 26 種 分 為 三 組 , 第 一 組 只 包 括 A, 第 二 組 只 包 括<br />

B, 第 三 組 只 包 括 其 他 的 字 母 , 這 種 結 構 表 示 如 下 :<br />

switch (ch)<br />

{ case 'A':<br />

/* 插 入 第 一 組 所 要 執 行 的 動 作 */;<br />

break;<br />

case 'B':<br />

/* 插 入 第 二 組 所 要 執 行 的 動 作 */;<br />

break;<br />

default : /* 第 三 組 所 要 執 行 的 動 作 */;<br />

}<br />

04 程 式 結 構<br />

04 程 式 結 構<br />

• switch 敘 述 的 區 塊 中 出 現 兩 個 標 記 (label)<br />

– case 標 記 敘 述 以 及 一 個 default 標 記 敘 述 。<br />

case 標 記 敘 述 的 寫 法 如 下 :<br />

case 常 數 : 敘 述 ;<br />

• case 後 面 的 敘 述 可 以 由 若 干 個 敘 述 組 成 , 最 後 通 常 以<br />

「break;」 結 束 , 跳 出 switch 敘 述 , 緊 接 著 執 行 switch<br />

的 下 一 個 敘 述 。 若 不 以 break 結 束 case 敘 述 則 會 繼 續 執 行<br />

下 一 個 case 或 default 敘 述 , 就 失 去 多 選 一 的 意 義 了 。<br />

defalut 標 記 敘 述 的 寫 法 如 下 :<br />

default : 敘 述 ;<br />

• default 後 面 的 敘 述 可 以 由 若 干 個 敘 述 組 成 , 但<br />

最 後 不 須 以 break 結 束 , 因 為 它 已 經 是 switch 的<br />

最 後 一 個 敘 述 了 , 不 過 您 加 上 break 也 沒 錯 。<br />

04 程 式 結 構<br />

04 程 式 結 構<br />

switch (ch) 的 流 程 圖 如 下 所 示 。<br />

【 程 式 】<br />

/************* charswitch.c ************/<br />

#include <br />

int main()<br />

{<br />

int ch;<br />

printf(" 輸 入 一 個 大 寫 英 文 字 母 ch: ");<br />

scanf("%c", &ch);<br />

switch (ch)<br />

{<br />

case 'A': printf("A"); break;<br />

case 'B': printf("B"); break;<br />

default: printf(" 其 他 ");<br />

}<br />

return 0;<br />

}<br />

04 程 式 結 構<br />

04 程 式 結 構<br />

5


【 程 式 gradeswitch.c】<br />

‧<br />

/********** gradeswitch.c ***********/<br />

#include <br />

int main()<br />

{<br />

int grade;<br />

printf(" 輸 入 成 績 grade: ");<br />

scanf("%d", &grade);<br />

switch (grade/10)<br />

{<br />

case 10:<br />

case 9: printf(" 甲 "); break;<br />

case 8: printf(" 乙 "); break;<br />

case 7: printf(" 丙 "); break;<br />

case 6: printf(" 丁 "); break;<br />

default: printf(" 戊 ");<br />

}<br />

return 0;<br />

}<br />

【 執 行 】<br />

gcc gradeswitch.c -o<br />

gradeswitch.exe <br />

gradeswitch.exe <br />

輸 入 成 績 grade: 99 <br />

甲<br />

gradeswitch.exe <br />

輸 入 成 績 grade: 77 <br />

丙<br />

gradeswitch.exe <br />

輸 入 成 績 grade: 33 <br />

戊<br />

04 程 式 結 構<br />

4.8 while 敘 述<br />

while 重 複 結 構<br />

首 先 測 試 條 件 運 算 式 expression 的 值 ,<br />

若 為 真 則 執 行 其 後 的 statement 敘 述 ,<br />

執 行 完 後 , 重 複 測 試 條 件 運 算 式<br />

語 法 如 下 :<br />

while (expression)<br />

statement ;<br />

• 一 般 statement 常 使 用 複 合 敘 述 。<br />

04 程 式 結 構<br />

【 程 式 triple.c】<br />

/********** triple.c ***********/<br />

#include <br />

int main()<br />

{<br />

int n;<br />

n = 3;<br />

while (n < 100)<br />

{<br />

n = n * 3;<br />

}<br />

printf("%d\n", n);<br />

return 0;<br />

}<br />

【 執 行 】<br />

gcc triple.c -o triple.exe <br />

triple.exe <br />

243<br />

04 程 式 結 構<br />

4.9 do/while 敘 述<br />

• do/while 敘 述 與 while 敘 述 唯 一 不 同 之 處<br />

– while 先 判 斷 條 件 運 算 式 expression 之 值 是 否 為 真 , 再 決 定 是<br />

否 要 執 行 statement 敘 述 ,<br />

– do/while 敘 述 剛 好 相 反 , 它 先 執 行 statement 敘 述 後 再 判 斷 條<br />

件 運 算 式 expression 之 值 是 否 為 真 , 再 決 定 是 否 重 覆 執 行<br />

statement 敘 述 。<br />

• while 後 的 statement 敘 述 可 能 一 次 都 沒 有 執 行<br />

( 開 始 時 條 件 運 算 式 expression 之 值 為 假 ), 但<br />

do/while 後 的 statement 敘 述 最 少 要 執 行 一 次 。<br />

• do/while 敘 述 一 樣 要 注 意 無 窮 迴 圈 的 問 題 。<br />

04 程 式 結 構<br />

• do/while 敘 述 的 語 法 如 下 :<br />

do<br />

statement<br />

while (expression) ;<br />

• 一 般 statement 常 使 用 複 合 敘 述 。<br />

【 程 式 increment.c】<br />

/********** increment.c ***********/<br />

#include <br />

int main()<br />

{<br />

int n;<br />

n = 1;<br />

do<br />

{<br />

printf("%d ", n);<br />

n = n + 1;<br />

} while (n


4.10 for 敘 述<br />

• 以 sum.c 程 式 為 例<br />

• for 敘 述 是 最 常 用 到 的 重 覆 敘 述 , 一 般 稱 為 for 迴 圈 。<br />

• for 敘 述 語 法 如 下 :<br />

for (expression1; expression2; expression3)<br />

statement;<br />

運 算 式 expression1 為 for 迴 圈 控 制 變 數 的 初 值 ,<br />

運 算 式 expression3 為 for 迴 圈 控 制 變 數 的 修 正 值 ,<br />

運 算 式 expression2 是 for 迴 圈 是 否 重 覆 執 行 的 條 件 運 算 式 , 若 條<br />

件 運 算 式 的 值 為 真 則 迴 圈 重 覆 執 行 敘 述 statement, 若 為 假<br />

值 則 終 止 for 迴 圈 之 執 行 。<br />

04 程 式 結 構<br />

04 程 式 結 構<br />

【 程 式 sum.c】<br />

/************** sum.c ***************/<br />

#include <br />

int main()<br />

{ int i, sum;<br />

sum = 0;<br />

for (i=1; i


‧ C 語 言 的 七 種 基 本 結 構<br />

–1 種 循 序 的 結 構<br />

–3 種 選 擇 的 結 構<br />

–3 種 重 複 的 結 構 。<br />

05 流 程 控 制 ( 二 ) 5.1 關 係 運 算 子 與 邏 輯 運 算 子<br />

5.2 關 係 運 算 子 與 運 算 式<br />

5.3 邏 輯 運 算 子 與 運 算 式<br />

5.4 複 合 敘 述<br />

5.5 空 白 敘 述<br />

5.6 break 及 continue 敘 述<br />

5.7 逗 號 運 算 子<br />

其 中 , 選 擇 與 重 複 的 結 構 都 會 改 變 程 式 執 行 的 流 程<br />

‧ break 及 continue 敘 述 會 改 變 程 式 執 行 的 流 程 。<br />

‧ 關 係 運 算 子 與 邏 輯 運 算 子<br />

構 成 條 件 運 算 式 的 運 算 子 , 而 條 件 運 算 式 值 的 真 與 假<br />

決 定 程 式 流 程 的 走 向 。<br />

5.8 條 件 運 算 子<br />

2<br />

05 流 程 控 制 ( 二 )<br />

5.1 關 係 運 算 子 與 邏 輯 運 算 子 (1)<br />

關 係 運 算 子 表<br />

5.1 關 係 運 算 子 與 邏 輯 運 算 子 (2)<br />

邏 輯 運 算 子 表<br />

3<br />

05 流 程 控 制 ( 二 )<br />

05 流 程 控 制 ( 二 )<br />

4<br />

運 算 子 優 先 順 序 表<br />

優 先 順 序<br />

1<br />

( ) [ ] -> .<br />

運 算 子<br />

結 合<br />

左 至 右<br />

5.2 關 係 運 算 子 與 運 算 式<br />

2<br />

3<br />

4<br />

5<br />

6<br />

7<br />

! ~ ++ -- - ( 運 算 元 ) * & sizeof<br />

* / %<br />

+ -<br />

><br />

< >=<br />

== !=<br />

右 至 左<br />

左 至 右<br />

左 至 右<br />

左 至 右<br />

左 至 右<br />

左 至 右<br />

• 六 個 關 係 運 算 子 均 為 二 元 運 算 子<br />

• 六 個 關 係 運 算 子 執 行 結 果<br />

關 係 運 算 式 為 真 , 值 為 整 數 值 1,<br />

關 係 運 算 式 為 假 , 值 為 整 數 值 0。<br />

8<br />

9<br />

10<br />

11<br />

12<br />

13<br />

14<br />

&<br />

^<br />

|<br />

&&<br />

||<br />

:<br />

= += -= *= /= %= = &= |= ^=<br />

左 至 右<br />

左 至 右<br />

左 至 右<br />

左 至 右<br />

左 至 右<br />

右 至 左<br />

右 至 左<br />

範 例<br />

a=5,b=3<br />

a=3,b=3<br />

a=3,b=5<br />

a-b<br />

正 數<br />

零<br />

負 數<br />

ab<br />

1<br />

0<br />

0<br />

15<br />

,<br />

左 至 右<br />

5<br />

6<br />

05 流 程 控 制 ( 二 )<br />

05 流 程 控 制 ( 二 )<br />

1


************ relexpr.c ************/<br />

#include <br />

int main()<br />

{<br />

int a, b;<br />

printf(" 輸 入 兩 個 整 數 a, b: ");<br />

scanf("%d%d", &a,&b);<br />

printf("a=%d b=%d\n", a,b);<br />

printf("a=b 值 為 %d\n", (a>=b));<br />

return 0;<br />

}<br />

gcc relexpr.c -o relexpr.exe <br />

relexpr.exe <br />

輸 入 兩 個 整 數 a, b: 123 123 <br />

a=123 b=123<br />

a=b 值 為 1<br />

05 流 程 控 制 ( 二 )<br />

7<br />

5.3 邏 輯 運 算 子 與 運 算 式 (1)<br />

• 邏 輯 運 算 子 ! 為 一 元 運 算 子 ,<br />

• && 及 || 為 二 元 運 算 子 ,<br />

• ! ,&& 及 || 作 用 於 運 算 式 結 果 為 true( 整 數 值 1) 或<br />

false( 整 數 值 0)。<br />

a<br />

0<br />

0<br />

非 零 整 數<br />

非 零 整 數<br />

b<br />

0<br />

非 零 整 數<br />

0<br />

非 零 整 數<br />

a&&b<br />

0<br />

0<br />

0<br />

1<br />

a||b<br />

0<br />

1<br />

1<br />

1<br />

05 流 程 控 制 ( 二 )<br />

8<br />

5.3 邏 輯 運 算 子 與 運 算 式 (2)<br />

05 流 程 控 制 ( 二 )<br />

9<br />

/************ logexpr.c ************/<br />

#include <br />

int main()<br />

{<br />

int a, b;<br />

printf(" 輸 入 兩 個 整 數 a, b: ");<br />

scanf("%d%d", &a,&b);<br />

printf("a=%d b=%d\n", a,b);<br />

printf("!a 值 為 %d\n", (!a));<br />

printf("!b 值 為 %d\n", (!b));<br />

printf("a&&b 值 為 %d\n", (a&&b));<br />

printf("a||b 值 為 %d\n", (a||b));<br />

return 0;<br />

}<br />

gcc logexpr.c -o logexpr.exe <br />

logexpr.exe <br />

輸 入 兩 個 整 數 a, b: 0 7 <br />

a=0 b=7<br />

!a 值 為 1<br />

!b 值 為 0<br />

a&&b 值 為 0<br />

a||b 值 為 1<br />

10<br />

05 流 程 控 制 ( 二 )<br />

5.4 複 合 敘 述<br />

• 複 合 敘 述 由 宣 告 及 敘 述 組 成<br />

• 包 含 於 一 對 大 括 號 { } 裡 面 。 從 左 大 括 號 開<br />

始 , 其 後 跟 著 敘 述 , 最 後 以 大 括 號 結 束 。<br />

{/* 複 合 敘 述 開 始 */<br />

int a, b, c;<br />

a = 1;<br />

b = 2;<br />

c = a + b;<br />

} /* 複 合 敘 述 結 束 */<br />

if and composite statements<br />

printf(" 輸 入 兩 個 整 數 a,b : ");<br />

scanf("%d%d", &a, &b);<br />

if (a > b)<br />

{<br />

c = a;<br />

printf("a>b");<br />

}<br />

else<br />

{<br />

c = b;<br />

printf("a


5.5 空 白 敘 述<br />

• 空 白 敘 述 只 包 含 一 個 分 號 「;」。 表 示 沒 有<br />

動 作 。 例 如 :<br />

if (a > b)<br />

; /* 空 白 敘 述 */<br />

else<br />

printf("a


5.8 條 件 運 算 子<br />

• 條 件 運 算 子 「:」 為 三 元 運 算 子 , 其 格 式 如 下 :<br />

運 算 元 1 運 算 元 2 : 運 算 元 3<br />

• 若 「 運 算 元 1」 為 非 零 值 , 則 條 件 運 算 子 執 行 的 結<br />

果 為 「 運 算 元 2」 之 值 , 否 則 為 「 運 算 元 3」 之 值 ,<br />

如 下 例 :<br />

int i=-5, absi;<br />

absi = i


06 函 式<br />

6.1 何 謂 函 式<br />

6.2 函 式 宣 告<br />

6.3 函 式 定 義<br />

6.4 函 式 呼 叫<br />

6.5 數 學 函 式 庫<br />

6.6 隨 機 數 產 生 器<br />

6.7 儲 存 類 別<br />

6.8 範 圍<br />

6.9 遞 迴<br />

http://www.csc.com.tw/csc_e/pd/prs05.htm<br />

• 在 C 語 言 中 的 模 組 (module) 稱 為 函 式<br />

(function), 它 沒 有 數 學 上 函 數 那 麼 單 純 , 但 在<br />

C 語 言 程 式 設 計 上 很 重 要 。<br />

• 如 何 設 計 自 己 的 函 式 : 函 式 的 宣 告<br />

(declaration)、 函 式 的 定 義 (definition)、 函<br />

式 的 呼 叫 (call)。<br />

• main() 函 式 是 C 語 言 的 唯 一 且 第 一 個 執 行 之 函 式 。<br />

• 函 式 的 呼 叫 (call): called by value, called by<br />

address (including called by pointer and called<br />

by reference.)<br />

06 函 式<br />

6.1 何 謂 函 式<br />

• 函 式 乃 是 為 完 成 特 定 工 作 的 獨 立 模 組 。<br />

• 函 式 的 架 構 :<br />

// 函 式 宣 告 , appeared in the front of a program<br />

int main()<br />

{<br />

...<br />

// 函 式 呼 叫<br />

...<br />

}<br />

// 函 式 定 義<br />

06 函 式<br />

/********* square.c *********/<br />

#include <br />

int square(int); /* 函 式 宣 告 */<br />

int main()<br />

{ int s;<br />

s = square(3); /* 函 式 呼 叫 */<br />

printf("3*3=%d\n", s);<br />

return 0;<br />

}<br />

int square(int a) /* 函 式 定 義 */<br />

{ int ret;<br />

ret = a * a;<br />

return (ret);<br />

}<br />

【 執 行 】<br />

square.exe <br />

3*3=9<br />

/********* square.c *********/<br />

#include <br />

int square(int); /* 函 式 宣 告 */<br />

int square(int a) /* 函 式 定 義 */<br />

{ int ret;<br />

ret = a * a;<br />

return (ret);<br />

}<br />

「 函 式 定 義 」 寫 在 main() 函 式 之 前<br />

int main()<br />

{ int s;<br />

s = square(3); /* 函 式 呼 叫 */<br />

printf("3*3=%d\n", s);<br />

return 0;<br />

}<br />

06 函 式<br />

6.2 函 式 宣 告<br />

• 函 式 宣 告 的 格 式 如 下 :<br />

傳 回 值 資 料 型 態 函 式 名 稱 ( 參 數 資 料 型 態 ) ;<br />

• 如 下 例 :<br />

int square ( int ) ;<br />

傳 回 值 資 料 型 態 函 式 名 稱 參 數 資 料 型 態 分 號 結 束<br />

• 「 傳 回 值 型 態 」 及 「 參 數 型 態 」 可 為 C 語 言 任 何 合 乎 語 法 的<br />

資 料 型 態 , 如 字 元 型 態 的 char、 整 數 型 態 的 int、 浮 點 數 型<br />

態 的 float 等 等 , 若 沒 有 傳 回 值 型 態 則 以 關 鍵 字 void 表 示 之 。<br />

6.3 函 式 定 義<br />

傳 回 值 資 料 型 態 函 式 名 稱 ( 參 數 資 料 型 態 參 數 名 稱 〕<br />

{<br />

宣 告<br />

...<br />

敘 述<br />

...<br />

}<br />

• 函 式 定 義 的 第 一 列 除 了 最 後 的 符 號 ; ,<br />

與 函 式 宣 告 相 同<br />

• 若 沒 有 參 數 則 以 void 表 示 。「 參 數 名 稱 」 稱 為<br />

形 式 參 數 , 或 簡 稱 為 參 數 。 執 行 時 參 數 的 值 將<br />

被 「 函 式 呼 叫 」 時 的 引 數 值 所 取 代 。<br />

06 函 式<br />

06 函 式<br />

1


6.4 函 式 呼 叫<br />

或<br />

函 式 名 稱 ( 引 數 ) ;<br />

變 數 = 函 式 名 稱 ( 引 數 ) ;<br />

引 數 為 實 際 的 值 , 引 數 間 以 逗 號 「,」 隔 開 。<br />

s = square( 3 ); /*square() 函 式 呼 叫 */<br />

s2 = sum ( 2 , 4 ) ; /*sum() 函 式 呼 叫 */<br />

06 函 式<br />

/************ callfunc.c ***********/<br />

#include <br />

int square(int a)<br />

{ a = a * a;<br />

return a;<br />

}<br />

int main()<br />

{ int i=3, s;<br />

printf(" 呼 叫 square(i) 前 i=%d\n", i);<br />

s = square(i);<br />

printf(" 呼 叫 square(i) 後 i=%d s=%d\n", i,s);<br />

return 0;<br />

【 執 行 】<br />

}<br />

callfunc.exe <br />

呼 叫 square(i) 前 i=3<br />

呼 叫 square(i) 後 i=3 s=9<br />

06 函 式<br />

6.5 數 學 函 式 庫<br />

6.5 數 學 函 式 庫<br />

• 由 於 C 語 言 提 供 了 前 置 處 理 器 藉 著<br />

「#include」 指 引 指 令 可 將 一 些 事 先 設 計 好<br />

的 常 數 、 函 式 , 儲 存 於 函 式 庫 , 使 用 時 才<br />

將 它 引 入 使 用 者 的 應 用 程 式 中 , 一 起 編<br />

譯 、 連 結 、 執 行 , 大 大 的 提 高 程 式 設 計 的<br />

生 產 能 力 。<br />

• 數 學 函 式 庫 math.h 表 頭 檔 讓 使 用 者 輕 易 地<br />

執 行 某 些 常 用 的 數 學 運 算 。<br />

06 函 式<br />

http://www.cppreference.com/stdmath/index.html<br />

06 函 式<br />

/************* fabs.c **************/<br />

#include <br />

#include <br />

int main()<br />

{ double x;<br />

printf(" 輸 入 一 個 倍 精 確 浮 點 數 x: ");<br />

scanf("%lf", &x);<br />

printf("fabs(%lf)=%lf\n", x, fabs(x));<br />

return 0;<br />

} 【 執 行 】<br />

fabs.exe <br />

輸 入 一 個 倍 精 確 浮 點 數 x: -123.0 <br />

fabs(-123.000000)=123.000000<br />

fabs.exe <br />

輸 入 一 個 倍 精 確 浮 點 數 x: 246.8 <br />

fabs(246.800000)=246.800000<br />

06 函 式<br />

/*********** trifunc.c ************/<br />

#include <br />

#include <br />

int main()<br />

{ double ang, x;<br />

printf(" 輸 入 一 個 倍 精 確 浮 點 數 角 度 ang: ");<br />

scanf("%lf", &ang);<br />

x = M_PI * ang / 180.0;<br />

printf("cos(%lf)=%lf\n", x, cos(x));<br />

printf("sin(%lf)=%lf\n", x, sin(x));<br />

printf("tan(%lf)=%lf\n", x, tan(x));<br />

return 0;<br />

【 執 行 】<br />

}<br />

trifunc.exe <br />

輸 入 一 個 倍 精 確 浮 點 數 角 度 ang: 60.0 <br />

cos(1.047198)=0.500000<br />

sin(1.047198)=0.866025<br />

tan(1.047198)=1.732051<br />

06 函 式<br />

2


*********** squareroot.c ************/<br />

#include <br />

#include <br />

int main()<br />

{ double x;<br />

printf(" 輸 入 一 個 倍 精 確 浮 點 數 x: ");<br />

scanf("%lf", &x);<br />

printf("sqrt(%lf)=%lf\n", x, sqrt(x));<br />

return 0; 【 執 行 】<br />

}<br />

squareroot.exe <br />

輸 入 一 個 倍 精 確 浮 點 數 x: 2.0 <br />

sqrt(2.000000)=1.414214<br />

06 函 式<br />

/************ ceilfloor.c *************/<br />

#include <br />

#include <br />

int main()<br />

{ double x;<br />

printf(" 輸 入 一 個 倍 精 確 浮 點 數 x: ");<br />

scanf("%lf", &x);<br />

printf("ceil(%lf)=%lf\n", x, ceil(x));<br />

printf("floor(%lf)=%lf\n", x, floor(x));<br />

return 0;<br />

ceilfloor.exe <br />

}<br />

輸 入 一 個 倍 精 確 浮 點 數 x: -16.3 <br />

ceilfloor.exe <br />

ceil(-16.300000)=-16.000000<br />

輸 入 一 個 倍 精 確 浮 點 數 x: 25.5 floor(-16.300000)=-17.000000<br />

ceil(25.500000)=26.000000<br />

floor(25.500000)=25.000000<br />

06 函 式<br />

6.6 隨 機 數 產 生 器<br />

• 在 科 學 研 究 及 及 遊 戲 的 領 域 , 經 常 需 要 做 適 當 的 模<br />

擬 , 才 能 分 析 問 題 , 找 出 解 決 問 題 的 方 案 。<br />

• 在 C 語 言 提 供 模 擬 作 業 , 通 常 使 用 隨 機 數 產 生 器 兩 個<br />

函 式 :rand() 及 srand()。<br />

• rand() 函 式 傳 回 一 個 介 於 0( 含 ) 與 RAND_MAX<br />

( 含 ) 之 間 的 整 數 。RAND_MAX 為 定 義 於 stdlib.h 表<br />

頭 檔 裡 的 符 號 常 數 , 隨 著 C 編 譯 器 的 不 同 而 異 。<br />

• srand() 函 式 可 以 讓 您 改 變 隨 機 種 子 而 取 得 不 同 系 列<br />

的 隨 機 數 。<br />

/************* diepoint.c ***********/<br />

#include <br />

#include <br />

int main()<br />

{ int i;<br />

printf("RAND_MAX=%d\n",RAND_MAX);<br />

for (i=1; i


***************** duration.c *****************/<br />

#include <br />

int total;<br />

int main()<br />

{ int a, b, i;<br />

for (i=1; i


C 語 言 基 本 四 種 變 數 等 級<br />

變 數 等 級<br />

auto 變 數<br />

( 普 通 內 在 變 數 )<br />

static auto 變 數<br />

(static 內 在 變 數 )<br />

extern 變 數<br />

( 普 通 外 在 變 數 )<br />

static extern 變 數<br />

(static 外 在 變 數 )<br />

生 命 週 期<br />

從 函 式 ( 或 區 段 ) 執 行 開 始 , 直 到<br />

函 式 ( 或 區 段 ) 執 行 結 束 。<br />

直 到 程 式 結 束 為 止 。<br />

從 程 式 執 行 到 程 式 結 束 為 止 。<br />

從 程 式 執 行 到 程 式 結 束 為 止 。<br />

視 野<br />

僅 限 於 區 段 之 內 。<br />

( 區 段 視 野 )<br />

僅 限 於 區 段 之 內 。<br />

( 區 段 視 野 )<br />

跨 檔 案 的 所 有 函 式 。<br />

( 檔 案 視 野 )<br />

同 一 檔 案 內 的 所 有 函<br />

式 。( 檔 案 視 野 )<br />

6.9 遞 迴<br />

‧ 一 般 函 式 通 常 都 呼 叫 別 的 函 式 ;<br />

‧ 遞 迴 函 式 一 定 會 呼 叫 函 式 本 身 , 稱 為 遞 迴<br />

(recursive) 呼 叫 。<br />

‧ 遞 迴 呼 叫 的 必 備 機 制<br />

– 在 遞 迴 呼 叫 的 函 式 中 必 須 有 結 束 條 件 設 計 ( 停 止<br />

遞 迴 的 機 制 ), 否 則 會 無 窮 無 盡 的 遞 迴 ,<br />

– 未 到 達 結 束 條 件 之 前 , 一 定 會 呼 叫 函 式 本 身 。<br />

陳 錦 輝 ,C/C++ 初 學 指 引 , 金 禾 書 局 06 (R501 函 式<br />

06 函 式<br />

/************* recur.c **************/<br />

#include <br />

void msg(int n)<br />

{ if (n>0)<br />

{ printf(" 您 好 !!\n");<br />

msg(n-1);<br />

}<br />

}<br />

數 學 階 乘 觀 念<br />

int main()<br />

{ int n;<br />

printf(" 您 要 重 複 顯 示 信 息 幾 次 n: ");<br />

scanf("%d", &n);<br />

}<br />

msg(n);<br />

return 0;<br />

recur.exe <br />

您 要 重 複 顯 示 信 息 幾 次 n: 3 <br />

您 好 !!<br />

您 好 !!<br />

您 好 !!<br />

06 函 式<br />

06 函 式<br />

/************ factorial.c *************/<br />

#include <br />

long factorial(int n)<br />

{ if (n


7.1 陣 列<br />

07 陣 列<br />

7.1 陣 列<br />

7.2 宣 告 陣 列<br />

7.3 陣 列 長 度<br />

7.4 陣 列 範 例<br />

7.5 陣 列 與 函 式 呼 叫<br />

7.6 陣 列 與 排 序<br />

7.7 陣 列 與 搜 尋 法<br />

7.8 多 維 陣 列<br />

‧ 陣 列 是 在 電 腦 記 憶 體 裡 一 塊 連 續 的 記 憶 體 , 用<br />

於 儲 存 同 一 型 態 的 若 干 個 資 料 。<br />

‧ 每 一 個 陣 列 資 料 均 使 用 同 一 個 名 稱 ( 亦 即 陣 列<br />

名 稱 )。 及 位 置 索 引 值 來 參 考 陣 列 中 某 一 個 位<br />

置 或 元 素 。<br />

‧ 陣 列 的 概 念 包 括<br />

陣 列 的 宣 告 、 初 值 的 設 定 、 陣 列 使 用<br />

07 陣 列<br />

陣 列 ( 續 )<br />

‧ 注 意 陣 列 的 位 置 索 引 , 又 稱 為 註 標 , 是 從 0 算 起<br />

的 。 註 標 必 須 是 整 數 或 整 數 運 算 式 ,<br />

‧n 個 元 素 的 陣 列 其 註 標 是 從 第 0 個 至 第 (n-1) 個 。<br />

‧int k[8]={64, 38, 16, 49, 91, 73, 82, 27};<br />

為 整 數 陣 列 k, 包 含 8 個 元 素 , 第 0 個 元 素 表 示<br />

為 k[0], 第 1 個 元 素 表 示 為 k[1], 第 7 個 元 素 表<br />

示 為 k[7] 等 等 。<br />

陣 列 ( 續 )<br />

‧ 陣 列 是 由 一 群 具 有 相 同 資 料 型 態 的 元 素 所 組 成 的 , 利 用<br />

迴 圈 並 配 合 陣 列 的 註 標 , 可 輕 易 的 處 理 大 量 的 資 料 。<br />

‧ 陣 列 及 結 構 在 資 料 結 構 中 佔 很 重 要 的 地 位 。<br />

‧ 結 構 (struct) 中 的 元 素 可 由 不 同 型 態 的 資 料 組 成 。<br />

‧ 陣 列 與 未 含 指 標 成 員 的 struct 結 構 體 均 屬 於 靜 態 結 構 。<br />

‧ 含 指 標 成 員 的 struct 結 構 ( 串 列 、 佇 列 、 堆 疊 與 樹 等 結<br />

構 ) 則 屬 於 動 態 結 構 。<br />

07 陣 列<br />

07 陣 列<br />

7.2 宣 告 陣 列<br />

• 陣 列 佔 一 塊 連 續 的 記 憶 體 空 間 , 必 須 標 明 每 一<br />

個 元 素 的 型 態 , 以 及 元 素 的 個 數 , 編 譯 器 才 能 決<br />

定 出 所 需 的 記 憶 體 空 間 。 例 如<br />

int k[8];<br />

上 述 宣 告 告 訴 電 腦 幫 您 保 留 一 個 八 個 元 素 的 整 數<br />

陣 列<br />

int a[6], b[13], c[52];<br />

/* 宣 告 一 個 八 個 元 素 的 整 數 陣 列 k*/<br />

一 個 宣 告 敘 述 可 以 同 時 宣 告 若 干 個 陣 列 , 以 逗 號<br />

隔 開 。<br />

07 陣 列<br />

宣 告 陣 列 ( 續 )<br />

• 陣 列 元 素 在 宣 告 時 同 時 給 予 初 值 , 如 下 例 :<br />

int k[] = {64,38,16,49,91,73,82,37};<br />

宣 告 一 個 整 數 陣 列 k, 含 八 個 元 素 , 其 值 分 別 為<br />

k[0]=64、k[1]=38、k[2]=16、k[3]=49、<br />

k[4]=91、k[5]=73、k[6]=82 及 k[7]=37。<br />

• 注 意 : 方 括 號 內 可 以 不 標 明 陣 列 元 素 個 數 , 編<br />

譯 器 會 決 定 其 個 數<br />

07 陣 列<br />

1


宣 告 陣 列 ( 續 )<br />

一 維 陣 列<br />

• 字 元 陣 列 宣 告<br />

char c[ ] = {'A','a','1','+'};<br />

宣 告 一 個 字 元 陣 列 c, 含 四 個 元 素 , 其 值 分 別 為<br />

c[0]=‘A’、c[1]=‘a’、c[2]=‘1’ 及 c[3]=‘+’。<br />

• 當 明 確 定 義 陣 列 大 小 時 , 若 設 定 的 陣<br />

列 元 素 初 始 值 不 足 , 則 編 譯 器 會 將 剩<br />

餘 未 設 定 初 值 的 元 素 內 容 設 定 為 0( 針<br />

對 數 值 陣 列 而 言 )<br />

float Temper[12]={0}; // 同 時 將 12 個 元 素 內 容 皆 設 定 為 0<br />

圖 6-1 陣 列 的 記 憶 體 配 置<br />

07 陣 列<br />

陳 錦 輝 ,C/C++ 初 學 指 引 , 金 禾 書 局 07 (R501)。 陣 列<br />

【 程 式 intarray.c】<br />

/************ intarray.c ************/<br />

#include <br />

int main()<br />

{<br />

int k[]={64, 38, 16, 49, 91, 73, 82, 37};<br />

double d[]={1.2, 3.4, 5.6};<br />

char c[]={'A', 'a', '1', '+'};<br />

printf("c[1]=%c\n", c[1]);<br />

printf("d[2]=%lf\n", d[2]);<br />

printf("k[3]=%d\n", k[3]);<br />

system(“pause”);<br />

return 0;<br />

}<br />

/*********** initarray.c ***********/<br />

#include <br />

int main()<br />

{<br />

int k[8]={0}, m[8];<br />

printf("k[3]=%d\n", k[3]);<br />

printf("k[5]=%d\n", k[5]);<br />

printf("k[7]=%d\n", k[7]);<br />

printf("m[3]=%d\n", m[3]);<br />

printf("m[5]=%d\n", m[5]);<br />

printf("m[7]=%d\n", m[7]);<br />

system(“pause”);<br />

return 0;<br />

}<br />

【 執 行 】<br />

initarray.exe <br />

k[3]=0<br />

k[5]=0<br />

k[7]=0<br />

m[3]=-1<br />

m[5]=2293728<br />

m[7]=2013471392<br />

07 陣 列<br />

07 陣 列<br />

7.3 陣 列 長 度<br />

sizeof 運 算 子 可 以 求 得 每 一 個 陣 列 長 度<br />

( 元 素 個 數 以 位 元 組 計 算 )。<br />

/************* lenarray.c **************/<br />

#include <br />

int main()<br />

{ int k[ ]={64, 38, 16, 49, 91, 73, 82, 37};<br />

float f[ ]={1.2, 3.4, 5.6};<br />

char c[ ]={'A', 'a', '1', '+'};<br />

printf(" 整 數 陣 列 k 的 長 度 ( 元 素 個 數 )=%d\n",<br />

sizeof(k)/sizeof(int) );<br />

printf(" 浮 點 數 陣 列 f 的 長 度 ( 元 素 個 數 )=%d\n",<br />

sizeof(f)/sizeof(float) );<br />

printf(" 字 元 陣 列 c 的 長 度 ( 元 素 個 數 )=%d\n",<br />

sizeof(c)/sizeof(char) );<br />

system(“pause”);<br />

return 0;<br />

}<br />

lenarray.exe <br />

整 數 陣 列 k 的 長 度 ( 元 素 個 數 )=8<br />

浮 點 數 陣 列 f 的 長 度 ( 元 素 個 數 )=3<br />

字 元 陣 列 c 的 長 度 ( 元 素 個 數 )=4<br />

07 陣 列<br />

7.4 陣 列 範 例<br />

/************* evenarray.c **************/<br />

#include <br />

#define SIZE 8<br />

int main()<br />

{ int a[SIZE], i;<br />

for (i=0; i


************** sumarray.c ***************/<br />

#include <br />

int main()<br />

{ int k[]={24, 38, 16, 49, 51, 33, 42, 37};<br />

int i, SIZE=sizeof(k)/sizeof(int); // 使 用 sizeof 計 算 整 數 陣 列 a 的 個 數<br />

float sum=0.0, avg;<br />

for (i=0; i


*************** passarray.c **************/<br />

#include <br />

void doublearray (int b[ ], int size) // called by address<br />

{<br />

int i;<br />

printf("\nb 陣 列 的 位 址 =0x%p\n", b);<br />

for (i=0; i


氣 泡 排 序 法 (Bubble Sort)<br />

• 『 氣 泡 排 序 法 』 是 一 種 非 常 簡 單 且 容 易 的 排 序 方 法 ( 效 率 普 通 )<br />

• 『 氣 泡 排 序 法 』 將 相 鄰 的 兩 個 資 料 一 一 互 相 比 較 , 依 據 比 較 結<br />

果 , 決 定 資 料 是 否 需 要 對 調 , 由 於 整 個 執 行 過 程 , 有 如 氣 泡 逐 漸<br />

浮 上 水 面 , 因 而 得 名 , 其 方 法 及 示 意 圖 如 下 :<br />

• 假 設 我 們 有 {24,7,36,2,65} 要 做 氣 泡 排 序 , 最 後 的 排 序 結 果 為<br />

{2,7,24,36,65}。<br />

for (i=1; i


***************** bsearch.c *****************/<br />

#include <br />

#include <br />

int comp (int *arg1, int *arg2) { // 略 }<br />

int main()<br />

{ int i,*ip, item=33;<br />

// int a[] = {84, 78, 16, 69, 96, 33, 82, 77, 55};<br />

// qsort (a, N, sizeof(int), comp);<br />

int a[ ] = {16, 33, 55, 69, 77, 78, 82, 84, 96 };<br />

int N = sizeof(a)/sizeof(int);<br />

for (i=0; i


08 指 標<br />

8.1 宣 告 及 初 始 化<br />

8.2 指 標 運 算 子<br />

8.3 函 式 呼 叫<br />

8.4 指 標 算 術<br />

8.5 指 標 陣 列<br />

8.6 函 式 指 標<br />

• C 語 言 一 個 最 強 大 的 功 能 , 就 是 指 標<br />

(pointer), 它 也 是 最 難 理 解 的 一 個 項<br />

目 , 指 標 讓 設 計 者 能 夠 模 擬 函 式 的 傳<br />

址 呼 叫 、 建 立 並 操 作 動 態 資 料 結 構 ,<br />

例 如 動 態 的 連 結 串 列 、 佇 列 、 堆 疊 、<br />

以 及 樹 等 結 構 , 這 種 結 構 號 稱 動 態 ,<br />

意 即 其 節 點 隨 時 可 以 增 減 。<br />

08 指 標<br />

8.1 宣 告 及 初 始 化<br />

• 指 標 變 數 事 實 上 就 是 一 個 變 數 , 只 不 過 它 的 內 含<br />

值 是 一 個 位 址 而 已 。<br />

char ch='A';<br />

char *p=&ch;<br />

變 數 p 宣 告 為 char * 型 態<br />

• 宣 告 時 * 運 算 子 表 示 所 宣 告 的 變 數 屬 於 指 標 變 數 ,<br />

• 運 算 子 & 表 示 取 其 後 變 數 的 位 址 。<br />

/**************** charptr.c *****************/<br />

#include <br />

int main()<br />

{<br />

char ch='A';<br />

char *p=&ch;<br />

printf("&ch=0x%p ch=%c\n", &ch, ch);<br />

printf(" &p=0x%p p=0x%p *p=%c\n", &p, p, *p);<br />

return 0;<br />

}<br />

【 執 行 】<br />

charptr.exe <br />

&ch=0x0022FF77 ch=A<br />

&p=0x0022FF70 p=0x0022FF77 *p=A<br />

08 指 標<br />

08 指 標<br />

/*************** intptr.c ***************/<br />

#include <br />

int main()<br />

{<br />

int k=123;<br />

int *p=&k;<br />

printf("&k=0x%p k=%d\n", &k, k);<br />

printf("&p=0x%p p=0x%p *p=%d\n", &p, p, *p);<br />

return 0;<br />

}<br />

【 執 行 】<br />

intptr.exe <br />

&k=0x0022FF74 k=123<br />

&p=0x0022FF70 p=0x0022FF74 *p=123<br />

08 指 標<br />

8.2 指 標 運 算 子<br />

• 指 標 運 算 子 & 稱 為 位 址 運 算 子 , 是 一 個 一 元 運 算 子 , 傳 回 運<br />

算 元 的 位 址 。<br />

或<br />

int k=123;<br />

int *p=&k;<br />

p=&k;<br />

• 位 址 運 算 子 & 的 運 算 元 必 須 為 變 數 , 不 能 為 常 數 、 運 算 式 。<br />

• 指 標 運 算 子 * 又 稱 為 間 接 運 算 子 , 傳 回 運 算 元 所 指 位 址 的 內<br />

含 值 。 如 下 例 :<br />

printf("%d", *p);<br />

/* 傳 回 運 算 元 k 的 位 址 指 定 給 p*/<br />

/* 傳 回 運 算 元 k 的 位 址 指 定 給 p*/<br />

• 將 p 所 指 位 址 的 內 含 值 顯 示 出 來 。<br />

08 指 標<br />

1


8.3 函 式 呼 叫<br />

• 函 式 呼 叫 有 兩 種 方 式 , 傳 值 及 傳 址 呼 叫 。<br />

• 傳 值 呼 叫 的 引 數 值 為 一 般 的 數 值 ,<br />

• 傳 址 呼 叫 所 傳 的 引 數 值 為 位 址 值 。<br />

08 指 標<br />

/***************** byval.c *****************/<br />

#include <br />

int cube(int n)<br />

{<br />

n = n*n*n;<br />

return n;<br />

}<br />

int main()<br />

{<br />

int i=4, j;<br />

printf(" 呼 叫 cube() 函 式 之 前 i=%d\n", i);<br />

j = cube(i);<br />

printf(" 呼 叫 cube() 函 式 之 後 i=%d j=%d\n", i,j);<br />

return 0;<br />

}<br />

08 指 標<br />

/************ byaddr.c **************/<br />

#include <br />

void cubeByRef ( int *p )<br />

{ *p = (*p) * (*p) * (*p);<br />

}<br />

int main()<br />

{ int i = 4;<br />

printf(" 呼 叫 cube() 函 式 之 前 i=%d\n", i);<br />

printf(" 呼 叫 cube() 函 式 之 前 &i=%p\n", &i);<br />

cubeByRef(&i);<br />

printf(" 呼 叫 cube() 函 式 之 後 i=%d\n", i);<br />

printf(" 呼 叫 cube() 函 式 之 後 &i=%p\n", &i);<br />

return 0;<br />

}<br />

08 指 標<br />

/************** convert.c ****************/<br />

#include <br />

void conv ( char *p )<br />

{ while (*p!='\0')<br />

{ if (*p>='a' && *p


8.4 指 標 算 術<br />

• 在 算 術 運 算 式 、 指 定 運 算 式 、 以 及 比 較 運 算 式 中<br />

指 標 是 一 個 正 確 的 運 算 元 , 在 其 他 的 運 算 式 中 指<br />

標 並 不 是 正 確 的 運 算 元 , 這 一 點 請 特 別 注 意 。<br />

• 指 標 的 運 算 也 只 限 於 有 限 的 幾 個 運 算 子 而 已 :<br />

– 指 標 的 遞 加 ++、 指 標 的 遞 減 --<br />

– 指 標 的 整 數 加 法 + 或 +=、 指 標 的 整 數 減 法 - 或 -=<br />

• 事 實 上 , 指 標 內 容 指 向 令 一 個 變 數 的 位 址 , 要 了<br />

解 指 標 的 運 算 最 好 能 夠 了 解 資 料 在 電 腦 記 憶 體 中<br />

的 表 示 法 。<br />

08 指 標<br />

/******************** size.c *******************/<br />

#include <br />

int main()<br />

{ printf(" sizeof(char)=%2d\n",sizeof(char) );<br />

printf(" sizeof(short)=%2d\n",sizeof(short) );<br />

printf(" sizeof(int)=%2d\n",sizeof(int) );<br />

printf(" sizeof(long)=%2d\n",sizeof(long) );<br />

printf(" sizeof(float)=%2d\n",sizeof(float) );<br />

printf(" sizeof(double)=%2d\n",sizeof(double) );<br />

printf("sizeof(long double)=%2d\n",sizeof(long double) );<br />

return 0;<br />

}<br />

To know the advance step of a variable<br />

08 指 標<br />

/************** arrayptr.c **************/<br />

#include <br />

int main()<br />

{<br />

int a[] = {11, 22, 33, 44};<br />

int i, j, SIZE=sizeof(a)/sizeof(int);<br />

int *p = a;<br />

printf(" 整 數 陣 列 a 每 一 個 元 素 的 位 址 \n");<br />

for (i=0; i


8.5 指 標 陣 列<br />

• 字 元 指 標 陣 列 char *suit[4] 包 含 四 個 元 素 , 每 個 元 素 均<br />

為 一 個 字 串<br />

char *suit[4] = {"C", "D", "H", "S"};<br />

• 字 元 指 標 陣 列 char *point[13]<br />

包 含 13 個 元 素 , 每 個 元 素 均<br />

為 一 個 字 串 。<br />

char *point[13] =<br />

{"A", "2", "3", "4", "5", "6",<br />

"7","8", "9", "10", "Jack",<br />

"Queen", "King" };<br />

a c k \0<br />

u e e n \0<br />

k i n g \0<br />

08 指 標<br />

08 指 標<br />

字 串 與 二 維 陣 列<br />

字 串 與 一 維 指 標 陣 列<br />

圖 8-14 使 用 指 標 陣 列 宣 告 方 式 儲 存 字 串 群<br />

圖 8-13 使 用 二 維 陣 列 宣 告 方 式 儲 存 字 串 群<br />

明 顯 地 , 它 節 省 了 一 些 記 憶 體 空 間<br />

陳 錦 輝 ,C/C++ 初 學 指 引 , 金 禾 書 局 08 (R501)。 指 標<br />

陳 錦 輝 ,C/C++ 初 學 指 引 , 金 禾 書 局 08 (R501)。 指 標<br />

8.6 函 式 指 標<br />

• 函 式 的 指 標 是 指 該 函 式 在 記 憶 體 中 的 位 址 。<br />

• 就 像 陣 列 一 樣 , 陣 列 名 稱 為 在 記 憶 體 中 第 0 個<br />

元 素 的 位 址 , 函 式 的 名 稱 也 是 在 記 憶 體 中 該 函<br />

式 的 開 始 位 址 。<br />

• 函 式 指 標 可 以 當 另 一 個 函 式 的 引 數 , 也 就 是 說<br />

函 式 定 義 中 其 參 數 可 為 另 一 個 函 式 指 標 。<br />

• 函 式 指 標 也 可 以 當 函 式 的 傳 值 、 儲 存 於 陣 列<br />

中 、 或 指 定 為 其 他 的 函 式 指 標 等 等 。<br />

08 指 標<br />

/**************** funcptr.c ***************/<br />

#include <br />

#include <br />

#include <br />

void func0( int a )<br />

{ printf("func0() 函 式 的 參 數 a=%d\n", a);<br />

}<br />

void func1( int a )<br />

{ printf("func1() 函 式 的 參 數 a=%d\n", a);<br />

}<br />

int main()<br />

{ int n;<br />

void (*f)(int);<br />

srand(time(NULL));<br />

n=rand();<br />

if (n%2==0)<br />

f=func0;<br />

else<br />

f=func1;<br />

(*f)(n); // firing a function<br />

return 0;<br />

}<br />

08 指 標<br />

4


************************* sorting.c ********************/<br />

/**************** sorting.c (cont.) ****************/<br />

#include <br />

void bubble(int *work, int size, int (*compare)(int, int) ) //function<br />

#define SIZE 10<br />

pointer<br />

void bubble(int *, int, int (*)(int, int) ); //function pointer<br />

{ int i, j; // may be either ascending or descending<br />

int ascending(int, int);<br />

void swap(int *, int *);<br />

int descending(int, int);<br />

for (i=0; i


09 字 元 與 字 串<br />

9.1 字 元 處 理 函 式 庫<br />

9.3 字 串 轉 換 函 式<br />

9.4 字 元 字 串 輸 入 及 輸 出<br />

9.2 字 串 長 度 *<br />

9.5 字 串 操 作 函 式<br />

9.6 字 串 比 較 函 式<br />

9.7 字 串 搜 尋 函 式<br />

9.8 字 串 記 憶 體 函 式 *<br />

9.9 字 串 錯 誤 訊 息<br />

字 元 、 字 串<br />

‧ 字 元 是 構 成 字 串 的 元 素 。<br />

‧ 字 元 常 數 是 一 個 以 單 引 號 括 起 來 的 字 元 , 表 示<br />

某 一 符 號 的 整 數 值 , 例 如 字 元 常 數 `A'。<br />

• 字 元 常 數 ‘\0’ , 也 稱 為 NULL 常 數 。<br />

• 字 串 是 由 含 有 字 母 、 數 字 及 數 種 特 殊 的 字 元 所<br />

組 成 , 以 字 元 常 數 ‘\0’ 當 字 串 結 束 符 號 。<br />

• 字 串 常 數 以 含 在 兩 個 雙 引 號 間 的 字 元 表 示 。<br />

"Good Morning!"<br />

"Kay Lin"<br />

"(07)2259999“<br />

“ 您 好 !”<br />

“ 歡 迎 光 臨 ”<br />

09 字 元 與 字 串<br />

字 串 及 字 元 陣 列<br />

char color[]={'r','e','d'};<br />

字 元 陣 列 color, 包 含 3 個 字 元 元 素 ‘r’,‘e’, ‘d’。<br />

不 能 稱 為 字 串<br />

char color[]={'r','e','d','\0'};<br />

字 元 陣 列 color, 包 含 4 個 字 元 元 素 ‘r’,‘e’, ‘d<br />

及 ’\0‘ ; 也 是 字 串 。<br />

char color[]=“red”;<br />

char *p="blue";<br />

陣 列 名 稱 具 有 指 標 功 能 , 指 向 為 陣 列 的 開 始 元 素 的 位 址 。<br />

09 字 元 與 字 串<br />

【 程 式 chartest.c】<br />

/************* chartest.c *************/<br />

#include <br />

int main()<br />

{<br />

char color[]={'r','e','d','\0'};<br />

char *p="blue";<br />

int i;<br />

for (i=0; i


************* inputchar.c *************/<br />

#include <br />

#include <br />

int main()<br />

{<br />

char ch;<br />

printf(" 請 輸 入 一 個 字 元 : ");<br />

scanf("%c", &ch);<br />

if ( isdigit(ch) )<br />

printf(" %c 是 數 字 \n", ch);<br />

else<br />

printf(" %c 非 數 字 \n", ch);<br />

if ( isalpha(ch) )<br />

printf(" %c 是 英 文 字 母 \n", ch);<br />

else<br />

printf(" %c 非 英 文 字 母 \n", ch);<br />

return 0;<br />

}<br />

09 字 元 與 字 串 09 字 元 與 字 串<br />

/***************** lower.c ****************/<br />

#include <br />

#include <br />

int main()<br />

{ char ch;<br />

printf(" 請 輸 入 一 個 字 元 : ");<br />

scanf("%c", &ch);<br />

if ( islower(ch) )<br />

{ printf(" %c 是 小 寫 英 文 字 母 \n", ch);<br />

printf(" %c 轉 成 大 寫 字 母 為 %c\n", ch, toupper(ch));<br />

}<br />

else<br />

printf(" %c 非 小 寫 英 文 字 母 \n", ch);<br />

if ( isupper(ch) )<br />

{ printf(" %c 是 大 寫 英 文 字 母 \n", ch);<br />

printf(" %c 轉 成 小 寫 字 母 為 %c\n", ch, tolower(ch));<br />

}<br />

else<br />

printf(" %c 非 大 寫 英 文 字 母 \n", ch);<br />

return 0;<br />

}<br />

09 字 元 與 字 串<br />

/***************** testctrl.c *****************/<br />

#include <br />

#include <br />

int main()<br />

{ printf(" 新 列 '\\n' %s\n",<br />

isspace('\n') " 是 空 白 字 元 " : " 不 是 空 白 字 元 ");<br />

printf("beep '\\007' %s\n",<br />

iscntrl('\007') " 是 控 制 字 元 " : " 不 是 控 制 字 元 ");<br />

printf(" 分 號 ';' %s\n",<br />

ispunct(';') " 是 標 點 符 號 字 元 " : " 不 是 標 點 符 號 字 元 ");<br />

printf("'A' %s\n",<br />

isprint('A') " 是 可 印 字 元 " : " 不 是 可 印 字 元 ");<br />

printf(" 空 白 ' ' %s\n",<br />

isgraph(' ') " 是 可 繪 圖 字 元 " : " 不 是 可 繪 圖 字 元 ");<br />

return 0;<br />

}<br />

09 字 元 與 字 串<br />

9.3 字 串 轉 換 函 式<br />

String conversion (1)<br />

• 字 串 轉 換 函 式 將 由 數 字 所 組 成 的 字 串 轉 換 成 整 數 、 長 整 數 、<br />

或 倍 精 確 浮 點 數 。<br />

• 字 串 轉 換 函 式 定 義 於 公 用 函 式 庫 stdlib.h 裡<br />

double atof(const char *s)<br />

• 將 s 字 串 轉 換 並 傳 回 倍 精 確 浮 點 數 。 轉 換 不 成 功 時 傳 回 0 值 。<br />

int atoi(const char *s)<br />

• 將 s 字 串 轉 換 並 傳 回 整 數 值 。 轉 換 不 成 功 時 傳 回 0 值 。<br />

long atol(const char *s)<br />

• 將 s 字 串 轉 換 並 傳 回 長 整 數 值 。 轉 換 不 成 功 時 傳 回 0 值 。<br />

/************* convert.c **********/<br />

#include <br />

#include <br />

int main()<br />

{ int i;<br />

long li;<br />

double d;<br />

d = atof("123.45");<br />

printf("atof(\"123.45\")= %.2f\n", d);<br />

i = atoi("12345");<br />

printf("atoi(\"12345\")= %d\n", i);<br />

li = atol("123456789");<br />

printf("atol(\"123456789\")= %ld\n", li);<br />

return 0;<br />

}<br />

09 字 元 與 字 串<br />

09 字 元 與 字 串<br />

2


9.3 字 串 轉 換 函 式<br />

String conversion (2)<br />

double strtod ( const char * str, char ** endptr );<br />

Convert string to double<br />

long int strtol ( const char * str, char ** endptr, int base );<br />

Convert string to long integer<br />

unsigned long int strtoul ( const char * str, char ** endptr, int base );<br />

Convert string to unsigned long integer<br />

字 串 轉 換 函 式 定 義 於 公 用 函 式 庫 裡<br />

http://www.cplusplus.com/reference/clibrary/cstdlib/strtod.html<br />

http://www.cplusplus.com/reference/clibrary/cstdlib/strtol.html<br />

http://www.cplusplus.com/reference/clibrary/cstdlib/strtoul.html<br />

09 字 元 與 字 串<br />

/**************** todecimal.c **************/<br />

#include <br />

#include <br />

int main()<br />

{ double d;<br />

char *s = "12.3% ABC", *sPtr;<br />

long ld;<br />

char *sl = "-1234567abc", *slPtr;<br />

unsigned long u;<br />

char *su = "1234567abc", *suPtr;<br />

d = strtod(s, &sPtr);<br />

printf(" s=%-12s d=%.2f sPtr=%s\n", s, d, sPtr);<br />

ld = strtol(sl, &slPtr, 0);<br />

printf("sl=%-12s ld=%ld slPtr=%s\n", sl, ld, slPtr);<br />

u = strtoul(su, &suPtr, 0);<br />

printf("su=%-12s u=%ld suPtr=%s\n", su, u, suPtr);<br />

return 0;<br />

}<br />

09 字 元 與 字 串<br />

9.4 字 元 字 串 輸 入 及 輸 出<br />

標 準 輸 入 及 輸 出 函 式 庫 stdio.h<br />

int getchar()<br />

char *gets(char *buf)<br />

int putchar(int ch)<br />

int puts(const char *s)<br />

int sscanf(const char *s, const char *format [, addr...])<br />

int sprintf(char *s, const char *format [, argument ...])<br />

/************** getline.c **************/<br />

#include <br />

void reverse(char *s)<br />

{<br />

int i, n;<br />

for (n=0; s[n]!='\0'; n++) ;<br />

for (i=n-1; i>=0; i--) putchar(s[i]);<br />

}<br />

int main()<br />

{ char s[80];<br />

printf(" 輸 入 一 個 字 串 : ");<br />

gets(s);<br />

printf(" 反 轉 列 印 : ");<br />

reverse(s);<br />

return 0;<br />

}<br />

09 字 元 與 字 串<br />

09 字 元 與 字 串<br />

/************* keyinchar.c ************/<br />

#include <br />

int main()<br />

{<br />

char ch, s[80];<br />

int i = 0;<br />

printf(" 輸 入 一 個 字 串 : ");<br />

while ( (ch = getchar() )!='\n‘ ) s[i++]=ch;<br />

s[i] = '\0';<br />

puts(" 您 輸 入 的 字 串 為 : ");<br />

puts(s);<br />

return 0;<br />

}<br />

09 字 元 與 字 串<br />

/***************** editstr.c ******************/<br />

#include <br />

int main()<br />

{ char s[80], si[10], sf[80];<br />

int x;<br />

float y;<br />

printf(" 輸 入 一 個 整 數 x 及 一 個 浮 點 數 y: ");<br />

scanf("%d%f", &x, &y);<br />

sprintf(s, " 整 數 : %6d 浮 點 數 : %8.2f", x, y);<br />

printf(" 輸 出 至 字 串 s 為 :\n\"%s\"\n", s);<br />

sscanf(s, "%6s%6d%8s%8.2f", si,&x, sf,&y);<br />

printf(" 從 字 串 s 使 用 sscanf() 函 式 讀 入 :\n"<br />

"si=\"%s\" x=%d sf=\"%s\" y=%.2f\n",si,x,sf,y);<br />

return 0;<br />

}<br />

09 字 元 與 字 串<br />

3


String Functions 字 串 處 理 函 式 庫<br />

• strcat(s1, s2) - It concatenates two strings. It concatenates s2 at<br />

the end of s1.<br />

• strcmp (s1, s2) – It is used to compare strings. It returns 0 if they<br />

are equal and less than 0 if s1s2.<br />

• strlen(s1) – It returns the length of the string s1.<br />

• strcpy(s1, s2) - It copies s2 into s1.<br />

• strncat(s1, s2, n) - It appends substring to the string. It takes<br />

first n characters of string s2 and appends s1.<br />

• strncmp(s1,s2,n) – It compares first n characters of string s1<br />

with first n characters of string s2.<br />

• strchr(s1, ch) – Finds character ch in string s1. It returns the<br />

pointer at the first occurrence of ch.<br />

• strstr(s1, s2) – Finds substring s2 in s1. It returns a pointer at<br />

the first occurrence of s1.<br />

9.2 字 串 長 度 *<br />

size_t strlen(const char *s)<br />

傳 回 字 串 s 之 長 度 , 即 字 元 數 , 不 含<br />

字 串 結 束 符 號 ‘\0‘ 字 元 ( 即 NULL 常 數 )<br />

size_t 型 態 為 長 整 數 型 態 。<br />

Either header file or must be included in the<br />

program. http://cpp-tutorial.cpp4u.com/C_style_string_functions.html<br />

09 字 元 與 字 串<br />

09 字 元 與 字 串<br />

/*********** strlength.c **************/<br />

#include <br />

#include <br />

int main()<br />

{ char *s1 = "abcdefghijklmnopqrstuvwxyz";<br />

char *s2 = "China";<br />

char *s3 = "Taiwan";<br />

printf(" 字 串 s1 的 長 度 = %d\n", strlen(s1) );<br />

printf(" 字 串 s2 的 長 度 = %d\n", strlen(s2) );<br />

printf(" 字 串 s3 的 長 度 = %d\n", strlen(s3) );<br />

return 0;<br />

}<br />

9.5 字 串 操 作 函 式<br />

char *strcpy(char *destination, const char *source)<br />

char *strncpy(char *destination, const char *source, size_t n)<br />

由 source 字 串 最 多 拷 貝 n 個 字 元 至 destination。 若 source 之 長 度 超<br />

過 或 等 於 n, 則 destination 將 不 會 以 ‘\0’ 結 束 。 傳 回 destination。<br />

char *strcat(char *destination, const char *source)<br />

char *strncat(char *destination, const char *source, size_t n);<br />

09 字 元 與 字 串<br />

09 字 元 與 字 串<br />

/************** copystr.c **************/<br />

#include <br />

#include <br />

#include <br />

int main()<br />

{ char s[] = "Hi, Good Morning!";<br />

char s2[25], s3[15];<br />

printf(“0000012345678901234567890\n");<br />

printf("s =\"%s\"\ns2=\"%s\"\n", s, strcpy(s2,s) );<br />

strncpy(s3, s, 8);<br />

s3[8] = '\0';<br />

printf("s3=\"%s\"\n", s3);<br />

system("pause");<br />

return 0;<br />

}<br />

/* strncpy example */<br />

#include <br />

#include <br />

int main ()<br />

{ char str1[]= "To be or not to be";<br />

char str2[6];<br />

strncpy (str2,str1,5);<br />

str2[5]='\0';<br />

puts (str2);<br />

return 0;<br />

}<br />

09 字 元 與 字 串<br />

09 字 元 與 字 串<br />

4


***************** concat.c ****************/<br />

#include <br />

#include <br />

int main()<br />

{<br />

char s1[10] = "Hi, ";<br />

char s2[20] = "Good Morning.";<br />

char s3[40] = "";<br />

printf("s1=\"%s\" \ns2=\"%s\"\n", s1,s2);<br />

printf("strcat(s1,s2)=\"%s\"\n", strcat(s1,s2) );<br />

printf("strncat(s3,s1,3)=\"%s\"\n",strncat(s3,s1,3) );<br />

s3[3]='\0';<br />

strcpy(s2,"every body.");<br />

printf("strcat(s3,s2)=\"%s\"\n", strcat(s3,s2) );<br />

return 0;<br />

}<br />

09 字 元 與 字 串<br />

9.6 字 串 比 較 函 式<br />

int strcmp(const char *s1, const char *s2)<br />

• 若 s1s2 則 傳 回 正 數 。<br />

int strncmp(const char *s1, const char *s2, size_t n);<br />

• 最 多 比 較 n 個 字 元 。<br />

• 若 s1s2 則 傳 回 正 數 。<br />

09 字 元 與 字 串<br />

/****************** compstr.c *****************/<br />

#include <br />

#include <br />

int main()<br />

{<br />

char *s1 = "Good Morning";<br />

char *s2 = "Good Morning";<br />

char *s3 = "Good Night";<br />

printf("s1=\"%s\" s2=\"%s\" s3=\"%s\"\n", s1,s2,s3);<br />

printf("strcmp(s1,s2)= %d\n", strcmp(s1,s2) );<br />

printf("strcmp(s1,s3)= %d\n", strcmp(s1,s3) );<br />

printf("strcmp(s3,s1)= %d\n", strcmp(s3,s1) );<br />

printf("strncmp(s1,s3,5)= %d\n", strncmp(s1,s3,5) );<br />

printf("strncmp(s1,s3,6)= %d\n", strncmp(s1,s3,6) );<br />

printf("strncmp(s3,s1,7)= %d\n", strncmp(s3,s1,7) );<br />

return 0;<br />

}<br />

09 字 元 與 字 串<br />

9.7 字 串 搜 尋 函 式<br />

char *strchr(const char *s, int ch)<br />

從 s 字 串 中 由 前 向 後 搜 尋 第 一 個 出 現 ch 之 位 置 。<br />

失 敗 時 傳 回 NULL。<br />

char *strrchr(const char *s, int ch)<br />

從 s 字 串 中 由 後 向 前 搜 尋 第 一 個 出 現 ch 之 位 置 ( 亦 即 傳 回 s 中<br />

最 後 出 現 ch 字 元 之 指 標 ) , 失 敗 時 傳 回 NULL。<br />

char *strstr(const char *s1, const char *s2)<br />

傳 回 s1 中 第 一 次 出 現 s2 的 指 標 。<br />

09 字 元 與 字 串<br />

/***************** charSearch.c ***************/<br />

#include <br />

#include <br />

int main()<br />

{<br />

char *s="Happy birthday!!";<br />

char ch1='y', ch2='z';<br />

if ( strchr(s,ch1) !=NULL)<br />

printf("\'%c\' 在 右 列 字 串 中 找 到 \"%s\"\n", ch1,s);<br />

else<br />

printf("\'%c\' 在 右 列 字 串 中 找 不 到 \"%s\"\n", ch1,s);<br />

if ( strchr(s,ch2) !=NULL)<br />

printf("\'%c\' 在 右 列 字 串 中 找 到 \"%s\"\n", ch2,s);<br />

else<br />

printf("\'%c\' 在 右 列 字 串 中 找 不 到 \"%s\"\n", ch2,s);<br />

return 0;<br />

}<br />

09 字 元 與 字 串<br />

/************ lastChar.c ***************/<br />

#include <br />

#include <br />

int main()<br />

{<br />

char *s="Happy New Year!!";<br />

int ch='Y';<br />

printf(" 在 \"%s\" 中 最 後 出 現 \'%c\' 字 元 的 字 串 是 \n", s,ch);<br />

printf("\"%s\"\n", strrchr(s,ch) );<br />

return 0;<br />

}<br />

09 字 元 與 字 串<br />

5


************** strSearch.c **************/<br />

#include <br />

#include <br />

#include <br />

int main()<br />

{ char *s1="Good Afternoon!!";<br />

char *s2="noon";<br />

printf(“0000012345678901234567890\n");<br />

printf("s1=\"%s\" s2=\"%s\"\n", s1,s2);<br />

printf(" 字 串 s1 第 一 次 出 現 s2 的 其 餘 字 串 為 \n");<br />

printf("\"%s\"\n", strstr(s1,s2) );<br />

printf("\"%d\"\n", strstr(s1,s2)-s1 );<br />

system("pause");<br />

return 0;<br />

}<br />

/************** strtoken.c ***************/<br />

#include <br />

#include <br />

int main()<br />

{ char s[] = "This is a sentence with 7 tokens.";<br />

char *p;<br />

printf(" 要 被 剖 成 句 元 的 字 串 \n\"%s\"\n", s);<br />

printf(" 剖 成 句 元 如 下 :\n");<br />

p = strtok(s, " ");<br />

while (p!=NULL)<br />

{ printf("%s\n", p);<br />

p = strtok(NULL, " ");<br />

}<br />

return 0;<br />

}<br />

09 字 元 與 字 串<br />

09 字 元 與 字 串<br />

9.8 字 串 記 憶 體 函 式 *<br />

• 字 串 函 式 庫 string.h 提 供 許 多 有 關 字 串 記 憶 體 函 式 的 操 作 ,<br />

void *memchr(const void *region, int ch, size_t n)<br />

• 傳 回 region 字 串 前 n 個 字 元 第 一 個 與 ch 相 同 字 元 的 指 標 ,<br />

失 敗 時 傳 回 NULL 值 。<br />

int memcmp(const void *r1, const void *r2, size_t count)<br />

• 若 r1r2 則 傳 回 正 數 。r1 與 r2 以 無 符 號 字 元 逐 字 元 比 較 , 直<br />

到 比 完 count 個 字 元 或 分 出 大 小 為 止 。<br />

09 字 元 與 字 串<br />

void *memcpy(void *r1, const void *r2, size_t n)<br />

• 由 r2 字 串 拷 貝 前 n 個 字 元 至 r1。 傳 回 r1。<br />

void *memmove(void *r1, const void *r2, size_t count)<br />

• 由 r2 拷 貝 前 n 個 字 元 至 r1。 傳 回 r1。<br />

位 置 重 疊 也 可 以 。<br />

void *memset(void *buf, int ch, size_t n)<br />

• 將 buf 前 n 個 字 元 之 內 含 設 定 為 ch 值 。 傳 回 buf。<br />

09 字 元 與 字 串<br />

/***************** memcopy.c *****************/<br />

#include <br />

#include <br />

int main()<br />

{<br />

char s1[17], s2[]="Memory copy this string.";<br />

printf("s2=\"%s\"\n", s2);<br />

memcpy(s1, s2, 11);<br />

s1[11]='\0';<br />

printf(" 字 串 s2 使 用 memcpy() 函 式 拷 貝 11 個 字 元 至 s1\n");<br />

printf("s1=\"%s\"\n", s1);<br />

return 0;<br />

}<br />

09 字 元 與 字 串<br />

/*************** movemem.c ***************/<br />

#include <br />

#include <br />

int main()<br />

{<br />

char s[] = "Home Sweet Home";<br />

printf(" 呼 叫 memmove() 函 式 之 前 的 字 串 : \"%s\"\n", s);<br />

printf(" 呼 叫 memmove() 函 式 之 後 的 字 串 : \"%s\"\n",<br />

memmove(s, &s[5], 10) );<br />

return 0;<br />

}<br />

09 字 元 與 字 串<br />

6


******************* memcomp.c ******************/<br />

#include <br />

#include <br />

main()<br />

{<br />

char s1[] = "abcdefg", s2[] = "abcdEFG";<br />

printf("s1=%s s2=%s\n", s1,s2);<br />

printf(" 相 等 memcmp(s1,s2,4)=%d\n", memcmp(s1,s2,4) );<br />

printf("s1 大 memcmp(s1,s2,7)=%d\n", memcmp(s1,s2,7) );<br />

printf("s2 小 memcmp(s2,s1,7)=%d\n", memcmp(s2,s1,7) );<br />

return 0;<br />

}<br />

【 執 行 】<br />

memcomp.exe <br />

s1=abcdefg s2=abcdEFG<br />

相 等 memcmp(s1,s2,4)=0<br />

s1 大 memcmp(s1,s2,7)=1<br />

s2 小 memcmp(s2,s1,7)=-1<br />

9.9 字 串 錯 誤 訊 息<br />

• 函 式 strerror() 會 接 收 一 個 錯 誤 訊 息 號 碼 ,<br />

然 後 傳 回 相 對 應 的 錯 誤 訊 息 字 串 , 其 函 式<br />

宣 告 如 下 所 示 :<br />

#include <br />

char *strerror(int error);<br />

• 傳 回 對 應 錯 誤 訊 息 號 碼 error 之 錯 誤 訊 息 字<br />

串 指 標 。<br />

09 字 元 與 字 串<br />

09 字 元 與 字 串<br />

/************ errormap.c ************/<br />

#include <br />

#include <br />

#include <br />

#define SIZE 30<br />

int main()<br />

{ int i;<br />

for (i=0; i


10 格 式 化 輸 入 與 輸 出<br />

10.1 輸 出 至 螢 幕<br />

10.2 從 鍵 盤 輸 入<br />

10 格 式 化 輸 入 與 輸 出<br />

stdin, stdout, stderr<br />

• C 言 的 輸 入 與 輸 出 相 關 的 函 式 很 多 , 最 基 本 的 輸 入 函 式<br />

是 scanf(), 最 基 本 的 輸 出 函 式 是 printf() 函 式<br />

• 資 料 流 是 指 一 連 串 排 列 的 字 元 ,ANSI C 規 定 資 料 流 最<br />

少 必 須 包 含 254 個 字 元 , 包 括 結 束 的 換 列 字 元 ‘\n’。<br />

• 程 式 執 行 時 會 有 三 個 資 料 流 與 程 式 自 動 結 合 , 標 準 輸 入<br />

資 料 流 (stdin) 與 鍵 盤 結 合 , 標 準 輸 出 資 料 流<br />

(stdout) 與 螢 幕 結 合 , 標 準 錯 誤 資 料 流 (stderr) 與<br />

螢 幕 結 合 。<br />

10 格 式 化 輸 入 與 輸 出 10 格 式 化 輸 入 與 輸 出<br />

10.1 輸 出 至 螢 幕<br />

• printf() 函 式 可 輸 出 精 確 格 式 化 的 結 果<br />

• printf() 呼 叫 語 法<br />

printf(“ prompt message %s… %c… %d …”, variable1, variable2,variable3);<br />

格 式 控 制 字 串 (format control string)<br />

• 格 式 控 制 字 串 包 括 字 串 常 數 及 轉 換 格 式 。 例 如 :<br />

printf("OK!"); /* 字 串 常 數 OK!*/<br />

printf("%d", 123); /* 轉 換 格 式 %d*/<br />

printf(" 整 數 =%d\n", 123); /* 字 串 常 數 及 轉 換 格 式 */<br />

10 格 式 化 輸 入 與 輸 出<br />

printf() 函 式 格 式<br />

• 格 式 一 :<br />

printf( 格 式 控 制 字 串 );<br />

• 格 式 二 :<br />

printf( 格 式 控 制 字 串 , 引 數 列 );<br />

10 格 式 化 輸 入 與 輸 出<br />

1


格 式 控 制 字 串<br />

format control string<br />

% [flags] [width] [.precision] [modifiers] type<br />

• 轉 換 格 式 的 格 式 以 百 分 比 「%」 開 始 ,<br />

其 後 跟 著 選 用 的 「 旗 標 」(flags)、<br />

選 用 的 「 欄 寬 」(width)、<br />

選 用 的 「 精 確 度 」(precision)、<br />

選 用 的 「 修 飾 字 」(modifiers)、<br />

及 一 定 要 標 示 的 「 轉 換 型 態 」(type)<br />

10 格 式 化 輸 入 與 輸 出<br />

• 轉 換 格 式 如 下 ( 方 括 號 [ ] 表 示 選 用 ):<br />

% [flags] [width] [.precision] [modifiers] type<br />

• 最 簡 單 的 轉 換 格 式 就 是 「%」 後 跟 著 轉 換 型 態<br />

• 每 一 個 轉 換 格 式 必 須 對 應 一 個 引 數 (argument), 引<br />

數 與 引 數 之 間 以 逗 號 隔 開 。 例 如 :<br />

printf("%d %s", 123, "OK");<br />

引 數 123 對 應 轉 換 格 式 「%d」, 引 數 "OK" 對 應 轉 換<br />

格 式 「%s」。<br />

10 格 式 化 輸 入 與 輸 出<br />

10.1.1 printf() 轉 換 格 式<br />

10 格 式 化 輸 入 與 輸 出<br />

printf() 轉 換 格 式 for integer<br />

/************ intformats.c *************/<br />

#include <br />

int main()<br />

{<br />

printf("d 轉 換 型 態 %d\n", 365);<br />

printf("i 轉 換 型 態 %i\n", 365);<br />

printf("d 轉 換 型 態 %d\n", +365);<br />

printf("d 轉 換 型 態 %d\n", -365);<br />

printf("hd 轉 換 型 態 %hd\n", 32767);<br />

printf("ld 轉 換 型 態 %ld\n", 1234567890);<br />

printf("o 轉 換 型 態 %o\n", 365);<br />

printf("u 轉 換 型 態 %u\n", 365);<br />

printf("u 轉 換 型 態 %u\n", -365);<br />

printf("x 轉 換 型 態 %x\n", 365);<br />

printf("X 轉 換 型 態 %X\n", 365);<br />

return 0;<br />

}<br />

10 格 式 化 輸 入 與 輸 出<br />

printf() 轉 換 格 式<br />

for real number<br />

printf() 轉 換 格 式<br />

for string & character<br />

/********* floatformats.c **********/<br />

#include <br />

int main()<br />

{<br />

printf("e 轉 換 型 態 %e\n", 1234567.89);<br />

printf("e 轉 換 型 態 %e\n", 1234567.89);<br />

printf("e 轉 換 型 態 %e\n", -1234567.89);<br />

printf("E 轉 換 型 態 %E\n", 1234567.89);<br />

printf("f 轉 換 型 態 %f\n", 12.3456789);<br />

printf("g 轉 換 型 態 %g\n", 1234567.89);<br />

printf("G 轉 換 型 態 %G\n", 1234567.89);<br />

return 0;<br />

}<br />

/*********** charformat.c ***********/<br />

#include <br />

#include <br />

int main()<br />

{<br />

char ch = 'A';<br />

char *s = "Good Morning!";<br />

printf(" 這 是 一 個 'A' 字 元 : \'%c\'\n", ch);<br />

printf("%s", " 這 是 一 個 字 串 : ");<br />

printf("\"%s\"\n", s);<br />

return 0;<br />

}<br />

10 格 式 化 輸 入 與 輸 出<br />

10 格 式 化 輸 入 與 輸 出<br />

2


**************** ptrformat.c *************/<br />

#include <br />

int main()<br />

{<br />

int *iPtr;<br />

int m = 12345, n;<br />

iPtr = &m;<br />

printf(" 整 數 指 標 變 數 iPtr 的 內 含 值 = 0x%p\n", iPtr);<br />

printf(" 變 數 m 的 位 址 = 0x%p\n", &m);<br />

printf(" 本 列 所 印 出 來 的 字 元 數 =%n", &n);<br />

printf(" %d\n", n);<br />

n = printf("abcdef");<br />

printf(" 印 出 %d 個 字 元 \n", n);<br />

printf(" 在 格 式 控 制 字 串 中 列 印 百 分 比 符 號 %% \n");<br />

return 0;<br />

}<br />

printf() 轉 換 格 式 :width<br />

for real number or integer<br />

/*************** width.c ****************/<br />

#include <br />

int main()<br />

{<br />

printf(" 欄 寬 4, 轉 換 型 態 d=%4d\n", 1);<br />

printf(" 欄 寬 4, 轉 換 型 態 d=%4d\n", 12);<br />

printf(" 欄 寬 4, 轉 換 型 態 d=%4d\n", 123);<br />

printf(" 欄 寬 4, 轉 換 型 態 d=%4d\n", 1234);<br />

printf(" 欄 寬 4, 轉 換 型 態 d=%4d\n", 12345);<br />

printf(" 欄 寬 4, 轉 換 型 態 d=%4d\n", -12345);<br />

printf(" 欄 寬 4, 轉 換 型 態 d=%4d\n", -1234);<br />

printf(" 欄 寬 4, 轉 換 型 態 d=%4d\n", -123);<br />

printf(" 欄 寬 4, 轉 換 型 態 d=%4d\n", -12);<br />

printf(" 欄 寬 4, 轉 換 型 態 d=%4d\n", -1);<br />

return 0;<br />

}<br />

10 格 式 化 輸 入 與 輸 出<br />

10 格 式 化 輸 入 與 輸 出<br />

10.1.6 精 確 度 之 使 用<br />

• 精 確 度 與 整 數 轉 換 型 態 一 起 使 用<br />

– 表 示 最 少 必 須 印 出 指 定 的 位 數 , 如 果 印 出 來 的 位 數 小 於 指 定 的 精<br />

確 度 , 則 多 出 來 的 位 數 會 補 上 零 , 整 數 的 精 確 度 預 設 為 1。 例 如<br />

下 列 程 式 使 用 「%.4d」。<br />

• 精 確 度 與 轉 換 型 態 e、E 或 f 一 起 使 用<br />

– 表 示 小 數 點 後 必 須 印 出 指 定 的 位 數 。<br />

• 精 確 度 與 轉 換 型 態 g 或 G 一 起 使 用<br />

– 表 示 印 出 指 定 的 最 大 有 效 位 數 。<br />

• 精 確 度 與 轉 換 型 態 s 一 起 使 用<br />

– 表 示 最 多 印 出 指 定 的 字 元 。<br />

• 精 確 度 可 與 欄 寬 一 起 使 用<br />

– 例 如 printf("%10.2f",123.456) 印 出 欄 寬 十 位 其 中 兩 位 小 數 。<br />

10 格 式 化 輸 入 與 輸 出<br />

printf() 轉 換 格 式 :precision<br />

/*************** precission.c *****************/<br />

#include <br />

int main()<br />

{<br />

int i = 365;<br />

float f = 123.78567;<br />

char *s = "Hello";<br />

printf("%d 使 用 整 數 精 確 度 \n", i);<br />

printf(" 精 確 度 .4d \t%.4d\n 精 確 度 .9d \t%.9d\n", i, i);<br />

printf("%f 使 用 浮 點 數 精 確 度 \n", f);<br />

printf(" 精 確 度 .3f \t%.3f\n 精 確 度 .3e \t%.3e\n", f, f);<br />

printf(" 精 確 度 .3g \t%.3g\n", f);<br />

printf("\"%s\" 使 用 字 串 精 確 度 \n", s);<br />

printf(" 精 確 度 11s \t%.11s\n", s);<br />

return 0;<br />

}<br />

10 格 式 化 輸 入 與 輸 出<br />

【 程 式 flags.c】<br />

10.1.7 旗 標 之 使 用<br />

‧ printf() 函 式 也 提 供 旗 標 (flags) 以 補 功 能 的 不 足 ,<br />

旗 標 有 「-」、「+」、「 」、 及 「#」 等 四 種 , 其<br />

用 法 如 下 表 所 示 。<br />

10 格 式 化 輸 入 與 輸 出<br />

/******************** flags.c ******************/<br />

#include <br />

int main()<br />

{<br />

printf(" 1 2 3 4 \n");<br />

printf("123456789012345678901234567890123456789012\n");<br />

printf("------------------------------------------\n");<br />

printf("%10s%10d%10c%10f\n", "string", 456, 'C', 1.23);<br />

printf("%-10s%-10d%-10c%-10f\n","string",456,'C',1.23);<br />

return 0;<br />

} 【 執 行 】<br />

gcc flags.c -o flags.exe <br />

flags.exe <br />

1 2 3 4<br />

123456789012345678901234567890123456789012<br />

------------------------------------------<br />

string 456 C 1.230000<br />

string 456 C 1.230000<br />

10 格 式 化 輸 入 與 輸 出<br />

3


【 程 式 plusflag.c】<br />

/************** plusflag.c ***************/<br />

#include <br />

int main()<br />

{<br />

printf(" 沒 用 + 旗 標 d \t%d\t%d\n", 987, -987);<br />

printf(" 使 用 + 旗 標 +d \t%+d\t%+d\n", 987, -987);<br />

return 0;<br />

}<br />

【 執 行 】<br />

gcc plusflag.c -o plusflag.exe <br />

plusflag.exe <br />

沒 用 + 旗 標 d 987 -987<br />

使 用 + 旗 標 +d +987 -987<br />

10 格 式 化 輸 入 與 輸 出<br />

printf() 轉 換 格 式 :<br />

number system for integer<br />

【 程 式 alternate.c】 【 執 行 】<br />

alternate.exe <br />

/************* alternate.c **************/<br />

365 使 用 # 旗 標 #o 0555<br />

#include <br />

365 使 用 # 旗 標 #x 0x16d<br />

int main()<br />

365 使 用 # 旗 標 #X 0X16D<br />

{<br />

365.25 沒 用 # 旗 標 g 365.25<br />

int i = 365;<br />

365.25 使 用 # 旗 標 #g 365.250<br />

float f = 365.25;<br />

printf(" 365 使 用 # 旗 標 #o %#o\n", i);<br />

printf(" 365 使 用 # 旗 標 #x %#x\n", i);<br />

printf(" 365 使 用 # 旗 標 #X %#X\n", i);<br />

printf("365.25 沒 用 # 旗 標 g %g\n", f);<br />

printf("365.25 使 用 # 旗 標 #g %#g\n", f);<br />

return 0;<br />

}<br />

10 格 式 化 輸 入 與 輸 出<br />

printf() 轉 換 格 式 : leading zero<br />

【 程 式 zeroflag.c】<br />

/**************** zeroflag.c ***************/<br />

#include <br />

int main()<br />

{<br />

printf("123 使 用 0 旗 標 +09d\n%+09d\n", 123);<br />

printf("123 使 用 0 旗 標 09d\n%09d", 123);<br />

return 0;<br />

}<br />

10.1.8 變 動 的 欄 寬 與 精 確 度<br />

• 使 用 星 號 「*」 來 指 定 變 動 的 欄 寬 及 精 確 度 。<br />

• Program assignment during execution: 相 對 應 的 引 數 值 先 被<br />

計 算 出 來 , 然 後 取 代 相 對 應 的 星 號 。 若 計 算 出 來 的 欄 寬 值 是<br />

負 數 , 表 示 左 邊 對 齊 , 但 精 確 度 計 值 必 須 是 正 整 數 。 例 如 :<br />

printf("%*.*f", 12, 3, 123.456);<br />

【 執 行 】<br />

gcc zeroflag.c -o zeroflag.exe <br />

zeroflag.exe <br />

123 使 用 0 旗 標 +09d<br />

+00000123<br />

123 使 用 0 旗 標 09d<br />

000000123<br />

10 格 式 化 輸 入 與 輸 出<br />

• 表 示 欄 寬 12, 小 數 3 位 , 左 邊 對 齊 , 印 出 “123.456 ”。<br />

printf("%*.*f", 12, 3, -987.654);<br />

• 表 示 欄 寬 12, 小 數 3 位 , 右 邊 對 齊 , 印 出 " -987.654"。<br />

10 格 式 化 輸 入 與 輸 出<br />

/************** asterisk.c **************/<br />

#include <br />

int main()<br />

{<br />

int w, n=12345;<br />

float f=123.456;<br />

for (w=7; w


10.2.1 scanf 轉 換 格 式<br />

‧ 表 10.5 scanf 轉 換 型 態 與 引 數 資 料 型 態 表<br />

• scanf() 函 式 的 格 式 控 制 字 串<br />

% [*] [width] [modifiers] type<br />

• 星 號 「*」 表 示 要 取 消 下 一 輸 入 欄 之 轉 換 格 式 ,<br />

width( 欄 寬 ) 表 示 輸 入 最 大 之 字 元 數 ,<br />

modifiers( 修 飾 字 ) 包 含 「h」、「l」 及 「L」,<br />

h 表 引 數 的 資 料 型 態 為 「short int」,<br />

l 表 引 數 資 料 型 態 為 「long int」 或 double,<br />

L 表 引 數 的 資 料 型 態 為 「long double」。<br />

10 格 式 化 輸 入 與 輸 出<br />

10 格 式 化 輸 入 與 輸 出<br />

Read integer data<br />

/***************** intscan.c **************/<br />

#include <br />

int main()<br />

{<br />

int a, b, c, d, e, f, g;<br />

printf(" 請 以 %%d 格 式 輸 入 一 個 整 數 a: ");<br />

scanf("%d", &a);<br />

printf(" 請 以 %%o 格 式 輸 入 一 個 整 數 b: ");<br />

scanf("%o", &b);<br />

printf(" 請 以 %%x 格 式 輸 入 一 個 整 數 c: ");<br />

scanf("%x", &c);<br />

printf(" 請 以 %%u 格 式 輸 入 一 個 整 數 d: ");<br />

scanf("%u", &d);<br />

printf(" 您 所 輸 入 的 整 數 a,b,c,d:\n");<br />

printf("a=%d b=%d c=%d d=%d ", a, b, c, d);<br />

return 0;<br />

}<br />

10 格 式 化 輸 入 與 輸 出<br />

Read real data<br />

/************** floatscan.c *************/<br />

#include <br />

int main()<br />

{<br />

float a, b, c;<br />

printf(" 請 以 %%e 格 式 輸 入 一 個 浮 點 數 a: ");<br />

scanf("%e", &a);<br />

printf(" 請 以 %%f 格 式 輸 入 一 個 浮 點 數 b: ");<br />

scanf("%f", &b);<br />

printf(" 請 以 %%g 格 式 輸 入 一 個 浮 點 數 c: ");<br />

scanf("%g", &c);<br />

printf(" 您 所 輸 入 的 浮 點 數 a,b,c:\n");<br />

printf("a=%f b=%f c=%f\n", a, b, c);<br />

return 0;<br />

}<br />

10 格 式 化 輸 入 與 輸 出<br />

Read character or string<br />

/*********** charscan.c ***********/<br />

#include <br />

int main()<br />

{<br />

char ch, s[80];<br />

printf(" 以 %%c 格 式 輸 入 一 個 字 元 ch: ");<br />

scanf("%c", &ch);<br />

printf(" 以 %%s 格 式 輸 入 一 個 字 串 s: ");<br />

scanf("%s", s);<br />

printf(" 您 所 輸 入 的 字 元 =\'%c\'\n", ch);<br />

printf(" 您 所 輸 入 的 字 串 =\"%s\"\n", s);<br />

return 0;<br />

}<br />

10 格 式 化 輸 入 與 輸 出<br />

Read a special string (1)<br />

【 程 式 scanset.c】<br />

/************* scanset.c ************/<br />

#include <br />

int main()<br />

{<br />

char s[9];<br />

printf(" 請 依 %%[aeiou] 格 式 輸 入 一 個 字 串 s: ");<br />

scanf( "%[aeiou]", s);<br />

printf(" 您 所 輸 入 的 字 串 =\"%s\"\n", s);<br />

return 0;<br />

}<br />

【 執 行 】<br />

gcc scanset.c -o scanset.exe <br />

scanset.exe <br />

請 依 %[aeiou] 格 式 輸 入 一 個 字 串 s: aioh! <br />

的 字 串 ="aio"<br />

您 所 輸 入<br />

10 格 式 化 輸 入 與 輸 出<br />

5


Read a special string (2)<br />

【 程 式 iscanset.c】<br />

/****************** iscanset.c ****************/<br />

#include <br />

int main()<br />

{<br />

char s[9];<br />

printf(" 請 依 %%[^aeiou] 格 式 輸 入 一 個 字 串 s: ");<br />

scanf( "%[^aeiou]", s);<br />

printf(" 您 所 輸 入 的 字 串 =\"%s\"\n", s);<br />

return 0;<br />

}<br />

【 執 行 】<br />

gcc iscanset.c -o iscanset.exe <br />

iscanset.exe <br />

請 依 %[^aeiou] 格 式 輸 入 一 個 字 串 s: string <br />

您 所 輸 入 的 字 串 ="str"<br />

10 格 式 化 輸 入 與 輸 出<br />

Be careful in data entry (1)<br />

【 程 式 widthscan.c】<br />

/**************** widthscan.c ***************/<br />

#include <br />

int main()<br />

{<br />

int a, b;<br />

printf(" 請 輸 入 七 個 阿 拉 伯 數 字 : ");<br />

scanf("%3d%4d", &a, &b);<br />

printf(" 整 數 變 數 a=%d 整 數 變 數 b=%d\n", a,b);<br />

return 0;<br />

}<br />

【 執 行 】<br />

gcc widthscan.c -o widthscan.exe <br />

widthscan.exe <br />

請 輸 入 七 個 阿 拉 伯 數 字 : 1234567 <br />

整 數 變 數 a=123 整 數 變 數 b=4567<br />

10 格 式 化 輸 入 與 輸 出<br />

Be careful in data entry (2)<br />

/************* suppress.c *************/<br />

#include <br />

int main()<br />

{<br />

int mm1, dd1, yy1, mm2, dd2, yy2;<br />

printf(" 請 輸 入 以 mm-dd-yy 格 式 的 日 期 : ");<br />

scanf("%d%*c%d%*c%d", &mm1, &dd1, &yy1);<br />

printf(" 月 =%d 日 =%d 年 =%d\n", mm1, dd1, yy1);<br />

printf(" 請 輸 入 以 mm/dd/yy 格 式 的 日 期 : ");<br />

scanf("%d%*c%d%*c%d", &mm2, &dd2, &yy2);<br />

printf(" 月 =%d 日 =%d 年 =%d\n", mm2, dd2, yy2);<br />

return 0;<br />

}<br />

suppress.exe <br />

請 輸 入 以 mm-dd-yy 格 式 的 日 期 : 1-26-2007 <br />

月 =1 日 =26 年 =2007<br />

請 輸 入 以 mm/dd/yy 格 式 的 日 期 : 1/26/2007 <br />

月 =1 日 =26 年 =2007<br />

10 格 式 化 輸 入 與 輸 出<br />

6


www.caneis.com.tw<br />

11 結 構<br />

11.1 結 構 定 義<br />

11.2 顯 示 結 構 成 員<br />

11.3 從 鍵 盤 輸 入 至 結 構 成 員<br />

11.4 結 構 變 數 輸 出 至 檔 案<br />

11.5 串 列 list<br />

11.6 同 位 union<br />

11.7 位 元 欄 位<br />

11.8 列 舉 型 態 enum<br />

11.9 型 態 定 義 typedef<br />

結 構<br />

• 結 構 在 高 階 的 物 件 導 向 的 程 式 中 , 是 一 個 極 其 重<br />

要 的 工 具 。<br />

• 傳 統 的 資 料 型 態 僅 適 用 於 個 別 的 單 純 資 料 。<br />

• 傳 統 的 資 料 型 態 結 合 陣 列 只 是 將 相 同 型 態 的 資 料<br />

結 合 起 來 。<br />

• 結 構 (struct) 可 將 不 同 資 料 型 態 及 相 同 型 態 的<br />

資 料 結 合 起 來 。<br />

• 結 構 可 以 用 來 定 義 儲 存 在 檔 案 裡 的 記 錄 , 建 構 資<br />

料 庫 系 統 ; 結 構 配 合 指 標 可 建 立 複 雜 的 資 料 結<br />

構 , 如 連 結 串 列 、 佇 列 、 堆 疊 、 及 樹 結 構 等 。<br />

11 結 構<br />

11.1 結 構 定 義<br />

• 結 構 是 一 種 衍 生 的 資 料 型 態 , 以 關 鍵 字 struct 開<br />

始 , 接 著 為 結 構 的 標 記 ( 也 就 是 結 構 的 名 稱 ), 其<br />

後 以 大 括 號 括 起 來 的 是 結 構 的 成 員 , 每 一 個 成 員<br />

皆 為 指 定 型 態 的 變 數 。<br />

結 構 的 標 記<br />

struct person<br />

結 構 的 成 員 1<br />

{ char name[12];<br />

int age; 結 構 的 成 員 2<br />

};<br />

struct 結 構 體<br />

圖 10-1 一 筆 資 料<br />

可 能 需 要 使 用 多 種<br />

資 料 型 態<br />

• 宣 告 以 person 結 構 體 為 組 成 的 結 構 變 數 man1, man2<br />

struct person man1, man2;<br />

11 結 構<br />

陳 錦 輝 ,C/C++ 初 學 指 引 , 金 禾 書 局 11 (R501)。 結 構<br />

struct 結 構 體 : 定 義<br />

struct student<br />

{<br />

char stu_id[12];<br />

// 學 號<br />

int<br />

ScoreComputer; // 計 概<br />

int ScoreMath;<br />

// 數 學<br />

int ScoreEng;<br />

// 英 文<br />

float ScoreAvg;<br />

// 平 均 成 績<br />

};<br />

struct 結 構 體<br />

延 續 前 面 的 結 構 體 student<br />

struct student John;<br />

struct student IM[50];<br />

圖 10-4<br />

結 構 體 在 記 憶 體 的 示 意 圖<br />

圖 10-3 結 構 體 示 意 圖<br />

圖 10-5 結 構 體 變 數 與 陣 列 在 記 憶 體 中 的 狀 況<br />

陳 錦 輝 ,C/C++ 初 學 指 引 , 金 禾 書 局 11 (R501)。 結 構<br />

陳 錦 輝 ,C/C++ 初 學 指 引 , 金 禾 書 局 11 (R501)。 結 構<br />

1


宣 告 結 構 變 數 同 時 賦 予 初 值<br />

• 宣 告 結 構 變 數 的 同 時 也 可 以 賦 予 初 值 的 , 例 如 :<br />

struct person man = { “KayLin", 6 };<br />

• 以 句 點 (.) 稱 呼 結 構 中 的 成 員 , 其 格 式 如 下 :<br />

結 構 變 數 名 稱 . 成 員 變 數 名 稱<br />

• 此 時 , 結 構 變 數 名 稱 為 man 的 成 員 變 數 name 及 age<br />

的 內 容 分 別 為<br />

man.name = "KayLin";<br />

man.age = 6;<br />

11 結 構<br />

透 過 結 構 指 標 變 數 取 得 成 員 變 數<br />

• 透 過 結 構 指 標 變 數 以 取 得 成 員 變 數 , 其<br />

格 式 如 下 :<br />

結 構 指 標 變 數 -> 成 員 變 數 名 稱<br />

• 如 下 例 :<br />

struct person *p = &man;<br />

• 相 當 於<br />

p->name = "KayLin";<br />

p->age = 6;<br />

11 結 構<br />

/************** person.c *************/<br />

#include 結 構 體 範 例<br />

struct person<br />

{<br />

char name[12];<br />

int age;<br />

};<br />

int main()<br />

{<br />

struct person man = {"KayLin", 6};<br />

struct person *p;<br />

printf("person 結 構 變 數 man 表 示 法 \n");<br />

printf(" man.name=\"%s\" ", man.name);<br />

printf(" man.age=%d\n", man.age);<br />

p = &man;<br />

printf("person 結 構 指 標 *p 表 示 法 \n");<br />

printf(" p->name=\"%s\" ", p->name);<br />

printf(" p->age=%d\n", p->age);<br />

return 0;<br />

}<br />

11 結 構<br />

person 結 構 成 員<br />

• person 結 構 , 包 含 兩 個 成 員 ,<br />

– 第 一 個 為 字 元 陣 列 name, 含 12 個 字 元 ,<br />

– 第 二 個 成 員 為 整 數 變 數 age。<br />

• 宣 告 一 個 person 結 構 型 態 的 變 數 man, 它 的 成 員<br />

初 值 以 大 括 號 表 示 ,name 成 員 的 初 值 為 “Kay”,<br />

age 成 員 的 初 值 為 6。age 佔 四 個 位 元 組 , 加 上<br />

name 佔 十 二 個 位 元 組 , 所 以 man 變 數 在 記 憶 體 裡<br />

佔 十 六 個 位 元 組 。<br />

11 結 構<br />

person 結 構 成 員 ( 續 )<br />

• 程 式 中 宣 告 一 個 person 結 構 的 指 標 變 數 p。<br />

使 用 變 數 man 中 成 員 的 表 示 法 , 即<br />

man.name 及 man.age, 並 將 它 們 的 值 顯 示<br />

出 來 。 將 person 結 構 指 標 變 數 p 的 內 含 值 設<br />

定 為 man 的 位 址 , 如 下 圖 所 示 。<br />

11 結 構<br />

11.3 從 鍵 盤 輸 入 至 結 構 成 員<br />

/*************** keyinperson.c ************/<br />

#include <br />

struct person<br />

{<br />

How about if data type<br />

char name[12]; struct is applied upon a<br />

int age;<br />

group data like array<br />

};<br />

int main()<br />

{<br />

struct person man, *p;<br />

printf(" 請 輸 入 姓 名 : ");<br />

scanf("%s", man.name);<br />

printf(" 請 輸 入 年 齡 : ");<br />

scanf("%d", &man.age);<br />

p = &man;<br />

printf("person 結 構 指 標 *p 表 示 法 \n");<br />

printf(" 輸 入 姓 名 =\"%s\" ", p->name);<br />

printf(" 輸 入 年 齡 =%d\n", p->age);<br />

return 0;<br />

}<br />

11 結 構<br />

2


11.4 結 構 變 數 輸 出 至 檔 案 (1)<br />

// file name: outperson.c<br />

struct person<br />

{<br />

char name[12];<br />

int age;<br />

};<br />

int main()<br />

{<br />

char buf[256];<br />

struct person man, *p;<br />

FILE *f = fopen("person.dat", "w");<br />

printf(" 請 逐 筆 輸 入 姓 名 、 年 齡 ( 直 接 按 Ctrl-Z 結 束 ):\n");<br />

while (gets(buf)!=NULL)<br />

{<br />

memset(man.name, '\0', sizeof(man.name));<br />

sscanf(buf, "%s %d", &man.name, &man.age);<br />

fseek(f, 0L, SEEK_END);<br />

fwrite(&man, sizeof(man), 1, f);<br />

}<br />

fclose(f);<br />

return 0;<br />

}<br />

11 結 構<br />

11.4 結 構 變 數 輸 出 至 檔 案 (2)<br />

• 程 式 outperson.c 將 從 鍵 盤 輸 入 的 man 值<br />

輸 出 至 檔 案 person.dat。 宣 告 一 個 FILE 檔<br />

案 指 標 f, 呼 叫 fopen() 函 式 開 啟 一 個<br />

person.dat 輸 出 檔 , 開 啟 失 敗 時 傳 回<br />

NULL 值 , 開 啟 成 功 時 傳 回 一 個 該 檔 案 的<br />

指 標 f。<br />

• 將 man 結 構 變 數 中 的 name 成 員 值 清 除 為<br />

'\0', 這 一 列 不 執 行 其 實 沒 有 關 係 的 , 執<br />

行 的 話 資 料 中 字 串 剩 餘 的 空 間 就 不 會 有<br />

其 他 的 雜 值 。<br />

11 結 構<br />

結 構 變 數 輸 出 至 檔 案 (3)<br />

• 使 用 gets(buf) 重 複 輸 入 姓 名 及 年 齡 至 記 憶 體<br />

緩 衝 器 buf, 直 到 您 直 接 按 Enter 鍵 才 停 止 輸<br />

入 。 這 時 buf 字 串 的 長 度 為 零 。<br />

• 找 到 檔 案 尾 端 , 將 輸 入 後 的 man 結 構 變 數 值 輸<br />

出 至 person.dat 檔 案 的 尾 端 , 姓 名 若 輸 入 “-1”<br />

則 結 束 輸 入 , 接 著 將 person.dat 檔 案 關 閉 而 結<br />

束 程 式 的 執 行 。<br />

• 本 例 題 重 點 在 介 紹 結 構 之 應 用 , 將 整 個 結 構 變<br />

數 ( 記 錄 ) 輸 出 至 檔 案 。<br />

11 結 構<br />

11.5 串 列 (list)<br />

• 結 構 裡 的 成 員 若 是 屬 於 結 構 的 指 標 , 這 種 指 標<br />

指 向 另 一 個 結 構 , 可 構 成 一 個 連 結 串 列<br />

• 連 結 串 列 中 的 每 一 個 節 點 都 是 同 一 種 結 構 。<br />

stack 結 構<br />

number<br />

link<br />

• stack 結 構 中 第 一 個 為 整 數 成 員 變 數 number,<br />

第 二 個 為 結 構 stack 的 指 標 變 數 link。 成 員 link<br />

的 內 含 值 可 為 NULL 表 示 沒 有 連 結 至 其 他 的 結<br />

構 , 若 不 為 NULL 則 表 示 連 結 至 其 他 的 結 構 。<br />

11 結 構<br />

結 構 連 結 串 列 ( 續 )<br />

struct stack<br />

{ int number;<br />

struct stack *link;<br />

} node, *p, *top;<br />

• node 為 stack 結 構 的 變 數 ,node.number 參<br />

考 到 number 成 員 ,node.link 參 考 到 link 成<br />

員 。p 及 top 均 為 stack 結 構 的 指 標 變 數 , 這<br />

三 個 變 數 node、p 及 top 均 沒 給 予 初 值 。<br />

/************* stack.c *************/<br />

#include <br />

#include <br />

struct stack<br />

{ int number;<br />

struct stack *link;<br />

} node, *p, *top;<br />

int main()<br />

{ int i;<br />

top = malloc(sizeof(node));<br />

top->link = NULL;<br />

for (i=0; inumber);<br />

p->link = top->link;<br />

top->link = p;<br />

}<br />

p = top->link;<br />

while (p != NULL)<br />

{ printf("%d ", p->number);<br />

p = p->link;<br />

}<br />

return 0;<br />

}<br />

11 結 構<br />

11 結 構<br />

3


• 程 式 stack.c 呼 叫 malloc() 函 數 取 得 一 塊 node 大<br />

小 的 記 憶 體 , 其 位 址 存 入 stack 結 構 的 指 標 變 數<br />

top 中 , 設 定 top 所 指 結 構 的 成 員 link 的 內 含 值 為<br />

NULL, 表 示 top 節 點 (node) 沒 有 連 結 至 其 他<br />

的 節 點 。<br />

• 呼 叫 malloc() 函 數 取 得 一 塊 node 大 小 的 記 憶<br />

體 , 其 位 址 存 入 stack 結 構 的 指 標 變 數 p 中 , 輸 入<br />

一 個 整 數 111 至 p 所 指 結 構 的 成 員 number, 設 定<br />

p 所 指 結 構 的 成 員 link 的 內 含 值 為 top 所 指 結 構 成<br />

員 link 的 內 含 值 , 將 top 指 標 移 到 p 所 指 的 節 點 。<br />

指 標 變 數 p<br />

指 標 變 數 p<br />

11 結 構<br />

11 結 構<br />

• 輸 入 222 至 p 所 指 結 構 的 成 員 number, 插 入 p 節 點<br />

至 top 節 點 的 後 面 , 如 下 圖 所 示 。<br />

• 輸 入 333 至 p 所 指 結 構 的 成 員 number, 插 入 p 節 點<br />

至 top 節 點 的 後 面 , 如 下 圖 所 示 。<br />

11.6 同 位 union<br />

• 同 位 (union) 也 是 種 衍 生 的 資 料 型 態<br />

• 同 位 的 成 員 佔 相 同 的 記 憶 體 空 間<br />

– 程 式 中 有 些 變 數 互 相 之 間 沒 有 關 聯 , 有 排 他 性 , 因 此<br />

讓 它 們 共 用 記 憶 體 空 間 , 為 了 節 省 記 憶 體 ,<br />

• 當 記 憶 體 已 經 很 便 宜 , 記 憶 體 擴 充 很 方 便 , 節<br />

省 記 憶 體 已 經 不 是 那 麼 重 要 ,<br />

• 不 過 在 單 晶 片 程 式 設 計 , 仍 然 有 需 求 , 我 們 還<br />

是 要 了 解 同 位 的 原 理 , 不 然 別 人 設 計 的 程 式 您<br />

可 能 就 看 不 懂 了 。<br />

11 結 構<br />

11 結 構<br />

11.6.4 union 宣 告<br />

union uTag<br />

{ int i;<br />

float f;<br />

} u;<br />

宣 告 一 個 同 位 變 數 u 。 成 員 u. i( 整 數 變 數 ) 及<br />

成 員 u. F ( 浮 點 數 變 數 ) 佔 共 同 的 記 憶 體 空 間 。<br />

int<br />

float<br />

int main()<br />

{<br />

union uTag u;<br />

u.i = 365;<br />

printf(" 將 整 數 365 存 入 union uTag 型 態 同 位 變 數 u 中 \n");<br />

printf(" 整 數 u.i 的 值 =%d 浮 點 數 u.f 的 值 =%f\n", u.i, u.f);<br />

u.f = 365.0;<br />

printf(" 將 365.0 存 入 union uTag 型 態 同 位 變 數 u 中 \n");<br />

printf(" 整 數 u.i 的 值 =%d 浮 點 數 u.f 的 值 =%f\n", u.i, u.f);<br />

return 0;<br />

}<br />

31 30 23 22 0<br />

± 數 值<br />

± 指 數<br />

尾 數<br />

11 結 構<br />

63 62 52 51 0<br />

double<br />

指 數<br />

± 尾 數<br />

11 結 構<br />

4


【 執 行 】<br />

uniontest.exe <br />

將 整 數 365 存 入 union uTag 型 態 同 位 變 數 u 中<br />

整 數 u.i 的 值 =365 浮 點 數 u.f 的 =0.000000<br />

將 365.0 存 入 union uTag 型 態 同 位 變 數 u 中<br />

整 數 u.i 的 值 =1136033792 浮 點 數 u.f 的 值 =365.000000<br />

將 u.f 設 定 為 365.0, 整 數 變 數 i 佔 共 同 的 記 憶 體 空<br />

間 , 因 此 將 下 列 資 料 :<br />

43 B6 80 00<br />

以 整 數 的 儲 存 格 式 加 於 解 釋 , 您 將 它 以 「%d」 格 式<br />

列 印 , 結 果 就 是 1136033792。<br />

11 結 構<br />

11.7 位 元 欄 位 bit field<br />

• ANSI C 語 言 提 供 位 元 欄 位 (bit field) 的<br />

功 能 , 這 種 功 能 讓 您 可 以 在 結 構 struct 及<br />

同 位 union 的 unsigned int 或 int 型 態 成 員 指<br />

定 位 元 個 數 。<br />

• 位 元 欄 位 (bit field) 的 功 能 除 了 節 省 記 憶<br />

體 之 外 , 也 提 高 了 執 行 效 率 , 位 元 欄 位 的<br />

成 員 必 須 宣 告 為 int 或 unsigned。<br />

11 結 構<br />

/****************** bitfield.c *******************/<br />

#include <br />

struct cardtag<br />

{ unsigned suit : 2;<br />

unsigned point : 4;<br />

};<br />

•Suit( 牌 組 ) 有 四 種 :<br />

黑 桃 (0)、 紅 心 (1)、 方 塊<br />

(2)、 梅 花 (3) : 占 2 位 元 。<br />

•Point( 牌 點 ) 共 有 13 種 牌 點 :<br />

占 4 個 位 元 。<br />

當 牌 組 為 3,<br />

牌 點 為 12,<br />

結 果 列 印 " 梅 花 K"。<br />

int main()<br />

{ char suitnames[][5]={" 黑 桃 ", " 紅 心 ", " 方 塊 ", " 梅 花 "};<br />

char pointnames[][3]={"A", "2", "3", "4", "5", "6", "7",<br />

"8", "9", "10", "J", "Q", "K"};<br />

struct cardtag card;<br />

int s, p;<br />

printf(" 請 輸 入 牌 組 (0-3): ");<br />

scanf("%d", &s);<br />

card.suit = s;;<br />

}<br />

printf(" 請 輸 入 牌 點 (0-12): ");<br />

scanf("%u", &p);<br />

card.point = p;<br />

printf("%s%s\n", suitnames[card.suit],<br />

pointnames[card.point]);<br />

return 0;<br />

11 結 構<br />

11.8 列 舉 型 態 enum<br />

• enum 列 舉 型 態 是 ANSI C 提 供 給 使 用 者 自<br />

定 資 料 內 容 ( 識 別 標 籤 ;tag) 的 合 法 使 用 集 合<br />

enum etag { North, East, South, West} e1, e2;<br />

North, East, South, West 值 分 別 為 0 至 3, 而 變 數 e1,<br />

e2 e 的 值 只 能 為 0, 1, 2, 3, 中 的 一 個 。<br />

enum { North=3, East, South=7, West } e;<br />

North、East、South、West 的 值 分 別 為 3,4,7,8, 而<br />

變 數 e 的 值 只 能 為 3,4,7,8 中 的 一 個 。<br />

11 結 構<br />

【 程 式 enumtest.c】<br />

/************** enumtest.c *****************/<br />

#include <br />

enum etag { North, East, South, West } e2;<br />

int main()<br />

{<br />

char enames[][3] = { " 北 ", " 東 ", " 南 ", " 西 " };<br />

for (e2=North; e2


11.9 型 態 定 義 typedef<br />

#include <br />

#include <br />

typedef int INTEGER ;<br />

typedef float AVERAGE ;<br />

int main()<br />

{ INTEGER count,total=0;<br />

AVERAGE number;<br />

for (total=count=0; count


12 檔 案 處 理<br />

12.1 循 序 檔 之 結 構<br />

12.2 開 啟 循 序 檔<br />

12.3 關 閉 循 序 檔<br />

12.4 feof() 函 式<br />

12.5 資 料 輸 出 至 循 序 檔<br />

12.6 資 料 附 加 至 循 序 檔<br />

12.7 資 料 由 循 序 檔 讀 取<br />

12.8 二 進 位 檔<br />

12.9 隨 機 檔<br />

http://en.wikipedia.org/wiki/Image:Hard_disk_platter_reflection.jpg<br />

• 儲 存 在 電 腦 記 憶 體 中 的 變 數 或 陣 列 裡 的 資<br />

料 是 暫 時 的 , 當 程 式 執 行 完 成 或 電 腦 關 機<br />

後 , 這 些 資 料 就 消 失 無 蹤 了 。<br />

• 檔 存 於 磁 片 、 磁 碟 、 光 碟 、 隨 身 碟 的 檔 案<br />

可 用 來 永 久 保 存 資 料 。<br />

• 在 ANSI C 語 言 中 , 檔 案 區 分 成<br />

– (A) 循 序 檔 或 隨 機 存 取 檔<br />

– (B) 本 文 檔 或 二 進 位 檔<br />

12 檔 案 處 理<br />

12.1 循 序 檔 之 結 構<br />

• ANSI C 將 每 個 檔 案 看 成 一 個 由 位 元 組 所 組 成 的 循 序<br />

資 料 流 。 每 一 個 檔 案 均 以 一 個 檔 案 結 束 符 號 結 尾 ,<br />

這 個 符 號 簡 稱 為 EOF。<br />

• 不 同 的 作 業 系 統 有 不 同 的 EOF 符 號 , 如 下 表 所 示 。<br />

表 12.1 作 業 系 統 與 EOF 符 號 表<br />

資 料 流 (stream)<br />

• 當 一 個 檔 案 開 啟 後 , 便 有 一 個 資 料 流 與 此 檔 案 結 合 在 一 起 。<br />

• 開 啟 一 個 檔 案 會 傳 回 一 個 指 向 FILE 結 構 的 指 標 , 這 個 FILE 結<br />

構 定 義 於 表 頭 檔 stdio.h 裡 ,FILE 結 構 其 成 員 依 C 語 言 編 譯 器<br />

的 不 同 而 異 。<br />

• 當 程 式 開 始 執 行 時 , 便 有 三 個 檔 案 及 其 相 結 合 的 資 料 流 會 自<br />

動 的 被 開 啟 , 這 三 個 分 別 是 標 準 輸 入 資 料 流 (stdin)、 標 準<br />

輸 出 資 料 流 (stdout) 及 標 準 錯 誤 資 料 流 (stderr)。<br />

• 資 料 流 提 供 檔 案 與 程 式 間 的 通 訊 管 道 。 例 如 標 準 輸 入 資 料 流<br />

讓 程 式 能 從 鍵 盤 讀 取 資 料 , 標 準 輸 出 資 料 流 及 標 準 錯 誤 資 料<br />

流 能 將 資 料 顯 示 在 螢 幕 上 。<br />

12 檔 案 處 理<br />

12 檔 案 處 理<br />

【 程 式 file2.c】<br />

/***************** filetest.c ******************/<br />

#include <br />

#include <br />

int main()<br />

{<br />

char buf[80], ptr[80];<br />

FILE *f=fopen("kay.txt", "r");<br />

fgets(buf,sizeof(buf),f);<br />

printf(" 讀 入 kay.txt 檔 案 第 一 筆 資 料 :\n%s",buf);<br />

strncpy(ptr,f->_ptr,4);<br />

ptr[4]='\0';<br />

printf(" 檔 案 指 標 指 到 下 一 筆 資 料 _ptr=\"%s\"\n", ptr);<br />

printf(" 所 使 用 緩 衝 器 大 小 為 _bufsiz=%d\n", f->_bufsiz);<br />

fclose(f);<br />

return 0;<br />

}<br />

12 檔 案 處 理<br />

【 檔 案 kay.txt】<br />

1001 FayChen 10000<br />

1002 T.C.Wang 20000<br />

1003 KayLin 3000<br />

【 執 行 】<br />

gcc filetest.c -o filetest.exe <br />

filetest.exe <br />

讀 入 kay.txt 檔 案 第 一 筆 資 料 :<br />

1001 Jemmy 10000<br />

檔 案 指 標 指 到 下 一 筆 資 料 _ptr="1002"<br />

所 使 用 緩 衝 器 大 小 為 _bufsiz=4096<br />

12 檔 案 處 理<br />

1


12.2 開 啟 循 序 檔<br />

• 表 12.2 開 啟 檔 案 模 式 mode<br />

1. fopen("fileWrt.dat", "w");<br />

開 啟 一 循 序 檔 fileWrt.dat 供 輸 出 之 用 , 若 該 檔 不 存 在 , 則 產 生 一 個<br />

新 的 資 料 檔 , 並 將 檔 案 指 標 移 至 新 資 料 檔 fileWrt.dat 的 起 始 位 置 。<br />

若 該 檔 為 既 有 的 檔 案 , 則 將 檔 案 指 標 移 至 原 檔 案 的 起 始 位 置 , 並<br />

將 原 檔 案 的 內 容 拋 棄 , 使 用 時 要 特 別 注 意 。<br />

• 模 式 mode 之 後 附 加 "t" 表 示 本 文 檔 ,<br />

附 加 "b" 表 示 二 進 位 檔 。<br />

12 檔 案 處 理<br />

2. fopen("fileApndx.dat", "a");<br />

開 啟 一 循 序 檔 fileApndx.dat 供 附 加 之 用 , 若 該 檔 不 存 在 , 則 產 生 一 個<br />

新 的 資 料 檔 , 並 將 檔 案 指 標 移 至 新 資 料 檔 fileApndx.dat 的 起 始 位 置 。<br />

若 該 檔 為 既 有 的 檔 案 , 則 將 檔 案 指 標 移 至 原 檔 案 之 結 束 位 置 ( 最 後<br />

一 筆 資 料 的 後 面 ), 以 備 新 資 料 逐 筆 附 加 。 注 意 , 原 檔 案 資 料 仍<br />

然 保 留 著 , 只 是 新 增 資 料 附 加 其 後 而 已 。<br />

3. fopen("fileRD.dat", "r");<br />

開 啟 一 循 序 檔 fileRD.dat 供 輸 入 之 用 , 若 該 檔 不 存 在 , 則 執 行 時 會<br />

產 生 錯 誤 。 若 該 檔 存 在 , 則 檔 案 指 標 移 至 fileRD.dat 的 起 始 位 置 。<br />

12 檔 案 處 理<br />

12.3 關 閉 循 序 檔<br />

fclose() 函 式 可 用 來 關 閉 循 序 檔<br />

fclose() 定 義 在 stdio.h 表 頭 檔 中<br />

fclose() 語 法 如 下 :<br />

int fclose(FILE *stream);<br />

關 閉 stream 所 指 之 檔 案 。<br />

成 功 時 傳 回 0 值 , 失 敗 時 傳 回 EOF 值 。<br />

12.4 feof() 函 式<br />

feof() 函 式 用 來 檢 查 檔 案 是 否 已 經 結 束 。<br />

feof() 函 式 定 義 在 stdio.h 表 頭 檔 中<br />

feof() 語 法 如 下 :<br />

int feof(FILE *stream);<br />

檢 查 stream 所 指 檔 案 是 否 已 到 檔 尾 。<br />

是 檔 尾 則 傳 回 非 0, 否 則 傳 回 0 值 。<br />

12 檔 案 處 理<br />

12 檔 案 處 理<br />

12.5 資 料 輸 出 至 循 序 檔 (new)<br />

資 料 輸 出 至 循 序 檔 的 四 個 基 本 過 程 :<br />

1. 宣 告 一 個 FILE 結 構 的 指 標 變 數<br />

FILE *fPtr;<br />

2. 以 fopen() 函 式 開 啟 指 定 的 檔 案 , 如 outfile.txt 為 輸 出 。<br />

fPtr=fopen("outfile.txt", "w“ );<br />

3. 以 fprintf() 函 式 將 資 料 輸 出 至 指 定 之 檔 案 。<br />

fprintf(fPtr, 格 式 字 串 , 資 料 );<br />

4. 以 fclose() 關 閉 指 定 之 檔 案 , 如 下 :<br />

fclose(fPtr);<br />

12 檔 案 處 理<br />

/**************** account.c ****************/<br />

#include <br />

int main()<br />

{<br />

char line[80];<br />

int account;<br />

char name[12];<br />

float amount;<br />

FILE *f = fopen("account.txt", "w");<br />

printf(" 請 輸 入 帳 號 、 姓 名 、 存 款 \n");<br />

while (1)<br />

{<br />

if(gets(line)==NULL) break;<br />

sscanf(line,"%d %s %f", &account, &name, &amount);<br />

fprintf(f, "%d %s %.2f\n", account, name, amount);<br />

}<br />

fclose(f);<br />

return 0;<br />

}<br />

12 檔 案 處 理<br />

2


***************** fixout.c ****************/<br />

#include <br />

#include <br />

int main()<br />

{<br />

char rec[25];<br />

FILE *f = fopen("fixout.txt", "w");<br />

printf(" 請 輸 入 定 長 整 筆 記 錄 ,Ctrl+Z 結 束 :\n");<br />

printf("123456789012345678901234\n");<br />

while (1)<br />

{<br />

if ( gets(rec)==NULL ) break;<br />

fprintf(f, "%s\n", rec);<br />

}<br />

fclose(f);<br />

return 0;<br />

}<br />

12 檔 案 處 理<br />

12.6 資 料 附 加 至 循 序 檔<br />

資 料 附 加 至 循 序 檔 的 四 個 基 本 過 程 :<br />

1. 宣 告 一 個 FILE 結 構 的 指 標 變 數 , 如 下 :<br />

FILE *fPtr;<br />

2. 以 fopen() 函 式 開 啟 檔 案 為 附 加 , 如 下 :<br />

fPr=fopen("account3.dat", "a“ );<br />

3. 以 fprintf() 函 式 將 資 料 輸 出 至 指 定 之 檔 案 , 如 下 :<br />

fprintf(fPtr, "%s\n", rec);<br />

4. 以 fclose() 函 式 關 閉 指 定 之 檔 案 , 如 下 :<br />

fclose(fPtr);<br />

12 檔 案 處 理<br />

/**************** append.c **************/<br />

#include <br />

#include <br />

int main()<br />

{<br />

char rec[25];<br />

FILE *f = fopen("fixout.txt", "a");<br />

printf(" 請 輸 入 定 長 整 筆 記 錄 ,Ctrl+Z 結 束 :\n");<br />

printf("123456789012345678901234\n");<br />

while (1)<br />

{<br />

if (gets(rec)==NULL) break;<br />

fprintf(f, "%s\n", rec);<br />

}<br />

fclose(f);<br />

return 0;<br />

}<br />

12.7 資 料 由 循 序 檔 讀 取<br />

資 料 由 循 序 檔 讀 取 的 四 個 基 本 過 程<br />

1. 宣 告 一 個 FILE 結 構 的 指 標 變 數 , 如 下 :<br />

FILE *fPtr;<br />

2. 以 fopen() 函 式 開 啟 檔 案 為 輸 入 , 如 下 :<br />

fPtr=fopen("fixout.txt", "r“ );<br />

3. 以 fscanf() 函 式 將 資 料 由 指 定 之 檔 案 輸 入 , 如 下 例 :<br />

fscanf(fPtr, "%d %s %f", &account, name, &amount);<br />

4. 以 fclose() 函 式 關 閉 指 定 之 檔 案 , 如 下 :<br />

fclose(fPtr);<br />

12 檔 案 處 理<br />

12 檔 案 處 理<br />

/*************** readfile.c ***************/<br />

#include <br />

int main()<br />

{<br />

int account;<br />

char name[12];<br />

float amount;<br />

char line[80];<br />

FILE *f = fopen("fixout.txt", "r");<br />

while ( fgets(line,sizeof(line), f) != NULL)<br />

{<br />

sscanf(line,"%d %s %f",&account,&name,&amount);<br />

printf("%d %s %.2f\n", account, name, amount);<br />

}<br />

fclose(f);<br />

return 0;<br />

}<br />

12 檔 案 處 理<br />

/**************** fixin.c *****************/<br />

#include <br />

int main()<br />

{<br />

int account;<br />

char name[12];<br />

float amount;<br />

FILE *f = fopen("fixout.txt", "r");<br />

while (1)<br />

{<br />

fscanf(f, "%4d%12s%f",&account,&name,&amount);<br />

if ( feof(f) ) break;<br />

printf("%d %s %.2f\n", account, name, amount);<br />

}<br />

fclose(f);<br />

return 0;<br />

}<br />

12 檔 案 處 理<br />

3


12.8 二 進 位 檔<br />

• 二 進 位 檔 與 本 文 檔 不 同 。<br />

• Windows 作 業 系 統 的 本 文 檔 每 一 記 錄 之 後 均 有 返 回<br />

字 元 (Carriage Return 簡 稱 CR) 及 換 列 字 元<br />

(Line Feed 簡 稱 LF),CR 以 十 六 進 位 表 示 為<br />

0x0d,LF 以 十 六 進 位 表 示 為 0x0a。<br />

• C 程 式 輸 入 本 文 檔 時 將 CR/LF 轉 換 為 只 有 LF 字 元 ,<br />

輸 出 本 文 檔 時 又 將 LF 轉 換 為 CR/LF 兩 個 字 元 。<br />

12.8 二 進 位 檔 mode<br />

• 二 進 位 檔 使 用 fopen() 開 檔 時 , 模 式 mode 後 附 加 “b”<br />

表 12.3 開 啟 二 進 位 檔 案 模 式 mode 表<br />

• 二 進 位 檔 之 輸 入 及 輸 出 都 沒 有 這 種 轉 換 的 動 作 。<br />

12 檔 案 處 理<br />

12 檔 案 處 理<br />

12.8 二 進 位 檔 存 取<br />

• fread() 函 式 從 二 進 位 檔 讀 入 資 料 至 變 數<br />

size_t fread(void *ptr, size_t size, size_t n,<br />

FILE *stream)<br />

由 指 定 檔 stream 輸 入 n 項 資 料 , 每 一 項 為 size 個 位 元 組 , 輸 入 至 ptr 指 標 所<br />

指 之 記 憶 體 位 址 。 成 功 時 傳 回 n 值 , 失 敗 或 讀 至 檔 尾 時 傳 回 0 值 。<br />

• fwrite() 函 式 將 變 數 的 內 容 寫 入 至 二 進 位 檔 案<br />

size_t fwrite(const void *ptr, size_t size, size_t n,<br />

FILE *stream);<br />

將 ptr 指 標 所 指 處 之 n 項 資 料 , 每 項 size 個 位 元 組 , 共 n*size 個 位 元 組 寫 入<br />

stream 所 指 的 檔 案 。 成 功 時 傳 回 寫 入 項 數 , 失 敗 時 傳 回 短 缺 之 項 數 。<br />

12 檔 案 處 理<br />

12.8 二 進 位 檔 的 資 料 特 性<br />

• 二 進 位 檔 可 看 成 一 個 位 元 組 循 序 的 集 合 體 ,<br />

• 記 錄 是 二 進 位 檔 基 本 儲 存 資 料 單 元 ,<br />

• 記 錄 本 身 嚴 格 來 說 可 以 是 一 個 位 元 組 , 也 可 以 是 多<br />

個 位 元 組 ,<br />

• 二 進 位 存 取 不 僅 可 讀 寫 ASCII 碼 檔 , 也 可 讀 寫 可 執<br />

行 檔 (.exe 檔 ) 或 目 的 碼 檔 (.obj 檔 ),<br />

• 二 進 位 存 取 對 一 個 已 開 啟 之 檔 可 往 前 或 往 後 讀 寫 ,<br />

12 檔 案 處 理<br />

Position the file pointer<br />

Int fseek(FILE *stream, long offset, int whence)<br />

將 指 定 檔 案 stream 的 檔 案 指 標 移 動 至 偏 離 檔 案 指 標 whence 處 offset<br />

個 位 元 組 之 位 置 。 定 位 成 功 時 傳 回 0 值 , 失 敗 時 傳 回 非 0 值 。<br />

• 檔 案 指 標 位 置 若 為 檔 開 頭 位 置 , 則 開 頭 之 位 元 組 編 號 為 0, 下<br />

一 個 位 元 組 編 號 為 1, 再 下 一 個 位 元 組 編 號 為 2, 等 等 。 檔 案 指<br />

標 位 置 若 為 目 前 檔 案 位 置 , 則 目 前 檔 案 位 置 位 元 組 編 號 為 「 檔<br />

案 指 標 位 置 +0」, 下 一 個 位 元 組 編 號 為 「 檔 案 指 標 位 置<br />

+1」, 等 等 。<br />

12 檔 案 處 理<br />

/******** 【 程 式 readwrite.c】 *******/<br />

#include <br />

#include <br />

int main()<br />

{ char s[80];<br />

unsigned char uc;<br />

FILE f=fopen("readwrite.dat", "wb");<br />

printf(" 請 輸 入 一 個 字 串 : ");<br />

gets(s);<br />

fwrite(s, strlen(s), 1, f);<br />

fclose(f);<br />

printf("\n 傾 印 readwrite.dat 檔 \n");<br />

f=fopen("readwrite.dat", "rb");<br />

while (1)<br />

{ fread(&uc, 1, 1, f);<br />

if (feof(f)) break;<br />

printf("%02X ", uc);<br />

}<br />

fclose(f);<br />

return 0;<br />

}<br />

【 執 行 】<br />

gcc readwrite.c -o readwrite.exe <br />

readwrite.exe <br />

請 輸 入 一 個 字 串 : 123 ABC <br />

傾 印 readwrite.dat 檔<br />

31 32 33 20 41 42 43<br />

12 檔 案 處 理<br />

4


12.9 隨 機 檔 ( 二 進 位 檔 )<br />

循 序 檔 、 隨 機 檔 之 資 料 結 構<br />

• 隨 機 存 取 資 料 儲 存 之 方 式 與 循 序 存 取 大<br />

不 相 同 。<br />

• 循 序 存 取 之 資 料 每 一 個 記 錄 長 度 不 一 , 且<br />

均 以 CR 歸 位 鍵 及 LF 換 列 結 束 ,<br />

• 隨 機 存 取 之 資 料 每 一 個 記 錄 均 為 定 長 , 並<br />

不 以 CR/LF 結 束 。<br />

資 料 1 CR LF<br />

資 料 2 CR LF<br />

資 料 3 CR LF<br />

…<br />

資 料 n CR LF<br />

循 序 檔 之 資 料 結 構 的 資 料 長 度 不 一<br />

紀 錄 1<br />

紀 錄 2<br />

紀 錄 3<br />

…<br />

紀 錄 n<br />

隨 機 檔 之 資 料 結 構 的 資 料 長 度 一 致<br />

12 檔 案 處 理<br />

12 檔 案 處 理<br />

struct accttag acctnode;<br />

FILE *acctfile;<br />

long totalbytes, totalnodes;<br />

void texttobase(void)<br />

{<br />

char line[80];<br />

FILE *f=fopen("acct.txt", "rt");<br />

acctfile=fopen("acct.dat", "wb+");<br />

while ( fgets(line,sizeof(line),f) !=NULL)<br />

{<br />

printf("%s", line);<br />

sscanf(line,"%4d%12s%10f", &acctnode.account,<br />

&acctnode.name, &acctnode.amount);<br />

fwrite(&acctnode, sizeof(acctnode), 1, acctfile);<br />

}<br />

fclose(f);<br />

fclose(acctfile);<br />

}<br />

12 檔 案 處 理<br />

int acctshow(void)<br />

{<br />

long n, offset;<br />

acctfile=fopen("acct.dat", "r+b");<br />

fseek(acctfile, 0L, SEEK_END);<br />

totalbytes = ftell(acctfile);<br />

totalnodes = totalbytes/sizeof(acctnode);<br />

printf("\n 輸 入 記 錄 編 號 : ");<br />

scanf("%ld", &n);<br />

n = n % totalnodes;<br />

offset = n * sizeof(acctnode);<br />

fseek(acctfile, offset, SEEK_SET);<br />

fread(&acctnode, sizeof(acctnode), 1, acctfile);<br />

printf(" 客 戶 編 號 =%-7d\n", acctnode.account);<br />

printf(" 客 戶 姓 名 =%-20s\n", acctnode.name);<br />

printf(" 客 戶 存 款 =%-12.2f\n", acctnode.amount);<br />

fclose(acctfile);<br />

return acctnode.account;<br />

}<br />

12 檔 案 處 理<br />

FILE *acctfile;<br />

int texttobase(void)<br />

{<br />

char line[80];<br />

struct accttag acctnode;<br />

int n, count=0;<br />

FILE *f=fopen("acct.txt", "rt");<br />

while (1)<br />

{<br />

fgets(line, sizeof(line), f);<br />

if (feof(f)) break;<br />

sscanf(line,"%4d%12s%10f", &acctnode.account,<br />

&acctnode.name, &acctnode.amount);<br />

n = acctnode.account;<br />

fseek(acctfile, (n-1)*sizeof(acctnode), SEEK_SET);<br />

fwrite(&acctnode, sizeof(acctnode), 1, acctfile);<br />

count++;<br />

}<br />

fclose(f);<br />

return count;<br />

}<br />

12 檔 案 處 理<br />

int main()<br />

{<br />

int choice=1, acct1=1, acct2=N-1;<br />

FILE *f = fopen("acctbase.dat", "r+");<br />

while (choice != 0)<br />

{<br />

printf(" 輸 入 選 項 /1 加 入 /2 更 新 /3 刪 除 /4 至 本 文 檔 /5 顯 示 /0 結 束 : ");<br />

scanf("%d", &choice);<br />

switch (choice)<br />

{<br />

case 1: newrecord(f); break;<br />

case 2: updaterecord(f); break;<br />

case 3: deleterecord(f); break;<br />

case 4: totextfile(f); break;<br />

case 5:<br />

printf(" 請 輸 入 起 迄 客 戶 編 號 (%d-%d): ",1,(N-1));<br />

scanf("%d %d", &acct1, &acct2);<br />

showrecord(f, acct1, acct2);<br />

break;<br />

}<br />

}<br />

fclose(f);<br />

return 0;<br />

}<br />

12 檔 案 處 理<br />

5


【 執 行 】<br />

acctbase.exe <br />

輸 入 選 項 /1 加 入 /2 更 新 /3 刪 除 /4 至 本 文 檔 /5 顯 示 /0 結 束 : 1 <br />

輸 入 要 新 增 的 客 戶 編 號 (1-9999): 33 <br />

輸 入 姓 名 ( 字 串 ) 及 存 款 ( 浮 點 數 ): SmithWang 333.3 <br />

輸 入 選 項 /1 加 入 /2 更 新 /3 刪 除 /4 至 本 文 檔 /5 顯 示 /0 結 束 : 5 <br />

請 輸 入 起 迄 客 戶 編 號 : 33 33 <br />

編 號 客 戶 姓 名 存 款<br />

33 SmithWang 333.30<br />

輸 入 選 項 /1 加 入 /2 更 新 /3 刪 除 /4 至 本 文 檔 /5 顯 示 /0 結 束 : 2 <br />

輸 入 要 更 新 的 客 戶 編 號 (1-9999): 33 <br />

33 SmithWang 333.30<br />

輸 入 調 整 金 額 (+) 或 (-): -33 <br />

33 SmithWang 300.30<br />

輸 入 選 項 /1 加 入 /2 更 新 /3 刪 除 /4 至 本 文 檔 /5 顯 示 /0 結 束 : 3 <br />

輸 入 要 刪 除 的 客 戶 編 號 (1-9999): 33 <br />

輸 入 選 項 /1 加 入 /2 更 新 /3 刪 除 /4 至 本 文 檔 /5 顯 示 /0 結 束 : 0 <br />

12 檔 案 處 理<br />

6

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!