官术网_书友最值得收藏!

2.4 常量

常量是在程序運行過程中值不發生改變的數據。

在C程序中,為了能給變量直接賦初值或用數值參與運算,經常需要使用由各種數碼組成的不同進制的數據(如整數、實數等)以及字符、字符串等,這類數據通常能直接從其字面形式即可判別其類型,稱為字面常量,或稱為直接量。如1,20,0,-6為整數, 1.2,-3.5為實數,‘a’,‘b’為字符,“C語言”為字符串等。

還有一種情況是C程序中可能會多次使用同一個數值,比如常數π,與其每次書寫時都寫上3.141 592 65,不如用一個標識符來代替該數值,即標識符常量,有時又稱為符號常量。由于標識符總比數值常量本身更具意義,因而在程序中使用標識符常量不僅可以提高程序的可讀性,而且在代碼中修改常量也極為方便,并有助于預防程序出錯。

下面來介紹各種不同類型的常量。

2.4.1 整數

整數,即沒有小數點的數,由于可以有不同進制,因而為了讓編譯器能識別,需要按下列規則來書寫:

(1)對于十進制整數,直接書寫其數碼,如34,128等。

(2)對于八進制整數,在書寫數碼前要以數字0開頭,如045,即(45)8,表示八進制數45,等于十進制數37;-023,即(-23)8,表示八進制數-23,等于十進制數-19。注意:八進制的數碼是0,1,2,3,4,5,6,7。

(3)對于十六進制整數,在書寫數碼前要以0x或0X開頭,如0x7B,即(7B)16,等于十進制的123,-0X1a,即(-1a)16,等于十進制的–26。注意:十六進制的數碼是0~9,A~F(a~f)。

需要說明的是,為了能使編譯器知道程序中指定的整數是一個具體的整數類型,還可在一個整數中添加類型后綴(它們是由類型名的首字母構成的),其規則如下:

(1)以L或其小寫字母l作為后綴的整數表示長整型(long)整數,如78L,496l, 0X23L,023l等都是合法的長整數。

(2)以U或u作為后綴的整數表示無符號(unsigned)整數,如2100U,6u,0X91U, 023u等都是合法的無符號整數。

(3)以U(或u)和L(或小寫字母l)的組合作為后綴的整數表示無符號長整型(unsigned long)整數,如23UL,23ul,23LU,23lu,23Ul,23uL等都是合法的無符號長整數。

(4)默認時,如果一個整數沒有添加后綴,則可能是int或long類型,這取決于該整數的大小。

2.4.2 實數

實數浮點數,為了讓編譯器能識別它們,在書寫時應遵循下列規則:

(1)對于十進制實數,由于它們在形式上和十進制整數的區別是小數點,因此在書寫實數時必須有且僅有一個小數點,但不允許出現單獨一個小數點。例如,0.12,.12,1.2, 12.0,12.,0.0都是合法的實數。

(2)對于指數形式的實數,為了能區別十進制整數和實數,C語言引入特征符E或e,用來表示科學計數法中的10,并強調E或e后面的指數必須是整數。例如,1.2×109,則應寫成1.2e9或1.2E9。由于引入特征符E或e后,指數形式的實數在書寫格式上已與十進制整數和實數不一致了,故特征符E或e前面的數字是否有小數點并不重要,但E或e前面必須有數字,否則以E或e字母開始的實數會被編譯器優先識別成一個合法的標識符。簡單地說,字母E或e前必須有數字,且E或e后面的指數必須是整數

同樣,若要指定實數的具體類型,還必須在實數后面指定類型后綴符:

(1)F或f后綴來表示單精度浮點數(float)。例如,1.2f,1.2E5f等都是合法的單精度浮點數。

(2)指定L或小寫字母l后綴來表示長雙精度浮點數(long double),若沒有后綴,則表示默認的雙精度浮點數(double)。例如,1.2L是合法的長雙精度浮點數,而1.2默認是double型。

注意:在書寫各種形式的整數或實數時(包括后綴),整個常量中不能出現空格,否則將因空格是詞法中的分界符而導致編譯器對詞義的解釋出現不同的結果。例如,1.2 f,編譯器會解釋成“1.2”和“f ”這兩個詞,從而使“f ”標識符因未先定義而變成不合法的。

由于閱讀時,書中的空格難以看出,故用符號表示一個空格,本書做此約定。

2.4.3 字符常量和轉義字符

在C語言中,用一對單引號來作為區分字符與整數、實數的特征符。這就是說,用一對單引號括起來的字符稱為字符常量或直接稱為字符,如‘B’,‘b’,‘%’,‘ ’等都是合法的字符,但若只有一對單引號‘ ’,一般作為空字符處理。需要說明:

(1)字符在計算機內是將其編碼值以整型格式來存儲的,由于大小寫字母的編碼值不同,因此是兩個不同的字符。例如,‘B’和‘b’是兩個不同的字符。

(2)由一對單引號指定的字符通常是指單字節字符,例如‘AB’,‘語’,‘12’等都不合法。

(3)由于在程序代碼中,編碼值大于127的擴展ASCII碼字符無法直接輸入,為了能使用這些字符,C語言允許通過使用“\”引導符,并指定1~3位八進制數或X(包括小寫x)后跟1~2位十六進制數來表示相應編碼值的字符。例如,‘\101’和‘\x41’都是表示編碼值為65的字符‘A’;若為‘\0’,則表示ASCII碼值為0的字符,這樣的字符稱為空字符

在C語言中,含有“\”引導符的字符還有很多,例如,前面程序中的‘\n’,它代表按Enter鍵換行,而不是表示字母n。這種將反斜杠“\”后面的字符轉換成另外意義的方法稱為轉義表示法,‘\n’稱為轉義字符。“\”稱為轉義字符引導符,單獨使用沒有任何意義。若要表示反斜杠字符,則應為‘\\’。表2.2列出了常用的轉義字符。

表2.2 常用轉義字符

在這些轉義字符中,除了前面表示相應編碼值字符的作用外,有的是將C語言本身特征符轉化成原來的一般字符含義,如‘\'’(單引號)、‘\"’(雙引號)、‘\\’(反斜杠)和‘\?’(問號)等;有的是用來轉換成輸出格式的操作(以后還會討論),如‘\r’(回車)和‘\t’(水平制表)等。需要強調:

(1)不是每個以轉義法表示的字符都是有效的轉義字符,當C編譯器無法識別時,就會將該轉義字符解釋為原來的字符。例如:‘\A’和‘\N’等雖都是形式上合法的轉義字符,但卻都不能被C編譯器識別,此時‘\A’就是‘A’,‘\N'就是‘N’。

(2)注意0,‘0’和‘\0’的區別:0表示整數,‘0’表示數字0字符。‘\0’表示ASCII碼值為0的字符。

2.4.4 字符串常量

在C語言中,字符串常量是由一對雙引號括起來的字符序列,簡稱字符串。字符串常量中除一般字符外,還可以包含空格、轉義序列符或漢字等其他字符。例如:

“Hello, World!\n”
“C語言”

等都是合法的字符串常量。字符串常量包含的字符個數稱為字符串長度。若僅有一對雙引號“ ”,則這樣的字符串常量的長度為0,稱為空字符串

書中表示字符串的一對雙引號“ ”是漢字字符,在程序代碼中是不可以的,它們只能用"來表示;類似地,一對單引號‘’也是漢字字符,在程序代碼中也只能用'表示。

顯然,在字面常量中,雙引號是字符串常量用于區分其他數值常量的特征符,如果需要在字符串中出現雙引號,則必須用轉義字符‘\"’來替換表示。例如:

“Please press \"F1\"to help!”

這個字符串被解釋為

Please press "F1" to help!

要注意字符串的機內格式與整型、實型和字符型等數據類型有著本質的區別。對于數值來說,其數據類型確定了它所占內存空間的大小。也就是說,當操作這些數值時,它們所需的內存空間的大小也是確定的。而字符串則不然,由于不同的字符串所包含的字符個數不一樣(每個ANSI字符都要占1字節),因而不同字符串所需的內存空間的大小也各不相同。正因為如此,C語言才沒有也無法有字符串的基本數據類型。

那么怎樣才能確定字符串操作時所需內存空間的大小,并保證字符串在內存空間中存取的正確性呢?

不同高級語言對上述問題的解決有著不同的方式,C語言采用以null為結尾的方式。其中null是指空字符,等價于‘\0’,即值為0的字符。也就是說,C語言對于字符串存儲操作,是將字符串中的字符依次存放在內存空間,并在其后再存入一個‘\0’字符。同時將‘\0’字符作為字符串所占內存空間的結束標志,稱為字符串的結束符。當字符串從內存空間中依次提取時,首先判斷取出的字符是否為結束符,若是,則字符串提取結束,從而保證了字符串存取的正確性。

可見,字符‘a’和字符串“a”有著本質區別:存儲時,字符‘a’僅占1字節,“a”則占2字節,因為“a”除了字符a需要1字節外,字符串結束符‘\0’還需1字節,如圖2.6所示。

圖2.6 “a”和‘a’的區別

需要說明:

(1)由于C語言字符串的存儲格式是以‘\0’為結尾的,也就是說,若在字符串中指定‘\0’,則這樣的字符串的長度和字節大小各為多少呢?例如,“AB\CD\t\0\n”。

顯然,當字符串存入內存時,系統會將其所包含的所有的字符連同結束符‘\0’一起依次存放,每個ASCII字符占1字節,需要8字節的內存空間,如圖2.7所示。但提取時,由于先遇到第一個‘\0’字符,C語言就會將其視為結束標志,提取出來的字符串是第一個‘\0’前的字符序列,即“AB\CD\t”,顯然該字符串的長度(字符個數)為5。

圖2.7 字符串存儲

(2)要注意字符串“AB\CD\t\0\n”中的轉義特征符‘\’,它必須與后跟的字符構成轉義字符,而不論構成的轉義字符是否是有效的轉義字符。例如,字符串中的‘\C’就是一個字符,千萬不要將‘\’和‘C’看做兩個字符。

2.4.5 標識符常量

與變量相似,標識符常量在使用前同樣需要先進行聲明。在C語言中,標識符常量包括const修飾的只讀變量、#define定義的常量及enum類型的枚舉常量等3種形式。考慮到以后還要對enum類型的枚舉常量進一步討論,故這里僅討論#define定義的標識符常量以及const修飾的只讀變量。

1.#define標識符常量

在C語言中,允許程序用編譯預處理指令#define來定義一個標識符常量。例如:

#define   PI  3.14159265

這條指令的格式是#define后面跟一個標識符,再跟一串字符,中間用空格隔開。由于它不是C語言的語句,因此行尾沒有分號

在程序編譯時,編譯器首先將程序代碼中所有“PI”這個詞用“3.14159265”來替換,然后再進行代碼編譯,故將#define稱為編譯預處理指令。#define又稱為宏定義命令,上述定義的PI稱為宏名。

【例Ex_PI.c】 用#define定義符號常量

#include<stdio.h>
#include<conio.h>
#define   PI   3.14159
int main()
{
double r=100.0,area;
area=PI*r*r;
printf("The area of circle is %lf\n",  area);
return 0;
}

程序運行的結果如下:

The area of circle is 31415.900000

需要說明的是,#define定義的常量不是真正的標識符常量,因為在編譯預處理完成后,標識符PI的生命期也就結束了,不再屬于程序中的元素名稱。而且,編譯器本身不會對標識符后面的內容進行任何語法檢查,僅僅在程序中與標識符進行簡單替換。例如:

#define  PI  3.141MNP+59

雖是一個合法的定義,但它此時已經失去了一個標識符常量的作用。正因為如此, ANSI/ISO C建議標識符常量都使用const來定義,而不使用#define

另外,#define作為預處理命令,還有一些較為復雜的應用,以后還會進一步討論。

2.const只讀變量

在定義變量時,可以使用關鍵字const來修飾,這樣的變量是只讀的,即變量所綁定的內存空間中的內容是不可修改的,但在程序中對其可以讀取數據。由于不可修改,因而它是一個標識符常量,且在定義時必須初始化。需要說明的是,通常將標識符常量中的標識符寫成大寫字母以與其他標識符相區別。例如:

const  float  PI=3.14159265f;          /* 指定f使其類型相同,否則會有警告錯誤 */

因π字符不能作為C語言的標識符,因此這里用PI來表示。PI被定義成一個float類型的只讀變量,由于float變量只有存儲7位有效位的精度,因此PI的實際值為3.141593。

若將PI定義成double,則全部接受上述數字。事實上,const還可放在類型名之后,如下列語句:

double  const  PI=3.14159265;

這樣,就可在程序中使用PI這個標識符常量來代替3.14159265。例如,將例Ex_PI.c中的語句:

#define   PI   3.14159

改為

const double PI = 3.14159265;
主站蜘蛛池模板: 册亨县| 和林格尔县| 静乐县| 通道| 九寨沟县| 本溪市| 正宁县| 仪征市| 宜都市| 达日县| 牟定县| 鄂尔多斯市| 建昌县| 柘荣县| 信阳市| 内乡县| 绥德县| 西乌| 高平市| 石城县| 桓仁| 兴仁县| 吕梁市| 洛川县| 鄱阳县| 高台县| 仙游县| 北票市| 灌阳县| 五河县| 五峰| 舒兰市| 璧山县| 高邑县| 雷波县| 鄂托克前旗| 渝北区| 大姚县| 温宿县| 巴林左旗| 大新县|