- C語言程序設計同步訓練與上機指導(第三版)
- 時景榮 李立春
- 5060字
- 2020-06-18 18:07:27
第2章 數據類型與數據運算
2.1 要點難點闡述
1.數據類型
(1)基本類型

·枚舉型。(用戶自定義的)
(2)構造類型

·文件:當輸入/輸出的對象是磁盤時,使用文件類型(FILE)。(系統提供的)
(3)指針類型
指針類型是某種類型數據的地址類型。(用戶自定義的)
(4)空類型
不需要數據類型時,使用空類型(void)。(系統提供的)
2.常量
常量是指在程序運行過程中其值不能改變的量。基本類型常量說明如表2-1所示。
表2-1 基本類型常量說明

3.變量
變量是內存的一個存儲單元,存儲單元內的當前值就是變量的值。其值在程序運行過程中可以改變,所以稱為變量。變量必須先定義其數據類型,才能使用。基本類型變量的取值范圍如表2-2所示。
表2-2 基本類型變量的取值范圍

變量定義的一般格式為:
數據類型名 變量表;
其中,變量表中可以含多個變量,各變量之間用逗號分隔,分號標志著定義結束。例如:
int a,b,c;
變量可以在定義的同時初始化(即賦初值)。例如:
int a=1,b=2,c=3;
也可以對部分變量初始化。例如:
int a,b,c=5;
注意:在程序設計時,要根據使用數據的范圍定義適合的數據類型的變量。若定義過大會浪費計算機資源,定義過小可能產生“溢出”或導致數據不精確。
4.數據運算
C語言規定了運算符的優先級別和結合性。在表達式求值時,先按運算符的優先級別高低次序進行運算,同級則按規定的“結合方向”處理。
(1)賦值運算
賦值運算符“=”的左側必須是變量名,右側是任意類型的表達式。
賦值表達式的求解過程:將賦值運算符右側表達式的值送到左側變量所代表的存儲單元中。結合方向是右結合,優先級別較低,只高于逗號運算符。
做賦值運算時,系統對不同類型的數據自動進行類型轉換。
①把實型數據賦給整型變量時,小數部分截去。
②長的數據給短的變量賦值,低位對齊賦值,高位丟失,有可能造成溢出。
③短的數據賦給長的變量,低位對齊賦值。對無符號數高位補0;對有符號數要進行“符號擴展”:即符號位為“0”,高位全補“0”;符號位為“1”,高位全補“1”。
(2)算術運算
①除法運算中,當兩個操作數都是整型時,結果為整型,如1/4結果為0。
②求余運算中,兩個操作數必須都是整型。
③自增/自減運算符的操作數只能是變量。在Turbo C中,若表達式中有自增/自減運算符,則應先掃描每一個變量的當前值,然后再計算表達式的值。例如:
int a=2,b=3,c;c=(++a)*(b--);
先掃描表達式(++a)*(b--),變量a先自增1,即當前值為3,b的當前值為3,所以c的值為3*3=9,然后b自減為2。所以,語句執行結束時a=3,b=2,c=9。
④數學表達式轉換成C語言表達式要注意兩點:一是乘法的乘號不能省略;二是恰當地使用圓括號以保證原來的邏輯關系不變。
(3)關系運算和邏輯運算
①關系運算和邏輯運算的結果都是一個邏輯值,即“真”或“假”。C語言沒有邏輯數據,用“1”代表“真”,用“0”代表“假”。當進行運算時,非0即“真”,0即“假”。
②要注意關系表達式、邏輯表達式的書寫,如數學中的不等式0<x<10,在C語言中應寫成:x>0&&x<10。
③在邏輯表達式的求解中,并不是所有的邏輯運算符都被執行,只是在必須執行下一個邏輯運算符才能求出表達式的解時,才執行該運算符。
如a=0;b=1;c=a++&&b++;,其結果為a=1,b=1,c=0。最后一個賦值語句中賦值號右側的邏輯表達式的求解過程為:邏輯與運算符左側的表達式a++的當前值為0,則整個邏輯表達式值即為0,因此無須繼續計算右側的表達式,a自身增1,0賦給c,運算結束。
再如a=0;b=1;c=++a||++b;,其結果為a=1,b=1,c=1。最后一個賦值語句中賦值號右側的邏輯表達式的求解過程為:邏輯或運算符左側的表達式++a的值為1,則整個邏輯表達式值即為1,因此無須繼續計算右側的表達式,1賦給c,運算結束。
注意:當需要判斷兩個量是否相等時,運算符是由兩個等號“==”組成的“等于”。注意一個等號“=”表示賦值。
(4)位運算
所謂位運算是指二進制位的運算,即運算的單位是二進制的一個位(bit)。
在程序中,若進行位運算的數據不是用二進制表示的,要先轉換成二進制補碼形式再運算,運算后的結果再轉換成要求的進制。位運算有如下幾種:
①按位與運算“&”:兩個對應位均為1時該位結果為1,否則為0。運算的特點:與0相與對應位清零;與1相與對應位保留原值。
②按位或運算“|”:兩個對應位均為0時該位結果為0,否則為1。運算的特點:與1相或對應位置1;與0相或對應位保留原值。
③按位異或運算“^”:兩個對應位不同為1,相同為0。運算的特點:與1相異或對應位翻轉;與0相異或對應位保留原值。
④按位取反運算“~”:就是0變1,1變0。
⑤左移運算“<<”:用來將一個數的各二進制位全部左移若干位,高位溢出舍棄,低位補0。操作數每左移一位,相當于乘以2。
⑥右移運算“>>”:用來將一個數的各二進制位全部右移若干位,低位舍棄。若無論操作數是正還是負都高位補0,稱為“邏輯右移”;若操作數為正高位補0,為負高位補1,稱為“算術右移”。操作數每右移一位,相當于除以2。
2.2 例題分析
【例2.1】 有變量定義語句int a=3;b=4;,則_______。
A.定義了a、b兩個變量 B.定義了a、b兩個變量,并均已初始化
C.程序編譯時出錯 D.程序運行時出錯
解題知識點:變量定義語句規則。
解:答案為C。本題的解題要點是:變量定義語句以分號表示結束。b前面的分號標志著int型變量定義結束,則變量b未被定義。所以編譯時出錯:“Undefined symbol'b'in function…”。
【例2.2】 表達式3.5+5%2*(int)(1.5+1.3)/4的值為_______。
A.4.5 B.4.0 C.3.5 D.4.2
解題知識點:強制類型轉換;算術運算。
解:答案為C。本題的解題要點是:做除法運算,當兩個操作數都是整型時,結果為整型。因為5%2為1,(int)(1.5+1.3)為2,2/4為0,所以結果為3.5。
【例2.3】 有變量說明語句float a,b;int k=0;,合法的C語言賦值語句是_______。
A.a=b=8.5 B.a=8.5,b=8.5 C.k=int(a+b); D.k++;
解題知識點:強制類型轉換;賦值語句的書寫規則。
解:答案為D。賦值語句的一般格式為:變量名=表達式;,語句以分號作為結束標志。選項A是賦值表達式,不是語句;選項B是逗號表達式;選項C使用了強制類型轉換,應將類型符用圓括號括起來,即k=(int)(a+b);;選項D相當于k=k+1;,所以是合法的賦值語句。
【例2.4】 有變量說明語句int a=9;,則執行完語句a+=a-=a*a;后,a的值是_______。
A.9 B.144 C.0 D.-144
解題知識點:復合賦值語句的運算規則。
解:答案為D。賦值語句的結合性為“自右至左”,復合賦值語句可以分解進行。將語句a+=a-=a*a;分解成如下兩條語句:a-=a*a;a+=a;,由第一條語句可以算出a的值為-72,由第二條語句算出a的值為-144。
【例2.5】 有下面程序段:
int i,j;
j=(i=32767,i+1);
printf("i=%d,j=%d\n",i,j);
則運行結果是_______。
A.i=32767,j=32768 B.i=32768,j=32768
C.i=32767,j=-32768 D.i=32767,j=32767
解題知識點:逗號表達式;整型變量的取值范圍。
解:答案為C。題中賦值語句j=(i=32767,i+1);,賦值號右側的括號內是逗號表達式,執行過程為:先用32767為i賦值,再計算i+1的值,并用i+1的值作為逗號表達式的值為j賦值。在內存中的表示形式為:

可見,i+1的值為-32768。原因是整型變量在內存中占2個字節,最大可表示32767,再加1則產生溢出。
【例2.6】 下面程序段的運行結果是_______。
int x=5,y=5,z=5;
printf("x=%d,y=%d\n",x++,++y);
z++;++z;
printf("x=%d,y=%d,z=%d\n",x,y,z);
A.x=6,y=6 B.x=5,y=5
x=6,y=6,z=6 x=6,y=6,z=7
C.x=6,y=5 D.x=5,y=6
x=6,y=6,z=6 x=6,y=6,z=7
解題知識點:自增/自減運算符。
解:答案為D。第一個輸出語句中的兩個輸出項都是表達式。x是后加操作,是先用變量的當前值作為表達式的值,然后變量的值加1;y是前加操作,是先為變量的值加1,加1后的值作為當前表達式的值;所以輸出為x=5,y=6。z++;和++z;都是獨立的語句,都是完成加1的操作,所以在第二個輸出語句中輸出時x、y各做一次加1操作,z做了兩次加1操作。
【例2.7】 若有變量定義int x=6;,則下面語句的運行結果是_______。
printf("x1=%d,x2=%d\n",++x,x++);
A.x1=7,x2=7 B.x1=8,x2=6 C.x1=8,x2=8 D.x1=7,x2=8
解題知識點:自增/自減運算符;系統對函數參數的求值順序。
解:答案為B。本題的解題要點是:在Turbo C中系統對函數參數的求值順序是自右而左。printf中要輸出兩個表達式的值(++x和x++),先求右邊的表達式x++的值為6(先使用當前值,后加1),x自增1為7;再求左邊的表達式++x的值為8(先加1,再使用),所以輸出x1=8,x2=6。可能出現的錯誤是從左到右計算表達式而選擇選項A。
【例2.8】 在下列選項中,不合法的賦值語句是_______。
A.n1=n2=n3=0; B.k=i==j; C.k=i&&j; D.a=b+c=1;
解題知識點:賦值語句的書寫規則。
解:答案為D。選項A相當于n3=0;n2=n3;n1=n2;,所以合法;選項B相當于k=(i==j);,即賦值號右側是關系表達式,當i和j相等時,k賦值為1,否則k賦值為0,合法;選項C中賦值號右側是邏輯表達式,當i和j均非零時k賦值為1,否則k賦值為0,也合法;選項D相當于a=((b+c)=1);,可見右邊的賦值號的左側不是變量名,而是表達式,所以不合法。
【例2.9】 設有如下表達式:
<<◆◆◆>c+d||~c&d
則表達式中運算符的優先順序是_______。
A.~、+、<<、>、&、|| B.~、+、>、<<、&、||
C.~、+、<<、&、>、|| D.~、+、&、||、>、<<
解題知識點:位運算及其優先級。
解:答案為A。優先級順序是:單目運算符“~”優先級最高,然后依次是算術運算符“+”、移位運算符“<<”、關系運算符“>”、按位與運算符“&”,最后是邏輯運算符“||”。
【例2.10】 設有如下定義:
unsigned x=0x6937;
int n=8;
則表達式(x&~(~0<<n))的作用是_____。
A.x左移8位 B.對x的低位字節清零
C.對x的高位字節置1 D.對x的高位字節清零,保留低位字節
解題知識點:位運算及其優先級。
解:答案為D。因為x是無符號整型,占16個二進位,~(~0<<8)為0000000011111111,由于與0相與對應位被清零,與1相與保留對應位,所以x的高位字節被清零,低位字節被保留。
【例2.11】 已知小寫字母a的ASCII碼值為97,有如下程序:

則運行結果是_______。
A.a B.b C.d D.100
解題知識點:按位或運算;字符的存儲形式。
解:答案為C。本題的解題要點是:先將操作數轉換成二進制,再進行按位或運算,結果作為一個字符的ASCII碼值,輸出對應的字符。a和b用二進制數表示分別為:a=00100000,b=01000100。a|b=01100100轉換為十進制是100,ASCII碼值100對應的字符是小寫字母d。
【例2.12】 以下敘述中不正確的是_______。
A.表達式a&=b等價于a=a&b B.表達式a<<=b等價于a=a<<b
C.表達式a%=b等價于a=a%b D.表達式a!=b等價于a=a!b
解題知識點:復合運算符。
解:答案為D。本題的解題要點是:只有算術運算符和位運算符中的雙目運算符才可以和賦值運算符組成復合賦值運算符。“&”、“<<”、“%”可以和“=”組成復合賦值運算符,但是“!”是邏輯非運算符,是單目運算符,不能與賦值運算符組合。而“!=”是關系運算符,含義是不等于,是不可分割的一個整體。
【例2.13】 已知大寫字母A的ASCII碼值為65,設有如下程序:
void main()
{char c='A';int b=-8;
printf("%d\n",c^b>>2);
}
則運行結果是_______。
A.-18 B.-65 C.65 D.57
解題知識點:按位異或運算、右移運算及其優先級。
解:答案為B。本題解題要點:①注意“>>”的優先級高于“^”;②在Turbo C中右移位采用的是算術移位;③若位運算的兩個操作數長度不同,應先以長的為基準,右端對齊,短的是正數則左邊補0,是負數則左邊補1,然后再運算。先將b轉換成二進制為1111111111111000,計算b>>2得1111111111111110;字符'A'的二進制形式為01000001,高8位補0后,再與b作異或運算得1111111110111110;最高位為1是負數,轉換成原碼為1000000001000001,轉換成十進制數為-65。可能出現的錯誤是優先級搞錯,若先做異或運算后做右移位,則會選擇選項A。
2.3 同步練習
一、選擇題
1.在C語言中,int、char、short三種類型的數據所占用的內存_______。
A.均為2字節 B.由用戶自定義
C.由所用機器的機器字長決定 D.是任意的
2.設int類型的數據占2個字節,則unsigned int類型數據的取值范圍是_______。
A.0~255 B.0~65535
C.-32768~32767 D.-256~255
3.以下_______是不正確的轉義字符。
A.'\\' B.'\'' C.'\08a' D.'\0'
4.設有說明語句:char a='\72';,則變量a_______。
A.包含1個字符 B.包含2個字符 C.包含3個字符 D.說明不合法
5.在C語言中,char型數據在內存中是以_______形式存儲的。
A.原碼 B.補碼C.AS C.I碼 D.反碼
6.以下選項中合法的字符常量是_______。
A."B" B.'\010' C.68 D.D
7.在C語言中,要求操作數必須是整型的運算符是_______。
A.% B./ C.< D.!
8.以下的選擇中,正確的賦值語句是_______。
A.a=1,b=2; B.i++; C.a+b=5; D.y=int(x);
9.以下不正確的敘述是_______。
A.在C程序中所有的變量必須先定義后使用
B.在程序中,APH和aph是兩個不同的變量
C.若a和b類型相同,執行a=b;后b中的值放入a中,b中的值不變
D.當輸入數據時,對整型變量只能輸入整型值,對實型變量只能輸入實型值
10.若變量已正確定義并賦值,下面符合C語言語法的表達式是_______。
A.a:=b+1 B.a=b=c+2 C.int 18.5%3 D.a=a+7=c+b
11.若x為int型變量,則執行以下語句后,x的值為_______。
x=6;x+=x-=x*x;
A.36 B.–60 C.60 D.–24
12.若有定義int x;,則逗號表達式(x=4*5,x*5),x+25的結果為(1),x的值為(2)。
(1)A.20 B.100 C.表達式不合法 D.45
(2)A.20 B.100 C.125 D.45
13.若已定義x和y是double類型,則表達式x=1,y=x+3/2的值是_______。
A.1 B.2 C.2.0 D.2.5
14.設x和y均為int型變量,則執行以下語句后的結果為_______。
x=15;y=5;printf("%d\n",x%=(y%=2));
A.0 B.1 C.6 D.12
15.若有以下程序段:
int c1=1,c2=2,c3;
c3=1.0/c2*c1;
則執行后,c3的值是_______。
A.0 B.0.5 C.1 D.2
16.若x、y、z均為int型變量,m為long型變量,則在16位PC上執行下述語句后,y值的十六進制形式為(1),x值為(2),z值為(3),m值為(4)。
y=(x=32767,x+1);z=m=0xFFFF;
(1)A.FFFF B.7FFF C.7FFE D.8000
(2)A.-32768 B.0 C.32768 D.32767
(3)A.0 B.32768 C.-1 D.65535
(4)A.0 B.32768 C.-1 D.65535
17.以下敘述不正確的是_______。
A.一個好的程序應該有詳盡的注釋
B.C程序中的#include和#define均不是C語句
C.在C程序中,賦值運算符的優先級最低
D.在C程序中,j++;是一條賦值語句
18.若有,其錯誤的C語言表達式是_______。
A.a*e/b*c B.a/b/c*e C.a*e/b/c D.(a*e)/(b*c)
19.設a和b均為int型變量,且a值為15,b值為240,則表達式(a&b)&&b的結果為_______。
A.0 B.1 C.true D.false
20.在位運算中,操作數每右移一位,其結果相當于_______。
A.操作數乘2 B.操作數除以2
C.操作數除以16 D.操作數乘以16
21.若有以下定義和語句,則執行語句后a和b的值分別是_______。
int a=3,b=4;
a=a^b;b=b^a;a=a^b;
A.a=3,b=4 B.a=4,b=3 C.a=3,b=3 D.a=4,b=4
22.設有以下語句,則c的二進制值是_______。
char a=3,b=6,c;
c=a^b<<2;
A.00011011 B.00010100 C.00011100 D.00011000
23.已知char a=15,則~a、-a和!a的整數值分別為_______。
A.240、-15、0 B.0、-15、240 C.-16、-15、0 D.0、-15、0
二、填空題
1.字符常量'a'在內存中應占(1)字節,字符串"a"應占(2)字節。
2.在16位PC環境下,int類型數據應占(1)字節,short類型數據應占(2)字節,long類型數據應占(3)字節,double類型數據應占(4)字節。
3.在16位PC環境下,short類型數據的取值范圍是(1),unsigned int類型數據的取值范圍是(2)。
4.若采用十進制數的表示方法,則077是(1),0111是(2),0x29是(3),0xAB是(4)。
5.若有說明char s1='\077',s2='\'';,則s1中包含(1)個字符,s2中包含(2)個字符。
6.設x為float型變量,y為double型變量,a為int型變量,b為long型變量,c為char型變量,則表達式x+y*a/x+b/y+c的結果為_______類型。
7.定義如下變量:
float x=2.5,y=4.7;int a=7;
表達式x+a%3*(int)(x+y)%2/4的值為_______。
8.設a,c,x,y,z均為int型變量,在下面對應的橫線上寫出各表達式的結果。
(1)a=(c=5,c+5,c/2)(1)
(2)x=(y=(z=6)+2)/5(2)
(3)18+(x=4)*3(3)
9.下列程序的運行結果為_______。

10.下列程序的運行結果是_______。

11.寫出實現以下計算的C語言賦值語句_______。

12.下列程序的運行結果為_______。

13.下列程序的運行結果為_______。

14.下列程序的運行結果為_______。

15.下列程序的運行結果為_______。

16.表達式5&7的值為(1),5|7的值為(2),5^7的值為(3)。
17.二進制數a值為00101101,若想通過異或運算a^b使a的高4位取反,低4位不變,則二進制數b值為_______。
18.二進制數a值為01100101,若想通過a&b運算使a的低4位清零,高4位不變,則二進制數b值為_______。
19.在C語言中,“&”作為雙目運算符時表示的是(1),而作為單目運算符時表示的是(2)。
2.4 參考答案
一、選擇題
1.C 2.B 3.C 4.A 5.C
6.B 7.A 8.B 9.D 10.B
11.B 12.(1)D (2)A 13.C 14.A 15.A
16.(1)D (2)D (3)C (4)D 17.C 18.A 19.A
20.B 21.B 22.A 23.C
二、填空題
1.(1)1 (2)2
2.(1)2 (2)2 (3)4 (4)8
3.(1)–32768~32767 (2)0~65535
4.(1)63 (2)73 (3)41 (4)171
5.(1)1 (2)1
6.double
7.2.5
8.(1)2 (2)1 (3)30
9.11,1,0,1
10.a=A,b=d,c=D
11.z=sin(75*3.14/180)/(x*y)
12.65535
13.dqz
14.14,a=9
15.24,20,36
16.(1)5 (2)7 (3)2
17.11110000
18.11110000
19.(1)按位與 (2)取地址