程序員之程序設計知識點二
2.1C語言的數據類型
數據類型包含兩方面的內容:數據的表示和對數據加工的操作。數據的全部可能表示構成數據類型的值的集合。數據全部合理的操作構成數據類型的操作集合。
在C語言中,把整型、實型和字符型稱為基本數據類型,又稱整型和實型為數值型。為了描述更復雜的數據結構,C語言還有構造類型、指針類型、放舉類型和空類型。構造類型是指由若干個相關的數據組合在一起形成的一種復雜數據類型。
1.整型
整型數據按其存儲在內存中的二進位信息的***位是當作數值信息位還是當作數據的符號位,將整型數據分成帶符號整型和無符號整型兩種。每種整型又按所需的字節個數的多少分成三種。所以整型共有6種:
帶符號整型(int)、帶符號短整型(short int)、帶符號長整型(long int,或 long)、無符號整型(unsigned int)、無符號短整型(unsigned short int)以無符號長整型(unsigned long)。
2.實型
實型數據有表示范圍和精度兩個不同的特征,為了適應數的范圍和精度的不同要求,實型數據分三種類型:單精度型(也稱浮點型 float)、雙精度型(double)、長雙精度型(long double)。
3.構造類型
構造類型是指由若干個相關的數據組合在一起形成的一種復雜數據類型,構造數據類型的成分數據可以是基本數據類型的,也可以是別的構造類型的。按構造方式和構造要求區分,構造類型主要有數組類型、結構類型和共用類型。數組類型是由相同類型的數據組成;結構類型可以由不同類型的數據組成;當不同數據類型不會同時使用時,以節約內存,讓不同數據占用同一區域,這就是共用類型。
4.指針類型
指針類型是取程序對象(如變量)在內存中占居的地址為值的一種特殊的數據類型。
5.枚舉類型
當變量只取很少幾種可能的值,并分別用標識符對值命名時,這種變量的數據類型可用枚舉類型來表示。如變量表示一個星期中的某一天,就可用校舉類型描述該變量的類型,并以星期見的英文名對日期命名,對應的變量取某日的星期名稱為其值。
6.void類型
用保留字VOid表示的數據類型有兩種完全相反的意思,或表示沒有數據(沒有結果、沒有形式參數),或表示某種任意類型的數據(如又與指針結合,用 void。標記)。 void表示空類型,void。表示任意數據的指針類型,程序如要使用 void。類型的數據,應該將它強制地轉換成某種具體的指針類型。
2.2 常量
常量是指程序運行過程中其值不可改變的數據。常量按其值的表現形式可分為如下類型:整型常量、實型常量、字符型常量、字符串常量和指針常量。
1.整型常量
C語言整型常量的書寫形式有三種:
(1)十進制整數。通常整數的寫法,如0,123,-45,+25。
(2)八進制整數。以數字符0開頭并由數字符0-7組成的數字符序列,為八進制整數。如 0123表示八進制整數,其值等于十進制整數 l*8*8+2*8+3=83。
(3)十六進制整數。十六進制整數以OX(或OX)開頭的整數。表示十六進制數的數字將有16個,它們分別是0-9和A、B、C、D、E、F,其中六個英文字母也可以小寫。例如,0x123表示十六進制整數,其值等于十進制整數1*16*16+2*16+3=291; oxabc,其值等于10*16*16+11+16+12=2748。
整型常量也可在整數之后接上字母L(或l),特別指明它是 long型的。
整型常量也可在整數之后接上字母U(或u),特別指明是不帶符號的,即是unsigned型的。為指明不帶符號的long型整型常量,則需在整數之后同時加上字母U和L,表明該整型常量是unsigned long型的。
整型數據以二進制形式存放,要求短整型數據的字節數不能大于整型數據的字節數;整型數據的字節數不能大于長整型數據的字節數。對于帶符號的整數,用二進制代碼的最左二進位作為數的符號,1表示負數,0表示正數。
2.實型常量
C語言實型常量的一般書寫格式是:
正負號 整數部分.小數部分 指數部分
其中,正負號可有可無,無正負號即為正實數;整數部分和小數部分都是十進數字符序列;指數部分是e(或E)后接上正負號(正號可有可無)和十進數字符序列。
按上述格式書寫實型常量,另有兩條限制:
(l)整數部分和小數部分可以任選,但不可同時都沒有。
(2)小數點和指數部分不可以同時都沒有。
ANSIC引入兩個后綴字符,用 f標識 float型實型常量,用 1(或 L)標識 fong double型實型常量,而無后綴符的實型常量被認為是double型的實型常量。
要注意實型常量的有效位數,不要以為寫上的數字都能被計算機所接受。在大多數C系統中,一個float型實型數據在內存中占用4個字節(32個二進位),約7個十進位有效數字,能表示絕對值最接近0的實數約為10的-38次方,***的實數約為10的38次方。例如,對于代碼 float x=123456.123f,在大多數系統中,實型常量123456.123f的***兩位數字是無效的。
double型實型數據占用8個字節(64個二進位),約15個十進位有效數字,能表示絕對值最接近0的實數約為10的一308次方,***的實數約為10的308次方。
3.字符常量
字符型數據用于表示一個字符值,但字符型數據的內部表示是字符的ASCll代碼(8位二進位的二進制形式)。字符型數據的類型符用char來標記。字符型常量的書寫方法:
(l)普通字符--用單引號括起一個字符。如’a’、’b’、’B’、’$’。
(2)特殊字符--用’\字符或字符列采標記。這種標記方法有三種:
’\特定字符’,標記特定控制符,如換行符用’\ n’來標記。
’\ 1至3個人進制數字’,以人進數表示字符的ASCll代碼。
’\ X1至2個十六進制數字符’,以十六進制數表示字符的 ASCll代碼。
由于字符以代碼存放,所以也可把字符值當作一個小整數。反之,一個小整數也可把它理解為是某個字符的代碼,把它當作一個字符。
4.字符串常量
字符串常量用來表示一個字符序列,它的書寫方法用雙引號括住字符序列。例如:”ABC”、””等。字符串常量“”是一個空字符串,即不含任何有效字符的字符串。字符串數據順序存儲字符串字符的ASCll代碼,并在***字符后面存儲一個H進制代碼全為0的特殊字符,用來標記字符串的結束。所以字符串常量“1234”在內存占5個字節,而空字符串只占一個字節。字符串中的字符也可以是轉義字符。
5.符號常量
為了提高程序的可讀性,常量可以用以下形式命名:
# define 標識符 常量
其中的標識符也稱作符號常量,這里的常量是前面所述的某種常量、或是程序中前面定義的符號常量。例如:
# define MAXN 100
2.3 變量
變量是程序執行時,其值允許改變的數據對象,用來存儲輸入數據、計算的中間結果和程序的最終結果等。
1.變量定義
變量用標識符命名,通過變量定義引入的變量名習慣用英文字母開頭,C系統可能也會預定義一些標記系統特性的變量,系統定義的變量習慣用下線字符開頭。變量的數據特性由變量定義時指定的類型確定。若定義指定數據類型的變量(即不在指定數據類型基礎上定義新數據類型的變量,如指定類型的指針、數組等),這種變量定義的句法為:
數據類型符變量名1,變量名2,……;
編繹系統根據變量的數據類型確定存放它的值所需要的內存字節數,變量值的內部表示形多也由其類型確定。
2.內部變量和外部變量
變量按其定義出現在程序中的位置不同分成兩類:在函數內定義的變量稱為內部變量,而在函數之外(函數之間)定義的變量稱為外部變量。
3.變量的存儲類型
系統按程序對計算機存儲空間使用的不同要求,將內存分成不同用途的塊,與計算機的寄存器一起將存儲空間分成不同類別。而C程序通過指定變量的存儲類表明變量的不同的使用要求,讓系統將變量分配于不同的內存塊或寄存器。如在上述變量定義形式中,還要指定變量的存儲類型,變量定義的形式為:
存儲類型符數據類型符變量名1,變量名2,…;
其中存儲類型有四種: auto(自動的)、static(靜態的)、register寄存器的)和 extem外部的)。
外部變量只允許被指定為靜態的,或不指定其存儲類型。內部變量可以被指定為自動的或靜態的、或寄存器的、或不指定存儲類型,若不指定存儲類型,它就是自動的。
自動變量是內部變量,在函數內或復合語句內定義,它們被分配在堆棧區。
靜態變量可以是內部變量,也可以是外部變量。靜態變量表示***性和專用性,即在程序執行過程中一直存在,局限于定義它的函數(內部靜態變量)或局限于定義它的程序文件中那些函數(外部靜態變量)。靜態變量被分配在與程序相聯的內存數據區。
寄存器變量是函數的內部變量或參數,也是一種臨時性的變量。如因函數使用非常頻繁程序希望將它分配在寄存器,程序就可將變量指定為寄存器的,但編譯系統也可能把它當作動變量處理。
指定存儲類型是外部的,實際b是告訴編譯器,這個變量是一個外部變量,在這里要使它,而它的定義或在別的程序文件或在后面的程序段等別的地方。
4.變量的作用域和生存期
變量的使用要注意變量的作用域(可使用范圍)和生存期(存在的時間)。C語言規定,內部變量的作用域只局限于定義它的函數或復合語句。自動的內部變量是一種臨時性變量,函數被調用時分配,函數執行結束時釋放。而靜態變量在程序執行前分配,直至程序結束才釋放。由于靜態的內部變量在函數結束時,依舊保持存儲,函數上一次調用時留在內部靜態變量中的結果能被下一次調用時繼續使用。外部變量也在程序啟動前分配,直至程序執行結束釋放。普通的外部變量能提供別的源程序文件中的函數使用(要對它作外部說明);靜態的外部變量只能供定義它的源程序中的全部函數專用。由于外部變量能供整個程序使用,所以外部量不能重名。
5.變量定義初始化
變量定義是對變量的存儲空間提出一種要求,存儲空間分配后,變量的初值通常是不拔的。但程序可以要求系統在為變量分配存儲空間同時為變量設定初值,這就是變量定義初始化。在變量的定義形式中,在變量名之后接上“=初值表達式”,該初值表達式的值就作為該變量的初值。C語言另有約定,對于靜態變量和外部變量,若定義它們時未指定初值,系統給它們設置成全部二進位都是0的值。以下是各種變量定義的例子:
(l)定義整型,并對其初始化。
Short minInt =100;
int i= l,j= 2, k=3;
long p=-1L,q=1234567890L;
unsigned usi= 254u;
unsigned long up= 4294967295UL;
(2)定義字符型變量,并對其初始化。
char ch=’A’;
(3)定義實型(浮點型、雙精度型)變量,并對其初始化。
float f=1.23456f;
double d=1.2345678op87654;
2.4 運算符
每個運算符都代表對運算對象的某種運算,都有自已特定的運算規則,規定運算對象的個數、運算對象數據類型,以及運算結果的數據類型。C語言還規定運算符有不同的優先級和結合性。運算符的優先級指表達式求值時,按運算符的優先級由高到低的次序計算。如“先乘除后加減”。運算符的結合性是指運算符要求它的運算對象對它的結合方向。結合性確定了在相同優先級運算符連續出現的情況下運算對象與運算符結合的順序,通常也是計算順序。如算術運算符的結合性是從左至右的,則連續的加減或連續的乘除是從左向右計算。而賦值運算符的結合性是從右至左的,則連續的賦值運算是從右向左逐個計算賦值。在C語言中,要特別注意某些運算符因運算對象數據類型不同,可能有不同的意義。
1.算術運算符
算術運算符的運算對象是基本數據類型的數據,實現通常的取整、取負、四則運算、求兩整數相除后的余數的運算和增1減1運算。特別要留心的是整除運算、求余運算、增1運算和減1運算。
對兩個整型數據執行除運算(/),稱為整除運算,要特別注意的是兩個整型數據的整除運算的結果是整型的,如表達式3/2的結果為1,表達式2/3的結果為0。
求余運算符(%)要求參與運算的兩個運算對象均為整型數據,如 5% 3的值為 2。一般來說,求余運算所得結果的符號與被除數的符號相同。如-5%3的值為-2,5%-3的值為2。
增1(++)和減1(--)運算符都是單目運算符,以整型、字符型和指針型變量為運算對象,并改變運算對象的值。按它們出現在變量之前和之后兩種不同情況,其作用有微妙的差別。
前綴++
前綴++的一般形式是
++變量
例如,若X是整型或某種指針類型的變量,則++X使變量X的值增大1個單位,并以X的新值作為表達式“++X”的運算結果。如以下語句執行前,變量X的值為1,語句
j= ++ x;
使變量X的值變成3,變量j的值也為3。這里所說的一個“單位”是指:如果X是整型的,則++x就是普通的解釋:“x的值比原值增加1";x是指針,它指向數組的某個元素,則++x使它指向數組的后一個元素。
后綴++
后綴++的一般形式是
變量++
表達式“變量++”運算結果是該變量的原來值,在確定了表達式結果之后,用與前綴++相同的方式增大該變量的值1個單位。
前綴++和后綴++都能使變量的值增加1個單位,但是它們所代表的表達式的值卻不相同,前者是變量增加后的值,后者是變量還未增加的原先值。例如i,j為整型變量,且i的值為4,以下分別用①和②表記的代碼將使j獲得不同的值:
①j=++i ;
②j= i++
都使變量i的值變為5,但①使j的值為5;②使j的值為4。
前綴--
前綴-- 的一般形式是
--變量
前綴--使變量的情減少(或后退)l個單位,并以變量的新值為表達式“--變量”的運算結果。
后綴--
后綴-- 的一般形式是
變量--
后綴-- 作用于變量時,以該變量的值作為表達式“變量--”的運算結果,即先取其值為結果,然后用與前綴--相同的方式減少該變量1個單位。
后綴-- 與前綴-- 的區別類似于后綴++與前綴++的區別。類似前面的例子,依舊假定i的值為4,兩代碼
③j= --i
④j=i--
都使變量i的值變為3,但③使j的值為3;④使j的值為4。
使用++和--運算符時,其運算對象僅適用于變量,不能是常量等數據值表達式。如 4++或(i+j)++都是不合法的。
++和--是帶有副作用的運算符。建議讀者不要在一個表達式中對同一變量多次使用這樣的運算符,可能會發生意想不到的結果。如i的值為4,對表達式
(i++)+(i++)
可能認為它的值為 9(+5)。然而在 TURBO C和MS C系統中,它的值為8。而表達式
(++i)+(++i)
的值為12。這是因為這些系統在處理 i++時,先使用 i的原值計算整個表達式,然后再讓i連續兩次自增;處理++i時,在計算表達式值之前,先對 i執行兩次自增,然后才計算表達式。放前一個表達式的值為8,后一個表達式的值為12。
因+與++(-與--類似)是兩個不同運算符,對于類似表達式i+++j會有不同的理解:(i++)+ j或i+(++j)。 C編譯的處理方法是自左至右讓盡可能多的字符組成一個合法的句法單位(如標識符、數字、運算符等)。因此,i+++j被解釋成(i++)+j,而不是i+(++j)。
增1(++)和減1(--)運算符的結合方向是自右至左的。
2.關系運算符
用于關系運算的關系運算符有六個:<(小于)、>(大于)、<=(小于等于)、>=(大于等于)、==(等于)和!=(不等)。關系運算是雙目運算,它的運算對象可以是基本數據類型的數據,用于比較大小;或是指向同一個數組兩元素的指針,用于比較前后關系。在高級語言中,習慣稱條件滿足為“真”,不滿足為“假”。特別在C語言中約定:比較后,條件滿足(真)的值為1;比較后,條件不滿足(假)的值為兒用關系運算符將兩個子表達式連接起來,構成關系比較表達式,求得結果為1(真)或0(假)。
六個關系運算符中,運算符(<、<=、>、>=)的優先級高于運算符(==,!=)。如表達式X>y==Cy)==(C<d)。
另外,為便于描述兩個復雜算式的比較,關系運算符的優先級低于算術運算符的優先級。
設有i=1,j=2,k=3,則表達式i>j的值為“假”,即表達式的值為0;表達式i==k>j的值為“真”,即表達式的值為1(先計算k>j,其值為1,等于i);i+j 的值為0。 關系運算符的結合方向是自左至右。仍設i=1,j=2,k=3,則表達式k>j>i的值為0(先計算k>j,其值為1,再計算1>1,結果為0)。 3.邏輯運算符 用于邏輯運算的邏輯運算符有三個: &&(邏輯與)、||(邏輯或)、!(邏輯非) 其中運算符“&&”和“||”是雙目運算符,要求有兩個整型或字符型的運算對象,用于連接多個判定條件,構成更復雜的條件判定;運算符“!”是單目運算符,用于描述對給定條件的否定判定。 邏輯運算產生的結果也只能是1或0。 1表示邏輯運算結果為“真”;用0表示運算結果為“假”。 在判定一個運算對象的值為“真”或“假”時,以運算對象的值不等于零為“真”,運算對象的值等于0為“假”。 邏輯運算符中,按優先級排列為:邏輯非運算符!的優先級高于邏輯與運算符&&,邏輯與運算符&&的優先級高于邏輯或運算符||。另外,&&和||的優先級低于關系運算符的優先級;!的優先級高于算術運算符的優先級。邏輯運算符||和&&的結合方向是自左至右,而邏輯運算符!的結合方向是自有至左。 需要特別指出的是,“邏輯與”和“邏輯或”運算符分別有以下性質: a&&b,僅當a為0時,不管b為何值(實際上不再計算b),結果為0。 a||b,僅當 a為 1時,不管 b為何值(實際上不再計算 b),結果為1。 上述性質就是說,對于表達式a&&b,僅當子表達式a為非零時,才計算子表達式b;對于表達式a||b,僅當子表達式a為0時,才計算子表達式b。在具體編寫程序時,也應利用以上性質。對于兩個條件的邏輯與,如當條件1不成立情況下,條件2的值沒有意義或不可計算時,邏輯表達式應寫成: 條件l&&條件2 避免在條件1不成立情況下,計算條件2。如有條件:y/x>2且 x!=0,應寫成: x!=0 && y/x>2 當X為0時,不會計算y/X。而寫成: y/X>2 && X!=0 是不正確的,因為當 X為0時,不能計算y/X。對于邏輯或也有類似情況。 由于上述性質,在計算連續的邏輯與和邏輯或運算時,實際上不分優先級,而是順序從左至右計算。在計算邏輯與運算時,若有左運算對象的值為0,則不再繼續計算邏輯與運算,并立即以0為邏輯與運算的結果;在計算邏輯或運算時,若有左運算對象的值為1,則不再繼續計算邏輯或運算,并立即以1為邏輯或運算的結果。在順序計算邏輯表達式的過程中,一旦確定了表達式的最終結果,就不再繼續計算。 #p# 4.賦值運算符 賦值運算的最簡單形式是 變量=表達式 其中“=”是賦值運算符。賦值運算的執行過程是: (l)先計算賦值運算符右端的表達式; (2)如表達式的類型與賦值運算符左邊的變量類型不同(僅限于基本類型),將表達式值的類型自動轉換成變量的類型; (3)將求得的值賦給變量,即存儲到由變量所占的內存中。 簡單地說,計算表達式的值,將該值賦給變量。 賦值運算也有結果,經賦值運算后,賦值表達式具有賦值后賦位運算符左邊變量同樣的類型和值。因賦位運算有值,所以可以進一步參與運算,特別是可以再賦植給其它變量。賦值運算符的結合性是‘邊有至左”的,當連續有多個賦值運算時,則從右至左逐個賦值。如有變量定義: int k; double x; 則賦值表達式: x= k= 3.5 是先將實數3.5自動轉換成整數3賦給整型變量k,然后又將整數3自動轉換成實數3.0賦給實型變量X。所以,k的值是3,X的值是3.0。 在程序中,經常遇到在變量當前值的基礎上作某種修正的運算。如 x=x+5.0 這類運算的特點是:變量既是運算對象,又是賦值對象。為避免對同一存儲對象的地址重復計算,C語言弓隊復合賦值運算符。它們是 +=、-=、*=、%=、〈〈=、〉〉= 、&= 、^=、|= 通常,記日為某個雙目運算符,復合賦值運算 xθ=e 其等效的表達式為 x= xθ(e) 注意,當e是一個復雜表達式時,等效表達式的括號是必需的。如 y*= a+b 的等效表達式是y= y*(a+b) 賦值運算符和所有復合賦值運算符的優先級全相同,并且都是“自右至左”結合,它們的優先級高于遠號運算符的優先級,低于其它所有運算符的優先級。 5.逗號運算符 逗號運算符“,”用于將若干表達式連接起來順序地逐個計算。連續返號運算的一般形式為: 表達式1,表達式2,…,表達式n 它的計算順序是從左到右逐一計算各表達式,并以表達式n的值為連續逗號運算的結果。例如,表達式 x=( i=3, i*2) 使i等于3,X等于6。其實,逗號運算只是把多個表達式串聯起來,在許多情況下,使用逗號運算的目的只是想分別計算各個表達式的值,而并非想使用逗號運算中***那個表達式的值。逗號運算最常用于for結構中,用于給多個變量登初值,或用于對多個變量的值逐一修改等。逗號運算符的優先級***,其結合性是“自左向右”的。 6.條件運算符 條件運算是一個三目運算,有三個運算對象。條件運算的一般形式為 表達式1?表達式2:表達式3 條件運算的計算規則是: (1)計算表達式1的值; (2)如果表達式1的值非0(真),則計算表達式2,并以表達式2的值為條件運算的結果(不再計算表達式3); (3)如果表達式1的值為0(假),則計算表達式3,并以表達式3的值為條件運算的結果(不再計算表達式2)。 例如,表達式 X>y?X:y 如果x>y條件為真,則條件運算取x值,否則取y值。 條件運算符(?:)的優先級高于賦值運算符,低于邏輯運算符,也低于關系運算符和算術運算符。例如,表達式 max= X> y?X: y+ l 等效于表達式 max=((x>y) ?x:( y+l)) 條件運算符的結合性為“自右至左”。例如,表達式X>y?X:u>V?u:V 等效于表達式 X>y?X:(u>V?u:V) 7.長度運算符 長度運算以字節為單位給出其運算對象所需(或所占)的字節數,運算對象可以是任何類型的數據對象或數據類型。它是根據對象的類型來確定對象(所需)的字節數的。 長度運算有兩種書寫形式: sizeof變量名或sizeof(類型名) 如果有某種類型為江的變量V,其中t可以是系統提供的類型或用戶自己定義的類型,可以是簡單的,也可以是數組、結構等。則 sizeof V就是變量 V所占的字節數。如有 int j; double x; 表達式sizeof j和sizeOf x分別是變量j和x所占的字節數。 sizeof(t)是系統為分配一個類型為t的數據對象所需的字節數。如sizeOf(int)和sizeof(dou-ble)分別是系統為分配一個類型為int和double變量所需的字節數。 8.位運算符 位運算的運算對象只能是整型或字符型數據,位運算把運算對象看作是由二進位組成的位率信息,按位完成指定的運算,得到位串信息的結果。位運算符又可分成兩類:一類是位邏輯運算符,另一類是位移位運算符。 位邏輯運算符有:&(按位與)、|(按位或)、^(按位異或)、~(按位取反) 位移位運算有:<<(位左移)和>>(位右移) 其中按位取反運算符是單目運算符。其余均為雙位運算符。位邏輯運算符的優先級從高到低,依次為~、&、^、|、,其中的結合方向自右至左,且優先級高于算術運算符,其余運算符的結合方向都是自左至右 ,且優先級低于關系運算符。位移位運算符的優先級低于算術運算符,高于關系運算符,它們的結合方向是自左至右。 按位與運算符(&) 按位與運算將將兩個運算對象的對應位按位遵照以下規則進行計算: 0&0=0, 0&l=0,1&0=0,1&l=1 即同為一的位,結果為1,否則結果為0。 例如,設 3的內部表示為00000011,5的內部表示為00000101,則3&5的結果為00000001 按位與運算有兩種典型用法。一是取一個位率信息的某幾位,如以下代碼截齲的***7位、&0177t二是讓某變量保留某幾位,其余位設置成0,如以下代碼讓X只保留***6位:x=X&077、以上用法都先要設計好一個常數,該常數只有需要的位是互,不需要的位是 0。用它與指定的位串信息按位與。 按位或運算符(|) 按位或運算將兩個運算對象的對應位按位遵照以下規則進行計算: 0|0=0, 0|l=1, 1|0=l, 1|1=1 即只要有五個是1的位,結果為1,否則為0。 例如,023|035結果為037。 按位或運算的典型用法是將一個位串信息的某幾位設置成1。如將要獲得最右4位為1,其它位與變量j的其它位相同,可用邏輯或運算 017|j。若要把這結果賦給變量 j,可寫成: j=017|j 按位異或運算符(^) 按位異或運算將兩個運算對象的對應位按位遵照以下規則進行計算: 0^0= 0, 0^1=l, l^0=l, 1^l=0 即相應位的值相同的,結果為0,不相同的結果為l。 例如,013^035的結果為026。 異或運算的意思是求兩個運算對象相應位值是否相異,相異的為1,相同的為0。按位異或運算的典型用法是求一個位串信息的某幾位信息的反。如欲求整型變量j的最右4位信息的反,用邏輯異或運算017^j,就能求得j最右4位的信息的反,即原來為1的位,結果是0;原來為0的位,結果是1。 按位取反運算符(~) 按位取反運算是單目運算,用來求一個位串信息按位的反,即那些為0的位,結果是1;而那些為1的位,結果是幾例如,~7的結果為0xfff8。取反運算常用來生成與系統實現無關的常數。如要將變量X***6位置成0,其余位不變,可用代碼 X= X&~077實現。以上代碼與整數 X用 2個字節還是用 4個字節來實現無關。 當兩個長度不同的數據進行位運算時(例如 long型數據與 int型數據),將兩個運算對象的右端對齊進行位運算。如果短的數為正數,高位用0補滿;如果短的數為負數,高位用1補滿。如果短的為無符號整數,則高位總是用0補滿。 位運算用來對位串信息進行運算,得到位串信息結果。如以下代碼能取整型變量k的位串信息的最右邊為亞的信息位:((k-l)^k)&k。 位左移運算符(<<) 位左移運算符用來將左運算對象(整型或字符型數據)作為二進位信息串作整體向左移動,移動的位數由右運算對象指定,右端空出的位用0補充,得到新的位申信息。例如014<<2,結果為060,即48。 位右移運算符(>>) 位右移運算將一個位串信息向右移指定的位,右端移出的位的信息被丟棄。例如12>>2,結果為3。與左移相反,對于小整數,每右移1位,相當于除以人在右移時,需要注意符號位問題。對無符號數據,右移時,左端空出的位用0補充。對于帶符號的數據,如果移位前符號位為剛正數),則左端也是用0補充;如果移位前符號位為1(負數),則左端用0或用1補充,這取決于計算機系統。對于負數右移,稱用0補充的系統為“邏輯右移”,用1補充的系統為“算術右移”。以下代碼能說明讀者上機的系統所采用的右移方法: printf(”%d\n\n\n”,-2>>4); 者輸出結果為一l,是采用算術右移;輸出結果為一個大整數,則為邏輯右移。 2.5 表達式 表達式就是將運算符與運算對象連接起來描述計算的式予。按表達式的構成規則分,表達式可分以下幾類: 1.初等量表達式 初等量表達式是常量、變量、字符串、函數調用、數組元素、結構成分和帶圓括號的表達式等。 2.單目運算表達式 單目運算表達式是由單目運算符和一個運算對象構成的表達式。單目運算符的優先級低于初等量的運算符,它們的結合性都是“自有向左”結合。 3.雙目運算表達式 雙目運算表達式的一般形式為 表達式 雙目運算符 表達式 雙目運算符自左向右結合。按雙目運算符分類,又可分算術表達式、關系表達式、邏輯表達式、賦值表達式和遠號表達式。由于C語言沒有特別的真、假值,判定時,以非0值為真,以0值為假。所以,前述的C語言的各種表達式的計算結果都可作為邏輯值。 4.條件運算表達式 條件運算表達式的一般形式為 表達式?表達式:表達式 條件運算符自右向左結合。 2.6 數據類型轉換 1.隱式類型轉換 C語言允許基本數據類型中的不同類型數據進行混合運算。因不同類型的數據所占內存字節數和其內部表示形式的不同,在算術運算中(其它運算例外)一個運算符所涉及到的各運算對象,能根據運算對象的情況,要求運算對象的值從一種類型轉換成另一種類型。這種類型轉換是自動進行的,稱作隱式類型轉換。隱式類型轉換嚴格遵守以下規則,按所列優先順序實行類型轉換。 (1)如有運算對象是 long double型的,則其余運算對象也轉換成 long doube型。 (2)如有運算對象是double型的,則其余運算對象也轉換成double型。 (3)如有運算對象是float型的,則其余運算對象也轉換成float型。 (4)如有運算對象是 unsigned long int型的,則其余運算對象也轉換成 unsigned long int型。 (5)如有運算對象是 long int型的,則其余運算對象也轉換成 long int型。 (6)如有運算對象是 unsigned int型的,則其余運算對象都轉換成 unsigned int型。 (7)***,運算對象和結果都是int型的。 根據***一條規則,兩個char型和short型運算對象都自動轉換成int型參與運算,并且結果是int型的。 2.顯式類型轉換 算術運算中,基本數據類型的混合運算會發生隱式類型轉換,當要求與隱式類型轉換規則不一致時,可在表達式中用顯式類型轉換運算,強制地將一種類型的表達式值轉換成另一種類型的位。顯式類型轉換的書寫形式為 (類型名)表達式 其中(類型名)是對其后的表達式作強制類型轉換運算,它將表達式的值強制地轉換成類型名所指明的類型。例如,庫函數sqrt()是求一個double型值的平方根。為求整型變量m的平方根,正確的寫法是 sqrt((double)m) 在求m的平方根之前,先將m的值強制地轉換成double型,然后去調用函數sqrt()。 類型轉換不只改變表達式的值的類型,也可能會因兩種表示形式上的差異,值的大小會有一些誤差。 【編輯推薦】