內容 | |
實 習 目 標 |
程式撰寫時常發生的語法錯誤 |
程式錯誤範例:以下測試一些常常遇見的語法錯誤, 讓你看一下編譯器 (g++ 或是 gcc) 的錯誤訊息, 通常這些錯誤訊息都是可以解釋的, 你應該要嘗試去瞭解為什麼編譯器會給你那樣的錯誤訊息, 它在看到什麼樣的程式時會給你那樣的訊息, 如此你才會看到編譯器是藉由語法檢查來幫助你完成一個正確的程式, 而不是在找你麻煩, 這個也不認得, 那個也不認得..., 千萬不要忽視這些錯誤訊息, 盲目地用嘗試錯誤法修改程式, 或是道聽途說地修改程式, 自己打進去(或是拷貝進去)的程式, 自己應該要能夠預期它的語法是否正確, 清楚瞭解它的功能是什麼!! |
|
1. |
語法錯誤一看一個錯誤訊息最重要的是看它在程式裡出現的位置, 上面第一個錯誤出現在第4列大括號 (before '{') 的地方, 當然你第一個直覺可能會認為這裡怎麼有錯呢? 明明是在前面第 3 列少了東西, 編譯器指著第 4 列的大括號說 "發現錯誤" 其實是有原因的, C 的程式編排是 格式自由 (Free format)的, 在程式裡每一個元素的順序是很重要的, 例如 int 之後接 main, 之後接左側小括號 (, 之後接 void, 之後接右邊小括號 ), 然後接大括號 {, 你可以打成 int main ( void ) {或是 int main(void) {順序是重要的, 但是空白字元, 換列, 怎麼對齊是隨意的, 所以編譯器看到 void 時都還認為是對的, 編譯器根據語法預期接下來可能有右邊小括號 ) 或是逗點 , 但是不幸的是它在第四列發現接下來的是左大括號 {, 所以在這個地方編譯器才能確定這個程式的語法出現錯誤 另外有一件事很重要, 當編譯器發現語法錯誤以後, 它會嘗試去猜你漏掉了什麼, 你打錯了什麼, 然後儘可能去回復, 跳過一些錯誤的程式元素, 繼續檢查剩下程式碼的語法, 不過因為要編譯器正確地跳過所有的錯誤是相當困難的, 因此常常編譯器的第二個以後的錯誤都沒有太大的參考價值...建議你由最上面的錯誤開始改, 改完以後立刻重新編譯, 一個一個錯誤往下修改...不要貪心想要一次就改很多個錯誤, 像這個例子中, 出現在第 8 列的錯誤你就暫時不需要太在意它 |
2. |
語法錯誤二在第 5 列的地方編譯器看到 printf, 看到 (, 接下來編譯器預期應該是一個 字串 或是 字元陣列變數, 編譯器看到 Hello 時, 會去檢查先前的變數定義, 看看有沒有 Hello 的定義, 因為沒有看到, 所以它就說 `Hello' undeclared, 後面那個 missing terminating " character 的訊息就請你暫時略過, 等你修改完前面這個, 重新編譯以後再來檢視 |
3. |
語法錯誤三第 5 列少了分號, 編譯器繼續往下尋找分號, 看到第 6 列的 system 時, 就知道程式缺了分號了 |
4. |
語法錯誤四編譯器在第 5 列最後找不到第二個雙引號 ", 於是告訴你程式有錯誤, 這也告訴你語法上每一個 字串 都要在同一列裡, 根據這個錯誤訊息, 你應該可以很快改過來, 可是你也許會有一個疑問? 如果我要打的訊息很長, 打在一列裡很難看, 可以分開多列打嗎? 基本上有三種方式可以完成: 1. 分成多次 printf 呼叫敘述 printf("Hello World!\n"); printf("Hello World!\n"); 2. 在前一列最後用反斜線 \ 字元表示下一列繼續 printf("Hello World!\n\ Hello World!\n"); 3. 編譯器自動將連續的多個 字串常數 合併 printf("Hello World!\n" "Hello World!\n");測試一下吧! |
5. |
語法錯誤五在第 5 列出現了 print 函數的呼叫, 但是這個函數並沒有定義在 stdio.h 或是 stdlib.h 檔案裡面, 所以出現 `print' undeclared 的訊息, 請注意你在輸入程式的時候不要忽略了大小寫是不同的這件事情, 否則大小寫一打錯的結果也常常就出現 xxxx undeclared 的訊息如下: |
6. |
語法錯誤六 |
7. |
連結錯誤Linker 就是指 連結器, 因為系統認為你的程式裡應該有一個 main 函數, 所以當連結器來尋找這個函數卻發現找不到的時候, 就給你這個訊息
|