1. 程式人生 > 其它 >C 語言基本語法

C 語言基本語法

本文內容來自網道專案,網道/WangDoc.com
網道是一個文件網站,提供高質量的、擁有自主版權的、可以自由使用的中文軟體文件。鄙人無意間瀏覽到後發現網站提供的軟體文件內容講解十分通俗,並且質量較高,特此收藏與分享。
本文乃至本系列都是謄抄於網道C語言教程,如有各種不當之處,還請速速聯絡。

1. 語句

C 語言的程式碼由一行行語句(statement)組成。語句就是程式執行的一個操作命令。C 語言規定,語句必須使用分號結尾,除非有明確規定可以不寫分號。

int x = 1;

上面就是一個變數宣告語句,宣告整數變數x,並且將值設為1
多個語句可以寫在一行。

int x; x = 1;

上面示例是兩個語句寫在一行。所以,語句之間的換行符並不是必需的,只是為了方便閱讀程式碼。
一個語句也可以寫成多行,這時就要依靠分號判斷語句在哪一行結束。

int x;
x
=
1
;

上面示例中,第二個語句x = 1;被拆成了四行。編譯器會自動忽略程式碼裡面的換行。單個分號也是有效語句,稱為“空語句”,雖然毫無作用。

;

2. 表示式

C 語言的各種計算,主要通過表示式完成。表示式(expression)是一個計算式,用來獲取值。

1 + 2

上面程式碼就是一個表示式,用來獲取1 + 2這個算術計算的結果。
表示式加上分號,也可以成為語句,但是沒有實際的作用。

8;
3 + 4;

上面示例是兩個表示式,加上分號以後成為語句。
表示式與語句的區別主要是兩點:

  • 語句可以包含表示式,但是表示式本身不構成語句。
  • 表示式都有返回值,語句不一定有。因為語句用來執行某個命令,很多時候不需要返回值,比如變數宣告語句(int x = 1)就沒有返回值。

3. 語句塊

C 語言允許多個語句使用一對大括號{},組成一個塊,也稱為複合語句(compounded statement)。在語法上,語句塊可以視為多個語句組成的一個複合語句。

{
	int x;
	x = 1;
}

上面示例中,大括號形成了一個語句塊。
大括號的結尾不需要新增分號。

4. 空格

C 語言裡面的空格,主要用來幫助編譯器區分語法單位。如果語法單位不用空格就能區分,空格就不是必須的,只是為了增加程式碼的可讀性。

int x = 1;
// 等同於
int x=1;

上面示例中,賦值號(=)前後有沒有空格都可以,因為編譯器這裡不借助空格,就能區分語法單位。
語法單位之間的多個空格,等同於單個空格。

int    x =     1;

上面示例中,各個語法單位之間的多個空格,跟單個空格的效果是一樣的。
空格還用來表示縮排。多層級的程式碼有沒有縮排,其實對於編譯器來說並沒有差別,沒有縮排的程式碼也是完全可以執行的。強調程式碼縮排,只是為了增強程式碼可讀性,便於區分程式碼塊。
大多數 C 語言的風格要求是,下一級程式碼比上一級縮排4個空格。為了書寫的緊湊,本書採用縮寫兩個空格。

// 縮排四個空格
if(x > 0)
	printf("positive\n");

// 縮排兩個空格
if(x > 0)
  printf("positive\n");

只包含空格的行被稱為空白行,編譯器會完全忽略該行。

5. 註釋

註釋是對程式碼的說明,編譯器會自動忽略註釋,也就是說,註釋對實際程式碼沒有影響。
C 語言的註釋有兩種表示方法。第一種方法是將註釋放在/*...*/之間,內部可以分行

/* 註釋 */

/*
	這是一行註釋
*/

這種註釋可以插在行內。

int open(char* s/* file name */, int mode);

上面示例中,/* filename */用來對函式引數進行說明,跟在它後面的程式碼依然會有效執行。
這種註釋一定不能忘記寫結束符號*/,否則很容易導致錯誤。

printf("a "); /* 註釋一
printf("b ");
printf("c "); /* 註釋二 */
printf("d ");

上面示例的原意是,第一行和第三行程式碼的尾部,有兩個註釋。但是,第一行註釋忘記寫結束符號,導致註釋一延續到第三行結束。
第二種寫法是將註釋放在//後面,從雙斜槓到行尾都屬於註釋。這種註釋只能是單行,可以放在行首,也可以放在一行語句的結尾。這是C99 標準新增的語法。

// 這是一行註釋

int x = 1; // 這也是註釋

不管哪一種註釋,都不能放在雙引號裡面。雙引號裡面的註釋符號,會成為字串的一部分,解釋為普通符號,失去註釋作用。

printf("// hello /* world */ ");

上面示例中,雙引號裡面的註釋符號,都會被視為普通字元,沒有註釋作用。
編譯時,註釋會被替換成一個空格,所以min/* space */Value會變成min Value,而不是minValue

6. printf()

6.1 基本語法

本書的示例會大量用到printf()函式,這裡先介紹一下這個函式。
printf()的作用是將引數文字輸出到螢幕。它名字裡面的f代表format(格式化),表示可以定製輸出文字的格式。

printf("Hello World");

上面命令會在螢幕上輸出一行文字"Hello World"。
printf()不會在行尾自動新增換行符,執行結束後,游標就停留在輸出結束的地方,不會自動換行。為了讓游標移到下一行的開頭,可以在輸出文字的結尾,新增一個換行符\n

printf("Hello World\n");

如果文字內部有換行,也是通過插入換行符來實現。

printf("Hello\nWorld\n");

上面示例先輸出一個Hello,然後換行,在下一行開頭輸出World,然後又是一個換行。
上面示例也可以寫成兩個printf(),效果完全一樣。

printf("Hello\n");
printf("World\n");

printf()是在標準庫的標頭檔案stdio.h定義的。使用這個函式之前,必須在原始碼檔案頭部引入這個標頭檔案。

#include <stdio.h>

int main()
{
	printf("Hello World\n");
}

上面示例中,只有在原始碼頭部加上#include <stdio.h>,才能使用printf()這個函式。
#include指令的詳細解釋,請看《前處理器》一章。

6.2 佔位符

printf()可以在輸出文字中指定佔位符。所謂"佔位符",就是在這個位置可以用其他值代入。

// 輸出 There are 3 apples
printf("There are %i apples\n", 3);

上面示例中,There are %i apples\n是輸出文字,裡面的%i就是佔位符,表示這個位置要用其它值來替換。佔位符的第一個字元一律為百分號%,第二個字元表示佔位符的型別,%i表示這裡代入的值必須是一個整數。
printf()的第二個引數就是替換佔位符的值,上面的例子是整數3替換%i。執行後的輸出結果就是There are 3 apples
常用的佔位符除了%i,還有%s表示代入的是字串。

printf("%s will come tonight\n", "Jane");

上面示例中,%s表示代入的是一個字串,所以printf()的第二個引數就必須是字串,這個例子是Jane。執行後的輸出就是Jane will come tonight
輸出文本里面可以使用多個佔位符。

printf("%s says it is %i o'clock\n", "Ben", 21);

上面示例中,輸出文字%s says it is %i o'clock有兩個佔位符,第一個是字串佔位符%s,第二個是整數佔位符%i,分別對應printf()的第二個引數(Ben)和第三個引數(21)。執行後的輸出就是Ben says it is 21 o'clock
printf()引數與佔位符是一一對應關係,如果有n個佔位符,printf()的引數就應該有n + 1個。如果引數個數少於對應的佔位符,printf()可能會輸出記憶體中的任意值。
printf()的佔位符有許多種類,與 C 語言的資料型別相對應。下面按照字母順序,列出常用的佔位符,方便查詢,具體含義在後面章節介紹。

  • %a:浮點數。
  • %A:浮點數。
  • %c:字元。
  • %d:十進位制整數。
  • %e:使用科學計數法的浮點數,指數部分的e為小寫。
  • %E:是用科學計數法的浮點數,指數部分的E為大寫。
  • %i:整數,基本等同於%d
  • %f:小數(包含float型別和double型別)。
  • %g:6個有效數字的浮點數,整數部分一旦超過6位,就會自動轉為科學計數法,指數部分的e為小寫。
  • %G:等同於%g,唯一的區別是指數部分的E為大寫。
  • %hd:十進位制 short int 型別。
  • %ho:八進位制 short int 型別。
  • %hx:十六進位制 short int 型別。
  • %hu:unsigned short int 型別。
  • %ld:十進位制 long int 型別。
  • %lo:八進位制 long int 型別。
  • %lx:十六進位制 long int 型別。
  • %lu:unsigned long int 型別。
  • %lld:十進位制 long long int 型別。
  • %llo:八進位制 long long int 型別。
  • %llx:十六進位制 long long int 型別。
  • %llu:unsigned long long int 型別。
  • %Le:科學計數法表示的 long double 型別浮點數。
  • %Lf:long double 型別浮點數。
  • %n:已輸出的字串數量。該佔位符本身不輸出,只將值儲存在指定變數之中。
  • %o:八進位制整數。
  • %p:指標。指標就是地址。
  • %s:字串。
  • %u:無符號整數(unsigned int)。
  • %x:十六進位制整數。
  • %zdsize_t型別。
  • %%:輸出一個百分號。

6.3 輸出格式

printf()可以定製佔位符的輸出格式。
(1)限定寬度
printf()允許限定佔位符的最小寬度。

printf("%5d\n", 123); // 輸出為 "  123"

上面示例中,%5d表示這個佔位符的寬度至少為5位。如果不滿5位,對應的值的前面會新增空格。
輸出的值預設是右對齊,即輸出內容前面會有空格;如果希望改成左對齊,在輸出內容後面新增空格,可以在佔位符的%的後面插入一個-號。

printf("%d-5d\n", 123); // 輸出為 "123  "

上面示例中,輸出內容123的後面添加了空格。
對於小數,這個限定符會限制所有數字的最小顯示寬度。

// 輸出 "  123.450000"
printf("%12f\n", 123.45);

上面示例中,%12f表示輸出的浮點數最少要佔據12位。由於小數的預設顯示精度是小數點後6位,所以123.45輸出結果的頭部會新增2個空格。
(2)總是顯示正負號
預設情況下,printf()不對正數顯示+號,只對負數顯示-號。如果想讓正數也輸出+號,可以在佔位符的%後面加一個+

printf("%+d\n", 12); // 輸出 +12
printf("%+d\n", -12); // 輸出 -12

上面示例中,%+d可以確保輸出的數值,總是帶有正負號。
(3)限定小數位數
輸出小數時,有時希望限定小數的位數。舉例來說,希望小數點後面只保留兩位,佔位符可以寫成%.2f

// 輸出 Number is 0.50
printf("Number is %.2f\n", 0.5);

上面示例中,如果希望小數點後面輸出3位(0.500),佔位符就要寫成%.3f
這種寫法可以與限定寬度佔位符,結合複用。

// 輸出為 "  0.50"
printf("%6.2f\n", 0.5);

上面示例中,%6.2f表示輸出字串最小寬度為6,小數位數為2.所以,輸出字串的頭部有兩個空格。
最小寬度和小數位數這兩個限定值,都可以用*代替,通過printf()的引數傳入。

printf("%*.*f\n", 6, 2, 0.5);

// 等同於
printf("%6.2f\n", 0.5);

上面示例中,%*.*f的兩個星號通過printf()的兩個引數62傳入。
(4)輸出部分字串
%s佔位符用來輸出字串,預設是全部輸出。如果只想輸出開頭的部分,可以用%.[m]s指定輸出的長度,其中[m]代表一個數字,表示所要輸出的長度。

// 輸出 hello
printf("%.5s\n", "hello world");

上面示例中,佔位符%.5s表示只輸出字串"hello world"的前5個字元,即"hello"。

7. 標準庫,標頭檔案

程式需要用到的功能,不一定需要自己編寫, C 語言可能已經自帶了。程式設計師只要去呼叫這些自帶的功能,就省得自己編寫程式碼了。舉例來說,printf()這個函式就是 C 語言自帶的,只要去呼叫它,就能實現在螢幕上輸出內容。
C 語言自帶的所有這些功能,統稱為"標準庫"(standard library),因為它們是寫入標準的,到底包括哪些功能,應該怎麼使用的,都是規定好的,這樣才能保證程式碼的規範和可移植。
不同的功能定義在不同的檔案裡面,這些檔案統稱為"標頭檔案"(header file)。如果系統自帶某一個功能,就一定還會自帶描述這個功能的標頭檔案,比如printf()的標頭檔案就是系統自帶的stdio.h。標頭檔案的字尾通常是.h
如果要使用某個功能,就必須先載入對應的標頭檔案,載入使用的是#include命令。這就是為什麼使用printf()之前,必須先載入stdio.h的原因。

#include <stdio.h>

注意,載入標頭檔案的#include語句不需要分號結尾,詳見《前處理器》一章。

本系列內容來自網道專案,網道/WangDoc.com