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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM