2.3 基本類型數據
2.3.1 整型數據
1.整型數據類型標識符
整型數據分為基本整型、短整型、長整型和無符號型4種。
① 基本整型(簡稱整型):類型標識符為int。
② 短整型:類型標識符為short int或short。
③ 長整型:類型標識符為1ong int或1ong。
④ 無符號型:表示不帶符號的整數。
無符號型整數又可分為以下3種。
① 無符號整型:類型標識符為unsigned int。
② 無符號短整型:類型標識符為unsigned short。
③ 無符號長整型:類型標識符為unsigned 1ong。
C語言標準沒有具體規定以上各類數據所占的內存字節數,不同C編譯系統有不同的規定。表2.2所示為在VC++6.0編譯環境中各種整型數據所占的內存字節數和取值范圍。
表2.2 整型數據類型所占內存字節數和取值范圍
2.整型變量的定義
根據表2.2給出的整型數據類型標識符可以定義相應的整型變量。例如:
int i,j,k; /* 定義變量i,j,k為整型 */
unsigned short n,m; /* 定義變量n,m為無符號短整型 */
long p,l; /* 定義變量p,l為長整型 */
當按上述方法定義變量時,編譯系統僅為所定義的變量分配了存儲單元,而沒有在存儲單元中存放任何數據,此時的變量不能正確使用,因為變量中的值無意義。
C語言允許在定義變量的同時,對該變量預先設置初值,也稱變量的初始化。例如:
int i1=6; /* 定義i1為整型變量并賦初值6 */
也可以為被定義變量的一部分賦初值,例如:
int i1,i2,i3=10;
定義i1、i2和i3為整型變量,并只對i3初始化,值為10。
如果對幾個變量賦以同一個初值,不能寫成:
int a=b=c=8;
而應寫成:
int a=8,b=8,c=8;
3.整型常量
整型常量簡稱為整數或整常數。C語言程序中整型常量有以下3種表示形式。
① 十進制整數:按通常習慣的十進制整數形式表示,例如,102、-98、0等。
② 八進制整數:以數字0開頭的八進制數符串,數字0是八進制整數的前綴,八進制數符為0~7。八進制數通常是無符號數。例如,025(表示十進制數21)、0400(表示十進制數256)。
③ 十六進制整數:以0x或0X開頭的十六進制數符串,0x或0X是十六進制整數的前綴,十六進制數符為0~9和a~f(或A~F),其中a~f(或A~F)對應于十進制數10~15。十六進制數通常是無符號數。例如,0x14(表示十進制數20)、0xFFFF(表示十進制數65535)。
整型數又分為長整型數、短整型數和無符號整型數。長整型數在表示上與其他整型數的區別是加后綴L或l。所謂后綴是指在數字后面加寫的字母,如1234L、0X2abL等。無符號數的后綴是U或u,如7543U、0125u等。前綴和后綴可同時使用以表示不同類型、不同進制的整型數。例如,03456LU表示八進制無符號長整型數。
在程序中出現的整數根據前綴來區分各種進制數,根據后綴來區分不同類型,因此在書寫常數時不要把前綴和后綴弄錯造成結果不正確。
2.3.2 實型數據
1.實型數據類型標識符
實型數據有單精度型和雙精度型兩種。
● 單精度型:類型標識符為float。
● 雙精度型:類型標識符為double。
在VC++6.0中,實型數據占內存大小、取值范圍和有效數據位數如表2.3所示。
表2.3 實型數據類型占內存大小、取值范圍和有效數據位數
與整型數據的存儲方式不同,實型數據是按照規范化的指數形式存儲的。所謂規范化的指數形式是指其尾數部分為純小數,即小數點前整數部分小于1,小數點后的第1位大于0。
2.實型變量的定義
根據表2.3給出的實型數據類型標識符可以定義相應的實型變量,并可在定義時賦初值。例如:
float f,f1=2.5; /* 定義f、f1為單精度實型變量,并為f1賦初值2.5 */
double d; /* 定義d為雙精度實型變量 */
3.實型常量
實型常量即實數,又稱浮點數。在C語言中實型數只有十進制形式,可以用十進制小數形式或十進制指數形式表示。
(1)十進制小數形式
一般由數字和小數點組成(必須有小數點,但小數點前后的 0 可以省略)。例如, 0.246,.246,246.0,246.,0.0等都是正確的小數表示形式。
(2)十進制指數形式
由尾數、字母e或E及指數部分組成。具體格式如下所示:
尾數e指數部分 或 尾數E指數部分
字母e或E左邊部分的尾數可以是“整數部分.小數部分”形式,也可以只有整數部分不含小數點和小數部分,或者只有小數部分前面含有小數點而不含整數部分。指數部分必須為整數,可以是正的,也可以是負的。例如,下面指數形式都是正確的:
135e3 124e-2 -12.12e-5 .135E4 0e0
而下面的指數形式是錯誤的:
e2 3.5e1.5 .e e5 e
2.3.3 字符型數據
1.字符型數據類型標識符
字符型數據的類型標識符為char,在內存中存儲一個字符型數據需要1個字節。
2.字符型變量的定義
使用字符型數據類型標識符char可以定義字符型變量,并可在定義時賦初值,例如:
char c1,c2='A'; /* 定義兩個字符型變量c1、c2 ,并給c1賦初值'A' */
3.字符型常量
C語言中,一個字符型常量代表ASCII字符集中的一個字符。在C語言程序中字符型常量有以下兩種形式。
① 用一對單引號(即撇號)括起來的單個字符。例如,'b'、'Y'、'9'、'('、'y' 等都是合法的字符型常量。
② 用一對單引號(即撇號)括起來的以一個反斜杠(\)開頭的轉義字符,形如'\n','\t'等,意思是將反斜杠(\)后面的字符轉變成另外的意義。例如,'\n'不代表字母n而是作為換行符。像換行這種非顯示字符難以用一般形式的字符表示,所以C語言規定用轉義字符這種特殊形式表示。常見的以反斜杠(\)開頭的轉義字符見表2.4。
表2.4 轉義字符表
表2.4中最后兩行用ASCII碼(八進制數或十六進制數)表示一個字符,即它將字符的ASCII碼值轉換為對應的字符。例如,'\103'代表字符C,'\012'代表換行,'\376'代表圖形字符■??梢姡褂帽?.4中的表示方法可以表示任何可輸出的字母字符、專用字符、圖形字符和控制字符。請注意,'\0'或'\000'代表ASCII碼為0的控制字符,即“空操作”字符,它可被用在字符串中。
【例2.2】 字符型常量的輸出。
程序代碼如下:
#include "stdio.h"
main( )
{
printf("Hello!\thow are you?\nI\'m fine!\n");
printf("This is a cup\b\b\bpen.\n");
printf("A,\101");
}
該程序中3次調用printf( )函數,直接輸出雙引號內的各個字符。請注意其中的轉義字符。第1個printf( )函數先從第一行左端開始輸出“Hello!”,然后遇到“\t”,它的作用是跳格,即跳到下一個輸出位置,在所用系統中,一個輸出區占8列。下一輸出位置從第9列開始,故從第9列開始輸出“how are you?”。下面遇到“\n”,代表回車換行,返回到下一行最左端(第1列),輸出字符“I”,然后遇到“\'”,表示輸出“'”,接著輸出“m fine”。下面是“\n”,作用是“回車換行”,即光標被移到下一行第一個字符位置。
第2個printf( )函數先輸出字符“This is a cup”,后面遇到3個“\b”,“\b”的作用是“退一格”,因此“\b\b\b”的作用是使當前輸出位置回退3格到“c”的位置,接著輸出“pen.”。最后是“\n”,即“回車換行”。
第3個printf( )函數先輸出“A,”,然后遇到“\101”,它的作用是輸出ASCII碼(八進制數101)所對應的字符,即“A”字符。
程序運行后在顯示屏上最后看到的結果是:
Hello! how are you?
I'm fine!
This is a pen.
A,A
注意:第2次調用printf( )函數時,先輸出“This is cup”,退3格后再輸出“pen.”,“pen.”將取代原來的“cup”。程序執行時在屏幕上看不到“cup”。實際上,屏幕上完全按程序要求輸出了全部的字符,只是因為在輸出前面的字符后很快又輸出后面的字符,在人們還未看清楚之前,新的字符已取代了舊的字符。
4.字符型數據在內存中的存儲形式
字符型變量存放一個字符,實際上并不是把該字符本身存放到內存單元中去,而是將該字符的ASCII碼(ASCII碼對照表見附錄C)存放到存儲單元中。例如,字符'A'的ASCII碼為65,'\n'的ASCII碼為10,則程序段:
char c1,c2;
c1='A';c2='\n';
執行后,在內存中變量c1和c2的值如圖2.3所示。
因為在內存中,字符數據是以ASCII碼的形式存儲的,它的存儲形式與整數的存儲形式類似。因此,在C語言中,字符型數據可以與整型數據混合使用。C語言允許對整型變量賦予字符值,也允許對字符變量賦予整型值。一個字符型數據既可以以字符形式輸出,也可以以整數形式輸出。以字符形式輸出時,需要先將存儲單元中的ASCII碼轉換成相應的字符,然后輸出。以整數形式輸出時,直接將ASCII碼作為整數輸出,也可以對字符數據進行算術運算,此時相當于對它們的ASCII碼進行算術運算。
【例2.3】 字符型數據的輸出。
程序代碼如下:
#include "stdio.h"
main( )
{
char c1; /* 定義c1為字符型變量 */
c1=65;
printf("%c,%d\n",c1,c1); /* c1以字符型和整型兩種格式輸出 */
}
程序運行結果為:
A,65
該程序中c1被定義為字符變量。但在第5行中,將整數65賦給了c1,就是將整數65直接存放到c1的內存單元中。程序的第5行也可用以下語句等價代替:
c1='A';
該語句在執行時,系統首先要將字符'A'轉換成其對應的 ASCII 碼值 65,然后再存放到cl的內存單元中。二者作用是相同的。第6行將按字符型和整型兩種格式輸出變量c1的值。其中“%c”是輸出字符的格式符?!?d”是輸出整數的格式符。有關輸出數據的格式符詳見第3章。
注意:字符型數據只占一個字節,所以它只能存放0~255范圍內的整數。C語言對字符型數據的這種處理增加了程序設計的自由度和靈活性。例如,實現英文字符的大小寫轉換、數字字符和數字的相互轉換等就變得非常方便。
【例2.4】 編寫程序實現英文字符的大小寫轉換。
分析:因為英文字母大小寫之間的ASCII碼值相差32(參見附錄C),即a'-'A'=32,所以很容易通過C語言程序實現英文字符的大小寫轉換。
程序代碼如下:
#include "stdio.h"
main( )
{
char c1;
c1='a';
printf("%c,%c\n",c1,c1-32);
}
程序運行結果如下:
a,A
【例2.5】 編寫程序實現數字字符和數字的相互轉換。
從附錄C可以看出,數字字符0的ASCII碼值為48,數字字符1~9的ASCII碼值為49~57,可以很容易地實現數字字符和數字的相互轉換。程序代碼如下:
#include "stdio.h"
main( )
{
char c1,c2;
c1='1';
c2=49;
printf("%c,%c\n",c1,c2);
c1=c1-'0';
c2=c2-'0';
printf("%d,%d\n",c1,c2);
}
程序運行結果如下:
1,1
1,1
注意:程序運行后,第1條printf語句輸出的是兩個字符1,而第2條printf語句輸出的則是兩個數字1。請大家思考,如果把這兩條語句互換位置,結果會是什么?
2.3.4 字符串常量
字符串常量是由一對雙引號(" ")括起來的字符序列。雙引號是字符串常量的定界符。在組成字符串的字符序列中若有雙引號時應使用轉義字符“\"”來表示。字符串的長度為字符序列中字符的個數,不包括兩邊的雙引號。
例如:
"It is fine day." /* 長度為15 */
"12345678.09" /* 長度為11 */
"$10000.00" /* 長度為9 */
"" /* 引號中有一個空格,長度為1 */
"" /* 引號中什么也沒有,長度為0 */
"a" /* 引號中有一個字符a,長度為1 */
因為字符串長度的不確定性,所以字符串常量在內存中存儲時,系統自動在每個字符串常量的尾部加一個字符串結束標志字符“\0”(“\0”是一個ASCII碼為0的“空操作”字符,它不引起任何控制動作,也不是一個可顯示的字符),以便系統據此判斷字符串是否結束。前面已提到,在內存中存儲單個字符需要1個字節,因此,長度為n的字符串常量,在內存中要占用n+1個字節的存儲空間,前n個字節存儲組成字符串的n個字符,最后1個字節存儲字符串結束標志“\0”。
例如,"hello"在內存中的存儲形式是(字符對應的ASCII碼值):
printf("hello");
執行此語句時從左到右一個字符一個字符地輸出,直到遇到最后的'\0'字符,表示字符串結束了,停止輸出。另外,在書寫字符串時也不必加'\0',否則就會畫蛇添足。
了解了這一點,就可以理解字符串常量"b"和字符型常量'b'的區別了。
存儲字符型常量'b'只需要1個字節: