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