tft每日頭條

 > 教育

 > 計算機二級c 語言基礎知識

計算機二級c 語言基礎知識

教育 更新时间:2025-02-07 14:39:42

第2章 C語言編程基礎

本章重點

· C語言基本數據類型

· 常量

· 變量

· 類型轉換

在開發C語言程序時,需要掌握一些基本語法,如變量的定義、常量的定義、類型轉換等,本章将針對這些知識進行詳細地講解。

認識二進制

二進制是計算技術中廣泛采用的一種。據是用0和1兩個來表示的數。它的基數為2,進位規則是"逢二進一",借位規則是"借一當二",由18世紀德國數理哲學大師發現。當前的使用的基本上是,數據在計算機中主要是以補碼的形式存儲的。計算機中的二進制則是一個非常微小的開關,用"開"來表示1,"關"來表示0。

1. 十進制與二進制之間的轉換

一個十進制數1024對應的二進制表示為100 0000 0000(為便于閱讀,在每四位數之間以一個空格進行分隔)。該如何轉換呢?

首先以簡單的4位二進制數為例:假設有4個bit,每一個bit的值是0或1,這樣一共可以表示24=16個不同的二進制數:

表 2‑1 4位二進制數

把4位二進制數從右到左分别稱為第0到3位。根據之前介紹的二進制表示規則,第0位的1表示1個20=1,第1位的1表示1個21=2,第2位的1表示1個22=4,第3位的1表示1個23=8,據此可以寫出這16個二進制數所對應的十進制值。以二進制的1101為例,它對應的十進制整數是8 4 1=13,如圖2-1所示:

計算機二級c 語言基礎知識(計算機等級考試必備之第2章)1

圖 2‑1 二進制到十進制的轉換示意

下表為4位二進制數到十進制數的轉換表。

表 2‑2 4位二進制數和十進制數

(多學一招:負整數的補碼表示法

大家已經知道了如何用二進制表示一個正整數,那麼二進制又是如何表示負整數的呢?一個很自然的想法是利用最高位來表示符号位,然後利用剩下的bit來表示絕對值。以4位二進制數為例:如果規定最高位用0表示正整數,用1表示負整數的話,16個4位二進制數的值分别是:

表 2‑3 4位二進制數和十進制數

很可惜,這樣的表示方法有幾個問題:首先,0的表示不唯一;更麻煩的是算術運算變得更加複雜了。以加法為例:當把兩個帶符号整數相加的時候,如果兩個數的符号相同,那麼結果的符号不變,絕對值是這兩個數的絕對值相加;如果兩個數的符号相反,那麼把兩個數的絕對值相減(大減小),并取絕對值較大的加數的符号作為結果的符号。這樣一次簡單的加法操作涉及到了多次判斷,比大小,甚至是減法。

出于上述考慮,計算機中采用補碼來表示負整數。補碼表示法不是很直觀,但是簡化了算術運算。以4位二進制數舉例:在補碼中,第0到2位的1含義和之前一樣,分别表示1,2和4,但是第3位的1表示的不是8,而是-8:

表 2‑4 4位二進制補碼和十進制數

以上表中的1010為例:第1位的1表示1個2,第3位的1表示1個-8,所以合起來1010就表示-8 2=-6。可以試着選0111(7)和1111(-1)做加法,看看能否得到0110。

現在大家已經知道了如何從一個二進制正整數算出對應的十進制正整數,那麼,如果給定一個十進制正整數,怎樣得到它對應的二進制數呢?通常采用的方法是除二取餘法:把正整數不斷除以2,将每次得到的餘數連起來再逆序,就是對應的二進制表示。下面仍以十進制的13為例:

1. 13除以2得6,餘數是1;

2. 6除以2得3,餘數是0;

3. 3除以2得1,餘數是1;

4. 1除以2得0,餘數是1;

所以13的二進制表示就是1101。

(多學一招:負整數的補碼表示法

比求正整數二進制表示更加困難的是如何從負整數求出對應的二進制補碼。在這裡以-3為例,求解對應的4位二進制補碼:

1. 求絕對值的二進制表示:3的二進制表示是0011;

2. 按位取反:0變1,1變0,得到1100;

3. 加1:1100 1=1101。這就是-3的補碼。

可以仿照上述過程求解負整數的補碼。

(腳下留心:計算機究竟是存儲十進制數,還是存儲二進制數?

大家都會有這樣的疑問:"講了十進制數,又講了二進制數,雖然知道計算機運算時用的是二進制數,但它存儲的時候是存儲十進制數呢,還是二進制數呢?"要解答這個問題,關鍵在于理解"數"和"數的表示"之間的區别。

對于一個數而言,在不同表示法下長的樣子可能是不一樣的。以上文講的13為例,在十進制表示法下由兩位數"1"和"3"組成,而在二進制表示法下由四位數"1""1""0"和"1"組成。盡管這兩種表示法看上去不同,但是它們的值是相同的,仍然表示同一個數。

因此計算機存儲的既不是十進制數,也不是二進制數——計算機存儲的是數值本身;運算時是基于二進制的;至于顯示到屏幕上時究竟是顯示成十進制還是二進制,這就由大家寫的程序決定了。

2.二進制的擴展:八進制與十六進制

除十進制和二進制以外,還有兩種在程序中經常使用的進制:八進制和十六進制。所謂八進制就是用0到7組成的數字,每一位的大小分别是1,8,64,512等等。比如八進制的156換算成十進制就是1個64,加上5個8,加上6個1:64 40 6=110。

八進制和二進制之間有十分簡單的轉換關系:對于八進制數,隻要将每一位都按照下表翻譯成3位二進制數,并将它們連接在一起即可:

表 2‑5 二進制數和八進制數

舉例來說,八進制數156換算成二進制就應該是:001 101 110,也就是1101110,試着将它轉換成十進制數:2 4 8 32 64=110,和八進制數一緻。

反過來要将二進制數轉換成八進制數也很簡單:隻要将二進制數3個一組,按照上表翻譯成對應的八進制數碼即可:比如下面這個16位的二進制數:

1001 1100 1010 1011

首先按照3個一組進行分組:

1 001 110 010 101 011

接着将它們轉換成對應的八進制數字:

1 1 6 2 5 3

所以對應的八進制數就是116253。可以驗證它們的十進制值都是40107。

除了八進制,在程序中更加常用的是十六進制。十六進制用0到9,A到F分别表示0到15這16個值,每一位的大小分别是1,16,162=256等等。每一位表示的分别是160,161,162等等。

表 2‑6 二進制數和十六進制數

二進制和十六進制的轉換同二進制和八進制的轉換非常類似:隻要将二進制數4個一組按照上表進行轉換即可。用十六進制替代二進制的一個好處就是書寫非常方便。比如一個32位的int類型整數:

0111 1101 1010 1010 0011 0110 1100 1001

轉換成對應的16進制整數就是:0x7DAA36C9。它的十進制大小是2108307145

(多學一招:利用windows計算器進行進制轉換

Windows 自帶的計算器可以方便地實現進制轉換的功能,這裡以Windows 7上的計算器為例進行簡單介紹。按住鍵盤上的windows鍵(一般在空格鍵左側,帶有windows圖标) R,輸入calc,可以快速啟動計算器,如圖2-2所示:

計算機二級c 語言基礎知識(計算機等級考試必備之第2章)2

圖 2‑2 快速啟動計算器

啟動計算器之後,在"查看"菜單下面找到"程序員",就可以進入專為程序員設計的計算器界面:

計算機二級c 語言基礎知識(計算機等級考試必備之第2章)3

圖 2‑3 計算器的程序員界面

圖2-3中注意到左側的進制選項,可以分别選擇十六進制、八進制、十進制和二進制。選擇十進制,并輸入一個十進制整數,就可以在數字下方看到它的32位bit表示,選擇相應的進制就可以得到進制轉換的結果。

(多學一招:如何将八進制和十六進制數轉換成十進制?

上文介紹了如何在二進制和八進制、十六進制之間進行轉換,那要如何将八進制和十六進制數轉換為十進制呢?思路很簡單:先将它們轉換成二進制數,再根據前文中講過的二進制到十進制的轉換方法轉換到十進制數即可。

例如對于十六進制數0xD53A,要轉換成十進制數的話需要經過以下過程:

0xD53A = 1101 0101 0011 1010 (二進制) = 54586 (十進制)

八進制數04255,要轉換成十進制數的話需要這樣做:

04255 = 1000 1010 1101 = 2221

3.有符号數和無符号數

有符号數就是用最高位表示符号(正或負),其餘位表示數值大小。比如: 0011 表示 3; 1011 表示 -3。 無符号數全部二進制均代表數值,沒有符号位。即第一個"0"或"1"不表示正負。比如: 0011 表示 3; 1011 表示 11。 C支持所有整型數據類型的有符号數和無符号數運算。盡管C标準并沒有指定某種有符号數的表示,但是幾乎所有的機器都使用二進制補碼。通常,大多數數字默認都使有符号的,C也允許無符号數和有符号數之間的轉換,當執行一個運算時,如果它的一個運算數是有符号的而另一個是無符号的,那麼C會隐含地将有符号參數強制轉換為無符号數,并假設這兩個數都是非負的,來執行這個運算。

基本數據類型

C語言為大家提供了不同種類的基本數據類型,其中包括整數類型、實型類型、字符類型等等,每一種數據類型用途都是不一樣的,本節将針對C語言基本數據類型的相關知識進行詳細地講解。

2.1.1 整數類型

顧名思義,整數類型就是用來保存整數的數據類型。C語言中基本的整數類型為int,一般長度為4個字節,即32位二進制數。

4在int的基礎上,C語言還提供了short int、long int和long long int三種整型數據類型,這三種類型名稱中的int都可以省略不寫,即略寫為short、long與long long。這幾種類型都是用來保存整數的,除了名字不同之外,還有什麼區别呢?顧名思義,"short"意味着短,"long"意味着長,用來存儲數字的空間越大,能存儲的最大數值就越大。因此一般而言,short型變量能存儲的最大數值要比int型變量能存儲的最大數值小,而long long型變量能存儲的最大數值是最大的。

C語言标準中并沒有明确規定以上四種整型數據類型的長度,因此它們的長度由編譯器自行決定。大家可以利用C語言提供的sizeof運算符查看自己計算機上這四種整型數據的長度。sizeof運算符接受數據類型的名稱,返回以字節為單位的該數據類型的長度。

在Visual Studio中新建一個工程,複制以下代碼:

例程 2‑1 查看數據類型的長度

1 /* DataTypeLength Project */

2 #include <stdio.h>

3 int main()

4 {

5 printf("%d\n", sizeof(int));

6 return 0;

7 }

程序的運行結果如圖2-5所示:

計算機二級c 語言基礎知識(計算機等級考試必備之第2章)4

圖 2‑5 int的長度

編譯運行該工程後,輸出的結果是電腦上int型變量的長度。可以将sizeof後面的int換成short,long和long long分别試驗,輸出的結果就是對應數據類型的長度。

盡管C語言标準中沒有明确規定整型數據的長度,但是有如下要求:首先,short型變量的長度必須不短于2個字節,long型變量的長度不短于4個字節;其次是幾種數據類型的相對長度:

計算機二級c 語言基礎知識(計算機等級考試必備之第2章)5

在64位計算機系統上利用VS編譯上述例程後,得到的以上各種數據類型的長度如下表所示,供大家參考,如表2-7所示:

表 2‑7整型數據的長度的一些參考值

現在大家清楚了,C語言能夠理解如下幾種整數類型:short、int、long和long long。對于short,計算機會準備2個字節來保存;對于int,計算機會準備4個字節,對于long long,計算機會準備8個字節。接下來第二個問題一定是:4個字節的int究竟能表示多大的整數?

要搞清楚這個問題,從十進制數開始分析。如果有人問:"3位的十進制數可以表示的最大整數是多少?"大家一定會很輕松地回答999,因為對十進制太熟悉了。

遺憾的是,計算機使用的是二進制。下面換一個問法:"32位(4字節)的二進制數可以表示的最大整數是多少?"直覺上,答案應該是下面這個數:

1111 1111 1111 1111 1111 1111 1111 1111

一共32位,每一位都取成最大值1,應該就是32位二進制能表示的最大整數了吧?因為是二進制,每一位隻能取0或者1,所以就取成1吧!

這個數大概是十進制的40億。然而,40億并不是int能夠表示的最大整數——int的最高位被用來區别要表示的數是正數還是負數了,所以實際上int能夠表示的最大整數是:

0111 1111 1111 1111 1111 1111 1111 1111

這個數大概是20億。int能夠表示的最小負數大概也是負20億,所以現在應該有這樣的概念:對于正負20億以内的數,用int來表示就足夠了(這句話的意思是說:4個字節就已經夠表示這個數了,沒有必要用8個字節的long long,多了也浪費是不是?)。下面的表格列出了這幾種數據類型能夠表示的範圍,供需要的時候對照:

表 2‑8 各種整型的表示範圍

大家可能已經注意到了int的最高位被用來表示正負數了,如果能夠保證不使用負數的話(比如說,定義一個整數來表示人的體重,體重總不可能取到負數的),那最高位不就沒什麼用了嗎?對于這種情況,C中提供了4種非負類型的整數,稱為無符号整型:

表 2‑9 各種無符号整型的長度和表示範圍

無符号整型看上去很簡單,隻是在之前的數據類型前面加了一個unsigned,而且不改變字節數。不過,無符号整型隻能表示非負整數了,但是非負整數的範圍比原來的有符号整型要大,這是非常合理的:因為之前用來表示符号的最高位被用來存儲數字。

在本小節結束對整型的讨論之前,還有最後一個疑問:

"如果定義的數超出了範圍會怎麼樣?"

如果對計算機說:

"定義一個short類型的整數,這個整數的值是70000。"

計算機查看了一下上面的幾張表,"short類型,要準備2個格子……70000……等一下70000?好像超出範圍了……"這個時候計算機會崩潰嗎?它不會那麼脆弱的,隻不過它會對輸入的70000做一些偷工減料的處理,從而把它塞到2個字節當中(當然,處理之後的這個數肯定不會是70000了)。具體的做法将在後文中講解。

計算機二級c 語言基礎知識(計算機等級考試必備之第2章)6

圖 2‑6 向short型變量中存入70000

小結一下:計算機用2/4/8個字節來表示一個有符号或者無符号的整數,不同的整數類型有不同的範圍,大家可以根據想要表示的數選擇合适的整數類型,如果想表示的值溢出了,計算機會自己偷偷做一些改動。

(多學一招:int類型的表示範圍

int一共包含32位,其中最高位可以區别正負,0表示正數,1表示負數,所以int型變量能夠表示的最大正整數應該是:

0111 1111 1111 1111 1111 1111 1111 1111

将這個數換算成十進制就是230 229 228 …… 20=231-1=2147483647,這就是int能夠表示的最大整數。

2.1.2 實型類型

實型數據是由整數部分和小數部分組成。除了正确地表示整數之外,還需要利用二進制正确地表示小數。小數的表示要複雜一些,但是思路和整數是一樣的:C語言提供了兩種類型,分别是浮點型float和雙精度浮點型double,float用4個字節,double用8個字節來表示小數,它們也都有各自能表示的範圍。

表 2‑10 浮點數的表示範圍

當然這裡有幾個問題需要注意:首先,和整數不一樣,小數可能有無限多個,但是由于隻有有限個字節,所以有些小數是注定無法準确表示的。比如:

計算機二級c 語言基礎知識(計算機等級考試必備之第2章)7

這是一個無限循環小數,程序是沒辦法用32位或者64位空間來精确表示的——因為它有無限多位。此外,有些看上去很簡單的十進制小數也沒有辦法用float和double來表示,比如0.6。這是由于十進制和二進制之間的轉換方式導緻的,所以很遺憾,在表示浮點數的時候,最好不要假設浮點數能夠被計算機精确地表示。

在Visual Studio中新建一個C工程,如例程2-2所示:

例程 2‑2 浮點數0.6

8 /* float Project */

9 #include <stdio.h>

10 int main()

11 {

12 float f = 0.6f;

13 printf("%.10f\n", f);

14 return 0;

15 }

程序的運行結果如圖2-7所示:

計算機二級c 語言基礎知識(計算機等級考試必備之第2章)8

圖 2‑7 浮點數0.6

例程2-2中程序做了如下幾件事情:

定義了一個float類型的數,值為0.6(後面的f隻是為了表示這個數是float類型,不影響0.6的值);

在屏幕上輸出這個數小數點後10位的值。

運行程序,會發現得到的值是0.6000000238。計算機對于精确表示0.6無能為力,所以它隻能盡量做到最好,用一個它能表示的最接近的值來代替0.6。

除了無法精确表示小數,浮點數表示的數是有下限的。對于float來說,10的負38次方是它所能表示的極限,這意味着比這個數量級更小的正數,如1e-100,float是無法表示的(不過0可以精确表示的),這也是由于浮點數的表示方式導緻的。

小結:C語言中用4個字節的float或者8個字節的double來表示一個浮點數,但是不一定能精确地表示想要的小數。此外,不要用float或者double去表示特别特别大,或特别特别小的數。當然大部分情況下,float和double提供的範圍已經夠用了。另外,float和double也可以表示整數,畢竟,整數也是一種"小數",隻不過小數部分為0。遺憾的是,對于一部分特别大的整數,即使這個整數在浮點數能夠表示的範圍之内,float和double也不能保證精确地表示。總之,在使用浮點數時,在任何情況下都不要假設提供的數被精确表示了——除非完全明白浮點數的表示方法。

2.1.3 字符類型

除了表示整數和浮點數,C語言中還需要表示的一類數據就是字符。最常見的字符就是英文字母了,假設現在對本章開頭那台高度智能的計算機說:

"定義一個英文字母A。"

對于計算機來說,它隻懂二進制,它隻知道為大家想要的值分配幾個小格子(字節),然後在每個格子裡面填上8個0或者1。它是無法直接理解英文字母的。這時候就需要有人告訴計算機一個對應關系:

"存一個英文字母A的時候,就分配一個小格子給它,然後在裡面存一個十進制數65。"

大體上,計算機就是這樣存儲字符的。這種用來存儲字符的數據類型叫做char,翻譯成中文字符型,長度為一個字節。一張名為"ASCII碼表"的表格負責把常見的字符對應到一個字節長的整數:把A對應到65,B對應到66,C對應到67,空格鍵對應到32,a對應到97,等等。計算機每次碰到一個字符的時候,就去ASCII碼表當中去查對應的整數,然後把這個整數存起來,于是字符就被保存下來了。當需要使用這個字符的時候,計算機就把格子裡的整數取出來,然後查ASCII碼表,找到對應的字符。下表是常見字符到ASCII編碼的對應。完整的ASCII碼表請參照下一節中,如表2-11所示:

表 2‑11 常見字符的ASCII碼

大家肯定已經意識到了,既然隻用一個格子來表示字符,而一個格子能表示的數肯定很少(其實隻有256個),所的這張ASCII碼表應該也很短,能表示的字符也很少。确實是這樣,而且它比想象的還要短——基本ASCII碼表裡面隻有128個字符,但是對英文來說這已經夠用了。

根據上面的描述,char類型本質上就是長度為一個字節的整數,所以它也可以像int和short那樣用來保存整數,也可以在前面加上unsigned變成unsigned char來保存無符号整數。請看下面的例子:

在Visual Studio中新建一個C工程,如例程2-3所示:

例程 2‑3 ASCII碼與字符

1 /* ASCII Project */

2 #include <stdio.h>

3 int main()

4 {

5 char ch = 'A';

6 printf("%c %d\n", ch, ch);

7 return 0;

8 }

程序的運行結果如圖2-8所示:

計算機二級c 語言基礎知識(計算機等級考試必備之第2章)9

圖 2-8 ASCII字符

例程2-3中首先定義了一個char類型的英文字母A,然後用兩種形式輸出:%c把ch看成是字符輸出,%d把ch看成是整數輸出。最後輸出的結果分别是A和65。

可以試着把第一句改成

char ch = 65;

重新編譯并運行發現結果是一樣的。這說明對于char來說,A和65其實沒什麼區别。

(多學一招:為什麼計算機要采用二進制

大家可能會奇怪,和十進制相比,二進制表示同樣的數要占用更多的位數,對使用者來說也更加不直觀,為什麼計算機還要選擇采用二進制來存儲和運算呢?這是因為計算機中實際上是以電子元件的狀态來保存數據的。具有兩種穩定狀态(如電壓的高與低,二極管的通與斷)的電子元件是很容易制造的,因此使用二進制來保存數據就順理成章了。如果計算機要使用十進制,就意味着在不增加電子元件數量的前提下,每一個元件需要有十種穩定的狀态來對應表示0到9這十種可能的值,這比直接使用二進制要困難多了。

通過上一小節的學習,大家應該對C語言中的基本數據類型有了一些基本的認識。同時,也看到了很多的例子中都有這種語句:

float f = 0.6f;

char ch = 'A';

這些語句就在讓計算機定義一個浮點數/字符。當然也可以讓計算機定義一個整型,比如:

int a = 30;

這行語句就完成了之前的要求:"定義一個整數30"。為了完成這項工作,大家需要讓計算機清楚這幾件事情:

1. 要定義的是什麼樣的數據類型,把它寫在開頭,比如:

int a = 30;

首先告訴計算機:"定義一個int類型的整數"。計算機(其實是編譯器)看到int之後,就在它所有的信箱中找出4個空閑的格子(4個字節),準備存放要定義的int。

2. 要給大家的信箱起一個名字

如果樓道口的信箱上沒有各家的門牌号,那麼所有的信箱看起來就完全一樣了,郵遞員就無法得知應該把信投到哪個信箱裡。類似地,當在第一步中認領了4個格子之後,也要為這4個格子起一個名字,不然計算機就不知道到哪一個格子當中去存放和尋找要保存的整數;在這裡,例程起了個很簡單的名字:a;

3. 把信件放進信箱(告訴計算機要定義的整數是多少)

在這裡大家想要定義一個整數30,就把它寫在等号的右邊。在C語言中,"="是一種賦值運算符,它表示把右邊的數存到左邊的格子裡。在這個例子中,隻要把30這個值存到a所在的4個格子當中,整個工作就完成了!

計算機二級c 語言基礎知識(計算機等級考試必備之第2章)10

圖 2‑9 定義變量并賦初始值

本節将重點介紹第三步中等号右邊的"0.6f"和"30"這樣的量怎麼寫,這些量被稱為常量——計算機是按一定規則辦事的,它不像人那麼高端,能夠理解各種自然語言。比如人與人之間可以說:

"定義一個整數10的5次方。"

理解起來毫無問題,但是如果和計算機說:

int a = 10的5次方;

那麼很遺憾,計算機是不能理解等号右邊這個值的。

即使換成英文也不行:

int a = 10 to 5;

必須寫成:

int a = 100000;

2.1.4 ASCII碼表

下表為ASCII碼表的可打印字符部分(0 ~ 127),供大家查閱使用,如表2-12所示:

表 2‑12 ASCII碼表

2.1.5 枚舉

枚舉用來給一系列整型常量命名。它的使用方法如下:

enum 枚舉名 {标識符1 = 整型常量1, 标識符2 = 整型常量2, ...}

和宏定義一樣,枚舉中的标識符習慣上也使用大寫字母和下劃線來命名。下面是用枚舉定義十二個月份的例子:

enum month{JAN=1, FEB=2, MAR=3, APR=4, MAY=5, JUN=6,

JUL=7, AUG=8, SEP=9, OCT=10, NOV=11, DEC=12};

這樣的定義比define要方便不少,但是依然有些冗長。幸運的是,在枚舉中,如果不指定标識符的具體值的話,會默認該标識符的值等于前一标識符的值加1。因此可以将上面的定義簡化成:

enum month{JAN=1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC};

更進一步地,如果不指定第一個标識符對應的常量,則它的默認值是0,如例程2-4所示:

例程 2‑4 枚舉的使用

16 /* Enum Project */

17 #include <stdio.h>

18 /* 定義一組常量 */

19 enum Constants {C1, C2, C3 = 4, C4, C5 = 3, C6, C7, C8 = '0', C9};

20 int main()

21 {

22 printf("C1=%d\n", C1);

23 return 0;

24 }

程序的運行結果如圖2-10所示:

計算機二級c 語言基礎知識(計算機等級考試必備之第2章)11

圖 2‑10 枚舉的使用

例程2-4中首先用枚舉定義了一組常量C1到C9,并在Console窗口中輸出常量C1的數值。請大家在編譯和運行該例程之前,先試着猜測C1到C9這九個常量的數值。

常量

2.1.6 整型常量

最簡單的整型常量是十進制整數,其聲明規則為:

[正負号][十進制整數][後綴]

如果聲明的是一個十進制正整數,則[正負号]一項中的正号可寫可不寫。[十進制整數]中,除非聲明的常量是0,否則不要以0開頭(即不要出現0123這樣的數,而應直接寫123)。[後綴]可以有以下幾種取值(大小寫随意):

表 2‑13 整型常量的後綴

如果沒有後綴,且常量的大小沒有超出int的範圍,則默認該整型常量的類型是int。

請參考下面的幾個例子以理解整型常量:

表 2‑14整型常量舉例

在十進制當中,15,015和0015都是同一個值,但是如果寫:

int a = 15;

int a = 015;

這兩個值是不一樣的。可以動手試試下面的程序:

在Visual Studio中新建一個C工程,如例程2-5所示:

例程 2‑5 八進制整數

9 #include <stdio.h>

10 int main()

11 {

12 int a = 015;

13 printf("%d\n", a);

14 return 0;

15 }

程序運行結果如圖2-11所示:

計算機二級c 語言基礎知識(計算機等級考試必備之第2章)12

圖 2‑11八進制整數

大家會發現最後輸出了13。這是因為0打頭的整數會被解釋成八進制數,而不是十進制數。而八進制的15剛好就是十進制的13。

2.1.7 實型常量

實數常量也叫浮點數常量,它表示的是一個浮點數的值。實數常量有兩種表示方式:十進制小數表示和指數表示。當用十進制小數表示時,實數常量的格式為:

[正負号][十進制整數部分][小數點][十進制小數部分][後綴]

其中小數點必須有,正負号一項中如果是正數的話正号可以不寫,十進制整數部分或十進制小數部分為0的話可以省略不寫,但如果同時為0的話則至少要保留一個,後綴部分隻有兩種取值(大小寫不限):F表示該常量的類型為float,L表示該常量的類型為long double。如果沒有後綴,那麼默認常量的類型為double。以下是一些正确的實型常量如表2-15所示:

表 2‑15 實數常量舉例

聲明實數常量的另一種方法是指數表示法,其聲明規則為:

[十進制實數][指數符号e或E][十進制指數][後綴]

下面逐個解釋各個部分的含義:

1. [十進制實數]可以是一個小數,或者整數。

2. [指數符号e或E]用e或者E表示10的幂,大小寫不限。

3. [十進制指數]必須是整數。

4. [後綴]部分的規則和前述"實型常量的十進制小數表示法"中後綴的規則一緻。

以下是一些正确的聲明方式:

表 2‑16指數表示法常量舉例

簡單地說:可以按照十進制小數的寫法去寫,也可以用指數的形式去寫。在指數形式中,指數必須是整數。

(腳下留心:整型常量和實型常量後綴中的L

在整型常量中,後綴L表示數據類型為long int;而在實型常量中,後綴L表示數據類型為long double。以實型常量0.123L為例:在聲明時,不要把小數點漏掉,否則該常量會變成0123L,這是一個八進制long int類型的整型常量。

2.1.8 字符常量

下面是特别容易和整型常量搞混的字符常量。字符常量是用一對單引号将單個字符括起來的常量,它隻有一種類型——char類型,占用8位1個字節。以下是一些字符常量的例子:

'A':字符常量A。

'B':字符常量B。

'0':字符常量0。

' ': 字符空格。

注意:字符'0'和整數0是不一樣的!如果去查ASCII碼表(下一節提供了ASCII碼表供查閱),就可以看到字符'0'實際上是整數48。

在此前查閱ASCII碼表的過程中應該留意到,在ASCII碼表中,除了可以直接從鍵盤上輸入的字符(如英文字母,标點符号,數字,數學運算符等)以外,還有一些字符是無法用鍵盤直接輸入的,例如表中值為13的回車鍵——無法通過鍵盤直接輸入來定義一個"回車"字符常量,因為當大家在VS中輸入"回車"(鍵盤上的回車鍵)的時候,其實際效果就是在文本編輯器上光标跳到了下一行。為了定義"回車"這個字符常量,需要采用一種新的定義方式:轉義字符。它以反斜杠\開頭,随後接特定的字符。一些常見的轉義字符定義如下:

表 2‑16 部分常見轉義字符表

在Visual Studio中新建一個C工程,如例程2-5所示:

例程 2‑5 ASCII碼與字符

16 /* ASCII Project */

17 #include <stdio.h>

18 int main()

19 {

20 char ch = '\n';

21 printf("%c", ch);

22 return 0;

23 }

程序的運行結果如圖2-12所示:

計算機二級c 語言基礎知識(計算機等級考試必備之第2章)13

圖 2‑12 ASCII字符

請大家試着運行這個程序,看看回車在屏幕上的顯示效果。也可以試試上表中其它的轉義字符。

在上面的"動手體驗"中大家已經了解了利用反斜杠定義字符常量的方法,值得一提的是反斜杠這個字符本身也必須以轉義的方式來定義,否則反斜杠會将後面的單引号解釋為轉義字符而導緻編譯錯誤。

(多學一招:回車和換行的區别

大家應該在電影和電視上見過打字機(不是打印機)這種設備:打字員首先将紙張附着在打字機的滾筒上,當開始打字時,打字員敲擊鍵盤輸入一個字符,打字機的打字頭在紙上打出相應的字符,随後滾筒帶動紙張向左移動,等待打字員的下一次輸入。當打字員輸入完一行即将開始輸入新的一行時,打字員手動将滾筒向右推,使得打字頭回到紙張上新一行的開頭,接着滾筒會将紙張整體向上移動一行。前一個動作被稱為回車(carriage return),後一個動作被稱為換行(line feed)。在現代計算機上,這兩個字符被保留了下來,用作文本文件中的行分隔符,然而,不同的操作系統對于究竟選擇使用回車還是換行作為行分隔符是有分歧的:在Windows操作系統中使用的是"回車 換行"的組合,Unix采用的是"換行",Mac OS采用的是"回車"。下面就以Windows下的文本文件為例向大家展示Windows的行分隔符:

打開記事本,鍵入以下内容,兩行文本用正常的回車鍵分隔,如圖2-13所示:

計算機二級c 語言基礎知識(計算機等級考試必備之第2章)14

圖 2‑13 Windows中的一個文本文件

随後請大家将文本文件保存,注意保存時編碼選擇"ANSI"(它是在ASCII字符集基礎上擴展出的字符編碼,這是Windows中記事本保存文本文件時的默認編碼)。接下來,利用帶有十六進制查看功能的文本編輯器如Sublime Text打開,選擇利用16進制查看該文本文件,如圖2-14所示:

計算機二級c 語言基礎知識(計算機等級考試必備之第2章)15

圖 2‑14 在16進制下查看文本文件

其中0x31是數字1的ASCII碼(十進制49),0x0d和0x0a分别是回車和換行的ASCII碼(十進制分别為13和10),0x32是數字2的ASCII碼。

2.1.9 宏定義

上文中已經介紹了各種類型常量的定義方法。有些時候,希望能夠給常量起一個别名,從而更加直觀地表示常量的具體含義。比如當定義了一個實數常量3.1415926時,希望能夠給這個常量起一個更加易懂的名字PI來方便閱讀和編寫程序。C語言中提供了define指令來解決這一問題。define指令的基本格式為:

#define 别名 常量

其中,"别名"習慣上采用大寫英文字母和下劃線來命名,如"JANUARY"、"MAX_LINE_NUMBER"、"PI"等。下面是一個例子:

#defineFEB 2

在這個例子中,程序給常量2起了一個别名FEB,之後隻要是出現FEB的地方都會被程序認為是2。

define指令所做的事情非常非常簡單:為指令中的"常量"起一個叫做"别名"的名字。在define指令之後的程序中,凡是出現了這個别名的地方,它一般都将被直接替換為對應的常量,如例程2-6所示:

例程 2‑6 #define用法示例

25 /* Define Project */

26 #include <stdio.h>

27 #definePI 3.1415926f

28 int main()

29 {

30 /* 定義圓的半徑為1 */

31 float radius = 1.0f;

32 /* 計算圓的面積 */

33 float area = PI * radius * radius;

34 /* printf輸出語句:圓的面積是*/

35 printf("%f\n", area);

36 return 0;

37 }

程序的運行結果如圖2-15所示:

計算機二級c 語言基礎知識(計算機等級考試必備之第2章)16

圖 2‑15define用法

例程2-6中定義了一個半徑為1的圓,計算圓的面積并輸出。程序利用define指令為常量3.1415926f定義了一個标識符PI,在編譯程序之前,編譯器會将程序中在define指令之後出現的PI直接替換成常量3.1415926f(記住:define是預處理指令,它和include一樣會在編譯整個程序之前被處理掉)。

利用define定義符号常量有以下幾點優勢:

1. 增強程序的可讀性。和冷冰冰的數字相比,像PI這樣的标識符顯然可以提供更多更有意義的信息。尤其是在規模較大的程序中,程序員是很難記住每一個常量的具體含義的,标識符的引入可以給編程中的程序員以有益的提示。

2. 便于對常量進行修改。假設在例程3-3中想要提高程序的計算精度,因此采用一個更加精确的PI值3.141592653589793238463。在引入了符号常量PI之後,隻要将#define指令中原有的PI常量修改為新的值即可。如果沒有引入符号常量,而是在程序中每一處使用了PI值的地方都直接輸入3.1415926的話(這種将常量直接編寫在程序中的方式通常被稱為"硬編碼"),就需要找到每一處3.1415926并進行替換,當一個常量在程序中多次出現時,這樣的修改是非常耗時的,而且還可能導緻常量前後的不一緻,從而引入潛在的錯誤。

變量

2.1.10 變量的定義

在程序運行期間,随時可能産生一些臨時數據,應用程序會将這些數據保存在一些内存單元中,每個内存單元都用一個标識符來标識。這些内存單元我們稱之為變量,定義的标識符就是變量名,内存單元中存儲的數據就是變量的值。

定義變量的語法如下:

變量類型 變量名 = 變量初值;

例如,定義一個int類型的變量sum,并且令它的初始值為0。其示例代碼如下:

int sum = 0;

這條語句的含義是,定義了一個名叫sum的變量,它的數據類型是int。因此,程序在内存中找到4個空閑的字節,并且把整數0寫到這4個字節中。

在定義變量時也可以不給出變量的初值,示例代碼如下:

int sum;

此時隻是告訴了計算機,定義一個int類型變量sum,在内存中分配4個字節的存儲空間,但還沒有為他賦值。此時,變量sum對應的4個字節在内存中的值是完全不确定的。

在程序中,還可以一次定義多個變量,示例代碼如下:

int a, b = 30, c;

上述代碼中定義了三個int類型的變量,并分别起名為a、b和c。不同的變量之間用逗号分隔,語句末尾用分号作為結束,不同的變量可以進行賦值也可以不賦值。

2.1.11 C語言關鍵字

關鍵字是編程語言裡事先規定好特殊含義的詞,有些資料上稱為"保留字"。C89标準規定了如下32個關鍵字。為避免沖突,在命名變量時不應該使用它們,如表2-17所示:

表 2‑17 C89标準中的關鍵字

這些關鍵字無需記憶,隻要了解即可。随着C語言學習的逐步深入,大家會慢慢知道每個關鍵字的獨特作用的。

C99标準新增了五個關鍵字:_Bool、_Imaginary、_Complex、restrict和inline。請同樣在變量命名時避免使用這五個關鍵字。

2.1.12 變量的使用

定義好變量之後,就可以對變量進行操作了,例如,讀取變量的值。在前面的講解中可以看到很多用printf讀取并輸出變量的例子,接下來通過具體的案例來演示如何輸出變量的值,如例程2-7所示:

例程 2‑7輸出變量的值

38 #include <stdio.h>

39 int main()

40 {

41 int a = 30, b = 25;

42 a = b 3;

43 printf("%d\n", a);

44 return 0;

45 }

程序的運行結果如圖2-16所示:

計算機二級c 語言基礎知識(計算機等級考試必備之第2章)17

圖 2‑16輸出變量a的值

例程2-7中,首先定義了兩個變量a和b,然後将b 3的值賦值給a。在計算b 3時,首先去讀取b當前的值25,然後加上3得到28,把28寫給a,最後通過printf語句輸出a當前的值。

1、變量的命名規範

上文提到在使用一個變量之前需要先給變量起好名字。名字當然不是随便起的,C語言對變量名有如下幾條限制:

1. 變量名隻能由字母,數字和下劃線組成,且第一個字符不能是數字。合法的變量名包括:a1,m_buffer,pName等等。

2. 不能使用C語言的保留字:保留字就是C語言自己預先定義好的一些名字,比如之前看到的return,double,int,char,include等等。這些名字C語言自己要使用,如果大家在程序中定義了一個叫做return的int變量,如下所示:

int return;

return;

C語言是分不清楚大家究竟是想返回還是想定義變量的。

盡管有上述兩條限制,程序員可選的變量名還是非常多的,如何為自己的變量起一個好名字也是一門學問。假設想要在程序中求自然數1加到100的和,并這個和存在一個int類型的變量裡,可以叫它aaa,也可以叫它sum,它們都是合法的變量名,但是顯然後者比前者要好得多,因為sum一詞指出了這個變量的含義和作用。

2、常見變量命名法

給變量起一個漂亮又有意義的名字是一門學問。在此向大家介紹兩種常用的命名規則:

匈牙利命名法:匈牙利命名法建議使用一個簡短的小寫字母前綴來标注變量的類型,随後接若幹首字母大寫的單詞來表明變量的作用,比如剛剛的sum,在匈牙利命名法中會被建議命名為iSum:首字母i表示這是一個int類型的變量,Sum指示了這個變量的含義是某些數的和。其他一些常用的前綴包括:

fpSpeed:fp是float point(浮點數)的縮寫,這是一個用來記錄速度的浮點數變量。

strStudentName:str是string(字符串)的縮寫,這是一個用來記錄學生姓名的字符串。

u8Color:u是unsigned(無符号整形)的縮寫,這是一個用來表示顔色的無符号整數。

匈牙利命名法的前綴并沒有嚴格的規定,程序員也可以發明自己覺得合适的前綴。

駝峰命名法:變量名由一系列首字母大寫的單詞組成,比如AccountNumber,FirstName,StudentID等等。也有人将變量的第一個單詞的首字母小寫:accountNumber,firstName,studentID。前者被稱為大駝峰式命名法或Pascal命名法,後者被稱為小駝峰式命名法。

變量的命名法更多地是出于方便程序員閱讀和編程的考慮,編譯器隻認變量名是否合法,而不會管變量名是否"有意義"。對于開發者來說,變量的命名法也沒有高下之分,隻要在自己的程序中做到變量命名法則前後一緻就可以了。

類型轉換

在C程序中,有時候會遇到在兩種不同類型的數據之間進行轉換的情況。比如利用一個float類型的浮點數給double類型的浮點數賦值,或者利用将兩個int整數相加的結果保存在long 類型變量當中。由于不同的數據類型約定了不同的表示數據的方式,因此就需要有一些特定的規則來規定如何在不同的數據類型之間進行轉換。

2.1.13 類型提升

在表達式中,char和short 類型的值,無論有符号還是無符号,都會自動轉換成int 或unsigned int 類型。舉例說明:

char c1=12,c2=108;

c1 c2;

c1和c2都是char型,計算表達式c1 c2會先将c1和c2轉換成int 類型,然後再相加,由于c1和c2是被準換成表示範圍更大的類型,故而把這種轉換稱為"提升"。

不光在表達式中,在函數中也會出現"提升"當作為參數傳遞給函數時,char和short類型會提升成int類型,而float類型則會提升成double類型,如:

char ch= 'a';

printf("ch保存的ASCII碼值:%d\n",ch);

ch是char型,作為參數傳遞給printf函數時,自動提升為int類型,因此不用再将ch強制轉換為int 類型。

2.1.14 類型下降

在賦值語句中,賦值運算符左側的變量是什麼類型,右側的值就要轉換成什麼類型。這個過程可能導緻右側值的類型提升,也可能導緻其類型下降。所謂"下降"是指等級較高的類型被轉換成等級較低的類型,也叫強制類型轉換如下:

int d;

double x=3.1415926;

d=(int)x;//強制轉換

x的級别比d高,因此将x的值賦給d會先将x的值轉換為與d同樣的類型,這将導緻x的值的類型下降(針對x的副本而言),下降可能會丢失數據,因此大部分編譯器會發出警告,為避免發出警告,需要進行強制轉換。另外需要注意的是,假如右值過大,超出了左值的取值範圍,那麼強行賦給左值,會導緻左值溢出。

2.1.15 常用算術轉換

C語言算術表達式的計算,在計算過程中,每一步計算所得結果的數據類型由參與運算的運算對象決定,相同數據類型的兩個對象運算,結果數據類型不變,不同數據類型的運算對象進行運算,結果的數據類型由高精度的運算對象決定。精度的高低:double>float>int。

需要注意的是,數據類型的轉換是在計算過程中逐步進行的,整個表達式結果的數據類型一定與表達式中出現的精度最高的數據相同,但是具體得到數據值是逐步得到的,例如:

int x=1,y=3; double k=1573.267;

x/y*k

這個表達式計算結果的數據類型是double, 計算結果的答案是 0.0。因為在第一步 x/y 的計算中 結果是一個整型數據 0。第二步計算 0 * 1573.267 結果是一個double類型的數據,但數值是0.0。也就是說,算術表達式計算結果的數據類型與運算的優先級沒有關系,一定具有表達式中精度最高的數據類型,但是具體得到數據結果數值,與優先級可就有關系。

2.1.16 賦值中的類型轉換

當賦值運算符兩邊的運算對象類型不同時,将要發生類型轉換,轉換的規則是:把賦值運算符右側表達式的類型轉換為左側變量的類型。具體的轉換如下:

1、 浮點型與整型

将浮點數(單雙精度)轉換為整數時,将舍棄浮點數的小數部分,隻保留整數部分。将整型值賦給浮點型變量,數值不變,隻将形式改為浮點形式,即小數點後帶若幹個0。注意:賦值時的類型轉換實際上是強制的。

2、 單、雙精度浮點型

由于C語言中的浮點值總是用雙精度表示的,所以float 型數據隻是在尾部加0延長為double型數據參加運算,然後直接賦值。double型數據轉換為float型時,通過截尾數來實現,截斷前要進行四舍五入操作。

3、 char型與int型

int型數值賦給char型變量時,隻保留其最低8位,高位部分舍棄。

char型數值賦給int型變量時, 一些編譯程序不管其值大小都作正數處理,而另一些編譯程序在轉換時,若char型數據值大于127,就作為負數處理。對于使用者來講,如果原來char型數據取正值,轉換後仍為正值;如果原來char型值可正可負,則轉換後也仍然保持原值, 隻是數據的内部表示形式有所不同。

4、 int型與long型

long型數據賦給int型變量時,将低16位值送給int型變量,而将高16 位截斷舍棄。(這裡假定int型占兩個字節)。 将int型數據送給long型變量時,其外部值保持不變,而内部形式有所改變。

5、 無符号整數

将一個unsigned型數據賦給一個占據同樣長度存儲單元的整型變量時(如:unsigned→int、unsigned long→long,unsigned short→short) ,原值照賦,内部的存儲方式不變,但外部值卻可能改變。

将一個非unsigned整型數據賦給長度相同的unsigned型變量時, 内部存儲形式不變,但外部表示時總是無符号的。

本章小結

本章主要介紹了學習C語言所需的基礎知識。其中包括C語言中的二進制、基本數據類型、變量和常量的定義,類型轉換等,通過本章的學習初學者能夠掌握C語言程序中如何進行進制轉換,以及正确的定義變量和常量,并根據變量的數據類型不同進行類型轉換等。

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关教育资讯推荐

热门教育资讯推荐

网友关注

Copyright 2023-2025 - www.tftnews.com All Rights Reserved