天天看點

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

需要多位(bit)二進制數才能表示一個大于1的值,具體需要多少位,則取決于數字大小。一個8位的二進制數(一個位元組)可以表示256個數字(0~255)。

16位的二進制數可以表示從0到65?535的值。如果使用一個位元組來傳輸資訊,一共可以傳輸256種可能的組合,足以表示十進制數、大小寫字母,以及其他一些符号。一般情況下,使用ascii(美國資訊交換标準碼)編碼規範來表示這些字元。

二進制數第0位的權值是2的0次方,第1位的權值是2的1次方,第2位的權值是2的2次方,以此類推。如果第0位是1,那麼它的值是1×20 = 1;如果是0,它的值則是0×20 = 0。如果第1位是1,那麼它的值是1×21=2;如果是0,它的值則是0×21 = 0。如果第3位是1,那麼它的值是1×23=8;如果是0,它的值則是0×23 = 0。

對于16位的二進制數來說,第0位是最低位(least significant bit),第15位是最高位(most significant bit)。圖2-2給出了每一位的權值(也就是說如果該位為1,其他位為0)所代表的十進制數。在所有pic相關的文檔中,第0位指的都是最低位。這也是最常見的表示法,但并不是所有的微控制器都是如此。

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

圖2-2 二進制數轉十進制數的權值

将16位二進制數每一位的值乘以其權值,相加之後就可以将其轉換成十進制數(參見圖2-3)。

讀者可以試着計算下列二進制數字的值:

0000

0001

0010

0011

0100

0101

……

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

圖2-3 二進制轉十進制示例

如果将這些二進制數看成是汽車的裡程表,但是上面隻有0和1兩個數字。當1翻轉成0時,就會進位。這就是數制中的基。

c語言中,在數字前加上0b表示二進制數。例如,給x指派為6,用二進制表示就是:

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

十進制就是我們經常使用的計數方式。每個數位可以使用0~9這十個符号表示不同的數值。c語言中我們這樣使用它:

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

稍後再來介紹“類型”。這裡我們注意到,編譯器将會把123當作1位元組來處理,因為一個位元組足以存儲123。如果由于某種原因,程式員需要編譯器将其當作兩個位元組,那麼可以在數字後加上l(long):

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

對于已經超過1位元組的數字(如1000),則不需要在後面加上l。

數字後面也可以加上u,以說明它是一個無符号數。

上面說的這些數字都是無符号數。8位的記憶體單元可以存儲的數字範圍是0~255。但是在c語言中也需要負數。此時,用某個位表示符号位,0表示正數,1表示負數。在計算機中,負數使用補碼來表示。之是以使用補碼是為了使加減法運算都可以用一種電路實作。-2的補碼是:

11111110

加1後等于:

11111111

這也是-1的補碼,也就是我們期望的結果:-2 + 1 = -1。如果再加1就等于:

符合我們的期望。

再回想一下前面的裡程表例子,初始全是0,如果想要表示-1,就需要向後撥1,這時裡程表上就全是1了。

在c語言中,用下面的方法表示有符号數:

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

十六進制使用16個符号計數:0~9以及a~f。這次可以設想下我們的裡程表上每位有16種符号。使用十六進制數可以很好地幫助程式員了解每一位的值;如果使用二進制,就會顯得很長,不友善記憶和交流。不像平常(在現實世界中)使用的十進制那樣,十六進制和二進制之間可以直接換算。每個十六進制位占用4個比特位。十六進制的每個數字都可以用一個4比特的二進制數表示(見圖2-4)。許多程式員都能記住每個十六進制數字對應的二進制數,這樣他們就可以直覺地看到十六進制數對應的二進制形式了。例如,期望傳送過來的數字是aa(0b1010 1010),但是得到的卻是55(0b0101 0101),我們立即就知道資料在傳輸中錯亂了一位。

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

圖2-4 十六進制轉換圖

在本書中,十六進制數有時被用來描述記憶體中的位址,有時被用來表示資料。使用十六進制并不難,隻需要多加練習即可。

一個位元組可以用兩位十六進制數表示。十六進制數通常排成兩位或四位一組,左邊是最高位。

本書中使用0x來表示十六進制數。最近也有些微晶片文獻中使用“h”來表示十六進制數(但在c語言中不合法)。

圖2-5給出了一些十六進制、二進制和十進制之間的換算結果。

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

圖2-5 數制轉換示例

顯然,0xffff(某些微控制器程式存儲器的位址空間的最大值)比寫成1111 1111 1111 1111 或者65535要簡單得多。

在c語言中,十六進制數的前面需要加上0x。例如,給x指派26(十進制)或者1a(十六進制):

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

八進制的基是8個分别代表不同數值的數字(0~7)。和十六進制一樣,八進制也可以直接換算成二進制。每個八進制位占3個比特位。在十六進制流行之前,早期的計算機使用的是八進制,因為可以直接使用開關輸入指令(見圖2-6)。雖然已經很少有人再用八進制了,但是c語言仍就将其納入自己的文法中。

在c語言中,數字前加上0表示該數字是一個八進制數。例如,給x指派10(十進制)或者12(八進制):

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

注意,等号後面的是數字0而不是字母o。即使你不打算用八進制,這裡也要特别注意,在十進制的數字前加上0就變成了八進制。上面那行代碼中,x是10,而不是12。

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

圖2-6 dec pdp-8的前面闆

上面講到的都是整數,沒有小數點。浮點數指的是有小數點且小數點可以在很大範圍内移動的數字。12.34就是一個典型的浮點數,在計算機内部用1234×10-2來存儲它。這兩部分分别稱為尾數和指數,編譯器規定了這兩部分的範圍。在小型pic裝置中,ccs c編譯器使用24位尾數和6位指數,再加上尾數和指數的兩個符号位,一共32位。也就是說下列數字可以表示成:

1.23 123×10-2

0.000?000?000?000?123 123×10-15

12?300?000?000?000?000 123×1014

但是數字:

1?200?000?000?000?003 1?200?000?000?000?003×100

隻能轉換成:

1?200?000?000?000?000 120×1014

因為尾數部分沒有那麼長來容納這麼多有效位。

由于浮點數在計算機中其實是一種不精确的表示,存在舍入誤差,是以在比較兩個浮點數時,不能使用小于和大于,而隻能用等于和不等于。

在c語言中,浮點數有三種表示方法:

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

定點數的小數點是固定的。在計算機中不需要存儲小數點的位置,不需要區分尾數和指數,隻需要像整數一樣存儲,編譯器和處理器會使用約定的小數點位置來處理定點數。這種計算機結構簡單,造價低廉。在程式中這樣表示:

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

程式設計中的字元包括數字(0~9)和字母(a~z)以及标點符号和特殊符号。c語言中,每個字元都可以對應到0~255中的一個數字。而ascii碼就是一套用8比特位來表示字元的标準編碼。

ascii表中一共有256個字元,附錄a給出了完整的ascii表。從表中可以看出,字母a在記憶體中是65。c語言中的字元在代碼中需要用一對單引号括起來。由于c語言在類型轉換時比較寬松(類型轉換,同一個字元在編譯器中可以有不同的解釋),是以在代碼中可以使用65來代替‘a’。字元指派示例:

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

有些字元在鍵盤上找不到,可以用“轉義”來表示它們。反斜線用來表示轉義字元。如果想要使用反斜線,必須連續輸入兩個反斜線:\。如果要使用十六進制數表示字元,也要用到“轉義”:'x41'(也就是字母'a'),用八進制表示就是'101'。表2-1列出了一些特殊字元。

表2-1 c語言轉義字元

n 換行——x0a v 垂直制表——x0b

r 傳回——x0d ? 問号——x3f

t 制表——x09 ’ 單引号——x22

b 倒退——x08 ” 雙引号——x22

f 換頁——x0c \ 反斜杠——x5c

a 響鈴——x07

注意,在使用反斜線時前面必須再加上一個反斜線表示這是個轉義字元,有時還需要使用單引号或雙引号。例如,下面這幾行代碼的功能是一樣的,都是給變量c指派一個換行符。

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

将一組字元連續存儲在記憶體中,并以空字元'000'結尾,就構成了c語言中的字元串。例如:

“abcd” 在記憶體中的内容

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

我們使用雙引号來定義字元串。上面的字元串中,一共有4個字元,但是在記憶體中占用5個字元(最後一個0表示字元串結尾)。是以,該字元串需要5位元組的記憶體。

字元串中也可以包含特殊字元,例如:

"a0x42111d" 相應記憶體中的内容

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

上面的字元串也占用5個位元組,其中字母b和c分别用十六進制和八進制表示。在c字元串中經常會用到r(回車)和n(換行)。windows檔案系統在檔案中使用這兩個字元表示回車換行。下面的字元串表示檔案中或者大多數程式終端顯示的一行:

"line onern" 相應記憶體中的内容

還有個有意思的特性,如果代碼中兩個字元串之間僅存在空白字元,那麼它們将被當作一個大的字元串處理。例如:

"abcd" "efgh"

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

會被當作:

"abcdefgh" 在記憶體中的内容

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

注意,這裡丢掉了d後面的0,因為兩個小字元串被當作一個大字元串處理,在記憶體中占9個位元組。

當需要将一個很長的字元串分開寫到多行中時,以及在稍後章節中将介紹的宏,都會用到這個特性。

每個c語言表達式都可以得出一個數值。使用關系運算符的表達式的值可能是true(1,真)或false(0,假)。關系表達式通常用在if或while語句中:

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

如果表達式的結果為true,則會執行if之後的語句。如果表達式的結果為false,則不會執行if後面的語句。關系表達式a<b></b>

<b></b>

<b>前面已經用過這種簡單的資料聲明:</b>

<b></b><b></b>

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

還可以在它前面加上關鍵字const來聲明一個符号常量:

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

定義好符号常量之後,在程式中可以直接使用常量名來代替該常量。還有一種更常用的定義常量的方法:

《嵌入式C程式設計:PIC單片機和C程式設計技術與應用》一2.2 C常量文法

這個預編譯指令在編譯前會将所有的level替換成10。下一章中會詳細介紹預編譯指令。

使用const的好處在于可以指定變量類型(如上面的int)。通常,程式員使用const定義符号常量時需要将變量名全大寫。

繼續閱讀