C的基礎知識

※本篇譯自Dropbox的Alex Allain的文章,但會加入ㄚ琪在TQC+的C認證經驗,所以內容非常值得檢視。

本教學是C++教學的一部分但也設計成為一個獨立的C介紹,即使你以前從未設計過程式,除非你有特別的理由要學C而不是C++,我建議你開始C++教學,不過,假如你不想要一些C++進階功能或是只想要以較不複雜的語言來開始,那麼這份教學正適合你!

準備設定

C是很多不同語言中的一種程式語言,就像是我們使用的語言有很多不同的方言那樣,在C裡面不會因為說的人住在北邊或南邊而存在方言,相反地,他們會因為很多不同的編譯器支援一些不同的功能而存在,有幾個常見的編譯器:特別是Borland C++Microsoft C++GNU C,對這些不同的編譯器來說也有許多前端的環境–最常見的就是使用GNU C++編譯器的Dev-C++,有一些,像是GCC,是免費的,而其他的則沒有,請見編譯器列表有更多關於如何取得邊譯器跟設定的資訊,你應該注意假如你是在C++的邊譯器上用C來設計程式,那麼你會想到確定你的編譯器會嘗試編譯C而不是C++來避免在後面章節中所提到的問題。
這些編譯器每一個都有些不同,每一個都應該支援ANSI標準C函式,但是每一個編譯器也有非標準的函式(這些函式類似於一個國家中用不同的方言講話),有時候非標準函式的使用在你嘗試用不同編譯器編譯原始碼(程式設計師撰寫的真正的C程式碼,然後存成一個文字檔)的時候會造成問題,這些教學使用ANSI標準C而且應該不會有問題;幸運的是,因為C已經使用一段時兼了,所以應該不會有太多相容性的問題除非是你的編譯器嘗試建立C++的程式碼。
假如你還沒有編譯器,我強烈建議你現在找一個,一個簡單的編譯器就夠我們使用了,但是要確定你所用的可以從這些教學裡獲得最多的效益,上面的連結頁,編譯器,以作業系統別列出編譯器。
每一個完整的C程式開始在一個函式內叫做”main”,一個函式只是一個做”某件事”的命令集合,main函式會在程式開始執行時被呼叫,從main,我們會呼叫其他的函式,不管是我們寫的或是其他人寫的還是使用內建的語言功能,要存取你編譯器的標準函式,你需要用#include指令來含括一個標頭檔,這樣做可以有效率地將每件事都放到標頭檔裡然後把它貼到你的程式中,讓我們看看一支使用中的程式:

 #include <stdio.h>

int main()
{
  printf( "I am alive!  Beware.n" );
  getchar();
  return 0;
}

讓我們看看程式的元素,#include是一個”前置處理器”的指令,告訴編譯器在真正建立執行檔前將一個叫做stdio.h的標頭檔的程式碼放到我們的程式裡,藉著含括標頭檔,你可以存取很多不同的函式–printf和getchar這兩個函式都被含括在stdio.h中,分號是C的一個語法,它告訴編譯器這是命令的結束,你稍後會看到分號在C的很多命令中用到。

接下來重要的一行是int main(),這一行告訴編譯器有一個函式叫做main,而且這個函式傳回整數,因此寫int,”大括號” ({跟})表示函式的開始和結束以及其它程式碼區塊,假如你有用過Pascal,你會知道他們是用BEGIN跟END,即使你沒有用過Pascal,思考一下他們的意義也不是錯的方法。
printf函式是顯示輸出到螢幕的標準C方法,引號告訴編譯器,你要輸出的文字字串原樣,’n’序列會被當成一個字元處理,它代表一個新行(我們稍後會有更多的討論);眼下,只要記住有一些序列當他們出現在字串中時,printf不會真正按字面來顯示,’n’是其中的的一個,’n’真正的影響是在你的螢幕上移動游標到下一行,再一次注意這個分號:它被加在每一行的結束處,像是這裡C的函式呼叫。

接下來的命令是getchar(),這是另一個函式呼叫:它讀取一個字元然後等候使用者按下enter然後讀取字元,這一行被含括進來是因為很多編譯器環境會開啟一個新的命令視窗,執行這個程式,然後在你看見輸出前關閉視窗,這個命令可以讓視窗不會關閉因為程式尚未執行完畢它在等候你按下enter,含括這一行可以給你時間來看程式的執行。

最後,程式的最後,我們藉著使用return敘述從main傳回一個值給作業系統,這個傳回值很重要因為她被用來告訴作業系統你的程式執行成功與否,傳回0表示成功。

最後的括號關閉函式,你應該試著編譯程式然後執行它,你可以剪下程式碼貼到一個檔案中,存成.c檔,然後編譯它,假如你使用命令列式的編譯器,像是Borland C++ 5.5,你應該閱讀編譯指令的資訊來編譯,否則,編譯和執行應該是像你用滑鼠點擊一個按鈕那樣簡單(或許是”build”或”run”按鈕)。

你可以開始玩弄 printf函式和習慣編寫簡單的c程式。

解釋你的程式

註解是除了最瑣碎的程式之外最重要的,而這篇教學通常會使用註解來解釋程式碼,當你告訴編譯器一段文字是註解的時候,它在執行的時候忽略它,而這些文字可以是任何你想要描述真正程式碼的文字,要在C裡建立註解,你要用/* 跟 */ 將任何文字包起來作為註解,某些編譯器環境或是文字編輯器 會改變註解區域的顏色來讓它容易被發現,但是有些則不會,確定不要因此就把你程式需要的註解取消掉(也就是說,告訴編譯器這個部份的程式碼是註解。

當你學習程式的時候,註解掉某段的程式碼也是有用的,這樣可以了解輸出如何受到影響。

使用變數

到目前為止你應該能夠撰寫簡單的程式來顯示你程式設計師輸入的資訊,以及用註解來描述你的程式,那太棒了,但是關於跟你的使用者互動?很幸運的是,你的程式也有可能來接受輸入。

但是首先,在你試著接收輸入前,你必須有一個地方可以儲存輸入,在程式設計裡,輸入跟資料被存到變數中,有幾種不同型態的變數;當你告訴電腦你宣告一個變數的時候,你必須含括資料型態跟著變數名稱,幾個基本的型態包括char、int及float,每個型態可以儲存不同的資料型態。

一個char型態的變數可以儲存一個字元,int型態的變數可以儲存整數(沒有小數點的數字),以及float型態的變數儲存有小數點的數字,這些變數型態- char、int跟float – 當你宣告一個變數時每一個都是關鍵字的使用,有些變數也會使用更多的電腦記憶體來儲存他們的值。

當有些多重變數型態看起來是多餘的時候這看起來很奇怪,但是要讓你的程式有效率使用正確的變數大小是重要的因為有些變數需要比其他的變數還多的記憶體,現在,我只想說不同的變數型態幾乎都會被用到!

在你可以使用變數前,你必須宣告變數來告訴編譯器,然後告訴編譯器它的”型態”,要宣告一個變數你要使用<變數型態> <變數名稱>;,(這裡的括號顯示你可以替換為你要的表示式),舉一個例,基本的變數宣告看起來像這樣:

int myVariable;

再一次這一行的結束注意分號的使用,即使我們沒有呼叫函式,分號仍是”表示式”結束時需要用到的,這個程式碼會建立叫做myVariable的變數;現在我們可以自由地在程式中使用myVariable。

在同一行上宣告同一型態的多個變數是允許的;每個變數用逗號來分隔,假如你試著使用一個未定義的變數,你的程式不會執行,你會收到一個錯誤訊息通知你犯了一個錯誤。

這裡有一些變數宣告的例子:

 
int x;
int a, b, c, d;
char letter;
float the_float;

你可以有多個變數擁有相同的型態,但是你不可以多個變數有相同的名稱,此外,你不可已有相同名稱的變數及函式。

變數最後一個限制是變數宣告必須在給定的”程式碼區塊”中其它種類的敘述之前宣告(程式碼區塊只是一段用{跟}包起來的程式碼),所以在C裡頭你必須在做任何事之前宣告你所有的變數:

錯誤

 
#include <stdio.h>
int main()
{
    /* wrong!  The variable declaration must appear first */
    printf( "Declare x next" );
    int x;

    return 0;
}

修正

 
#include <stdio.h>
int main() 
{
    int x;
    printf( "Declare x first" );

    return 0;
}

讀取輸入

一開始在C裡面使用變數來輸入或輸出可能有點麻煩,但是忍耐一下,而且它會很有意義,我們會使用scanf函式還讀取一個值然後用printf把它讀出來,讓我們看一下程式碼然後分兩部份來看看發生什麼事,如果可以幫助你跟著你甚至可以編譯程式碼然後執行。

 
#include <stdio.h>

int main()
{
  int this_is_a_number;

  printf( "Please enter a number: " );
  scanf( "%d", &this_is_a_number );
  printf( "You entered %d", this_is_a_number );
  getchar();
  return 0;
}

那麼這一切意味著?我們在前面已經看到#include以及main函式;main必須出現在你要執行的每一個程式中,而#include讓我們存取printf(以及scanf),(正如你可能已經猜到,stdio.h的io代表”input/output”;而std則表示”standard.”),關鍵字int宣告this_is_a_number是整數。

就是事情開始變得有趣的地方:scanf函式藉著用一個字串以及一些變數前加一個&來執行, 字串告訴scanf要尋找什麼變數:注意我們有一個字串只有”%d” — 這告訴scanf函式要讀進整數,scanf的第二個參數可以說是變數,我們稍後會學到發生了什麼事,但是這裡的大意就是scanf需要知道變數要存到哪裡以改變它的值,在變數前使用&允許你取得它的位置並給予scanf而不是給變數的值,把它想成是給一個提示從蘇打過到他們取得可口可樂而不是直接給那人可樂那樣,& 給scanf函式變數的指示。

當程式執行的時候,每個scanf呼叫會檢查它自己的輸入字串來看看什麼種類的輸入是符合要求的,接著存輸入的值到變數中。

第二個printf敘述也含有相同的’%d’–scanf跟printf兩個使用相同的格式來表示嵌入字串的值,在這裡printf會在字串後使用第一個參數,變數this_is_a_number,並依”格式指定字串”指定的型態來做處理,在這裡,printf處理this_is_a_number依照格式指定字串成為一個整數。

所以把一個數字當成整數是什麼意思呢?假如使用者試著輸入一個小數,在儲存到變數裡的時候小數部份會被截掉,當你執行範例程式的時候試著輸入一系列的字元或小數位數;回應會隨著輸入的不同而不同,但在任何情況下,它非常地漂亮。

當然,不論你使用什麼型態,變數會因不能修改他們而顯得無趣,幾個變數使用的運算子包括下列:*、 -、 +、 /、 =、 ==、 >、 <,* 表乘號、/ 表除號、- 表減號及+表加號,當然要知道修改程式裡變數的值是重要的而使用等號也相當重要,在某些語言裡,等號會比較左右兩邊的值,但是在C裡==才用來做比較,等號仍然相當有用,它設定等號左邊變數的值等於等號右邊的值,執行數算函式的運算子應該用在等號右邊以便指定結果給左邊的變數。

這裡有一些例子:

 
a = 4 * 6; /* (Note use of comments and of semicolon) a is 24 */
a = a + 5; /* a equals the original value of a with five added to it */
a == 5     /* Does NOT assign five to a. Rather, it checks to see if a equals 5.*/

另一個等號的格式==並不是用來指定值給變數,相反地,它會檢查看看如果這些變數是否相等,在很多C的地方它相當地有用;例如,你常常會用==在條件敘述及迴圈的結構中,你大概可以猜到<跟>的功能是如何,他們是大於跟小於的運算子。

例如:

 
a < 5  /* Checks to see if a is less than five */
a > 5  /* Checks to see if a is greater than five */ 
a == 5 /* Checks to see if a equals five, for good measure */ 
學了本章之後,你將可以修正下面這樣的問題,ㄚ琪提醒各位變數一定要先宣告,還有輸入scanf跟輸出printf函數的運用,這兩個函數不清楚使用的也可以參考

ANSI C技術手冊

#include <stdio.h>
#include <stdlib.h>

int main()
{
double a, b;
printf(“請輸入兩個浮點數:”);
scanf(“%d %d”, a, b);
total = a+b;
printf(“total=%f”, total);
system(“PAUSE”);
return 0;
}

測驗一下你的知識

下一課:If敘述

感謝你看到這裡,很快就可以離開了,但最好的獎勵行動就是按一下幫我分享或留言,感恩喔~

點我分享到Facebook

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *