運算子和表示式之間有什麼聯絡?

  • 作者:由 匿名使用者 發表于 攝影
  • 2022-10-31

運算子和表示式之間有什麼聯絡?dadalili 2006-05-01

2。6 運算子

C語言的內部運算子很豐富,運算子是告訴編譯程式執行特定算術或邏輯操作的符號。C語言有三大運算子:算術、關係與邏輯、位操作。另外, C還有一些特殊的運算子,用於完成一些特殊的任務。

2。6。1 算術運算子

表2 - 5列出了C語言中允許的算術運算子。在C語言中,運算子“ +”、“-”、“*”和“ /”的用法與大多數計算機語言的相同,幾乎可用於所有C語言內定義的資料型別。當“ /”被用於整數或字元時,結果取整。例如,在整數除法中, 1 0 / 3 = 3。

一元減法的實際效果等於用- 1乘單個運算元,即任何數值前放置減號將改變其符號。模運算子“%”在C語言中也同它在其它語言中的用法相同。切記,模運算取整數除法的餘數,所以“%”不能用於float和double型別。

表2-5 算術運算子

運算子 作用 運算子 作用

- 減法,也是一元減法 % 模運算

+ 加法 —— 自減(減1)

* 乘法 ++ 自增(增1)

/ 除法

下面是說明%用法的程式段。

int x,y;

x = 10;

y = 3;

printf(“%d”,x/y); /* 顯示3 */

printf(“%d”,x%y) ; /* 顯示1 ,整數除法的餘數* /

x = 1 ;

y = 2 ;

printf(“%d,%d”,x/y,x%y) ; /* 顯示0,1 */

最後一行列印一個0和一個1,因為1 / 2整除時為0,餘數為1,故1 % 2取餘數1。

2。6。2 自增和自減

C語言中有兩個很有用的運算子,通常在其它計算機語言中是找不到它們的—自增和自減運算子, + +和- -。運算子“ + +”是運算元加1,而“- -”是運算元減1,換句話說:x = x + 1 ; 同+ + x ; x = x - 1 ; 同- - x ;

自增和自減運算子可用在運算元之前,也可放在其後,例如: x = x + 1;可寫成+ + x;或x + +;但在表示式中這兩種用法是有區別的。自增或自減運算子在運算元之前, C語言在引用運算元之前就先執行加1或減1操作;運算子在運算元之後, C語言就先引用運算元的值,而後再進行加1或減1操作。請看下例:

x = 1 0;

y = ++x;

此時,y = 11。如果程式改為:

x = 10 ;

y = x++ ;

則y = 10。在這兩種情況下, x都被置為11,但區別在於設定的時刻,這種對自增和自減發生時刻的控制是非常有用的。

在大多數C編譯程式中,為自增和自減操作生成的程式程式碼比等價的賦值語句生成的程式碼要快得多,所以儘可能採用加1或減1運算子是一種好的選擇。

下面是算術運算子的優先順序:

最高 ++、——

-(一元減)

*、/、%

最低 +、-

編譯程式對同級運算子按從左到右的順序進行計算。當然,括號可改變計算順序。C語言處理括號的方法與幾乎所有的計算機語言相同:強迫某個運算或某組運算的優先順序升高。

2。6。3 關係和邏輯運算子

關係運算符中的“關係”二字指的是一個值與另一個值之間的關係,邏輯運算子中的“邏輯”二字指的是連線關係的方式。因為關係和邏輯運算子常在一起使用,所以將它們放在一起討論。

關係和邏輯運算子概念中的關鍵是True(真)和Flase(假)。C語言中,非0為True,0為Flase。使用關係或邏輯運算子的表示式對Flase和Ture分別返回值0或1 (見表2 - 6 )。

表2-6 關係和邏輯運算子

關係運算符 含義 關係運算符 含義

> 大於 <= 小於或等於

>= 大於等於 == 等於

< 小於 != 不等於

邏輯運算子 含義

&& 與

|| 或

! 非

表2 - 6給出於關係和邏輯運算子,下面用1和0給出邏輯真值表。

關係和邏輯運算子的優先順序比算術運算子低,即像表示式10>1+12的計算可以假定是對錶

達式10>( 1 + 12)的計算,當然,該表示式的結果為Flase。

在一個表示式中允許運算的組合。例如:

10>5&&!(10<9)||3<=4

p q p&&q p||q !p

0 0 0 0 1

0 1 0 1 1

1 0 0 1 0

1 1 1 1 0

這一表達式的結果為True。

下表給出了關係和邏輯運算子的相對優先順序:

最高 !

>= <=

== !=

&&

最低 ||

同算術表示式一樣,在關係或邏輯表示式中也使用括號來修改原計算順序。

切記,所有關係和邏輯表示式產生的結果不是0就是1,所以下面的程式段不僅正確而且將在螢幕上列印數值1。

int x;

x = 100;

printf(“%d”,x>10);

2。6。4 位運算子

與其它語言不同,C語言支援全部的位運算子( Bitwise Operators)。因為C語言的設計目的是取代組合語言,所以它必須支援組合語言所具有的運算能力。位操作是對位元組或字中的位(bit)進行測試、置位或移位處理,這裡位元組或字是針對C標準中的char和int資料型別而言的。位操作不能用於float、double、long double、void或其它複雜型別。表

2 - 7給出了位操作

的運算子。位操作中的AND、OR和NOT(1的補碼)的真值表與邏輯運算等價,唯一不同的是位操作是逐位進行運算的。

表2-7 位運算子

運算子 含義 運算子 含義

& 與(AND) ~ 1的補(NOT)

| 或(OR) >> 右移

^ 異或(XOR) << 左移

下面是異或的真值表。

表2-8 異或的真值表

p q p^q

0 0 0

1 0 1

1 1 0

0 1 1

如表2 - 8所示,當且僅當一個運算元為True時,異或的輸出為True,否則為Flase。

位操作通常用於裝置驅動程式,例如調變解調器程式、磁碟檔案管理程式和印表機驅動程式。這是因為位操作可遮蔽掉某些位,如奇偶校驗位(奇偶校驗位用於確保位元組中的其它位不會發生錯誤通常奇偶校驗位是位元組的最高位)。

通常我們可把位操作A N D作為關閉位的手段,這就是說兩個運算元中任一為0的位,其結果中對應位置為0。例如,下面的函式透過呼叫函式read_modem( ),從調變解調器埠讀入一個字元,並將奇偶校驗位置成0。

[例2 - 4 ]

Char get_char_from_modem()

{

char ch;

ch=read_modem(); /*從調變解調器埠中得到一個字元* /

return(ch&127);

}

位元組的位8是奇偶位,將該位元組與一個位1到位7為1、位8為0的位元組進行與操作,可將該位元組的奇偶校驗位置成0。表示式ch&127正是將ch中每一位同127數字的對應位進行與操作,結果ch的位8被置成了0。在下面的例子中,假定c h接收到字元“A”並且奇偶位已經被置位。

奇偶位

110000001 內容為‘A’的c h,其中奇偶校驗位為1

011111111 二進位制的127執行與操作

& 與操作

——————-

=010000001 去掉奇偶校驗的‘A’

位操作OR與AND操作相反,可用來置位。任一運算元中為1的位將結果的對應位置1。如下所示,128|3的情況是:

1000000 128的二進位制

0000011 3的二進位制

| 或操作

——————

=1000011 結果

異或操作通常縮寫為XOR,當且僅當做比較的兩位不同時,才將結果的對應位置位。如下所示,異或操作127 ^ 12 0的情況是:

01111111 127 的二進位制

01111000 120 的二進位制

^ 異或操作

————-

=00000111 結果

一般來說,位的AND、OR和XOR操作透過對運算元運算,直接對結果變數的每一位分別處理。正是因為這一原因(還有其它一些原因),位操作通常不像關係和邏輯運算子那樣用在條件語句中,我們可以用例子說明這一點:假定X = 7,那麼x && 8為Ture( 1 ) ,而x & 8卻為Flase( 0 )。

記住,關係和邏輯運算子結果不是0就是1。而相似的位操作透過相應處理,結果可為任意值。換言之,位操作可以有0或1以外的其它值,而邏輯運算子的計算結果總是0或1。

移位運算子>>和<<將變數的各位按要求向或向左移動。右移語句通常形式是:

variable >>右移位數

左移語句是:

variable << 左移位數

當某位從一端移出時,另一端移入0(某些計算機是送1,詳細內容請查閱相應C編譯程式使用者手冊)。切記:移位不同於迴圈,從一端移出的位並不送回到另一端去,移去的位永遠丟失了,同時在另一端補0。

移位操作可對外部裝置(如D/A轉換器)的輸入和狀態資訊進行譯碼,移位操作還可用於整數的快速乘除運算。如表2 - 9所示(假定移位時補0),左移一位等效於乘2,而右移一位等效於除以2。

表2-9 用移位操作進行乘和除

字元x 每個語句執行後的x x的值

x=7 00000111 7

x<<1 00001110 14

x<<3 01110000 112

x<<2 11000000 192

x>>1 01100000 96

x>>2 00011000 24

每左移一位乘2,注意x < < 2後,原x的資訊已經丟失了,因為一位已經從一端出,每右移一位相當於被2除,注意,乘後再除時,除操作並不帶回乘法時已經丟掉的高位。

反碼運算子為~。~的作用是將特定變數的各位狀態取反,即將所有的1位置成0,所有的0位置成1。

位運算子經常用在加密程式中,例如,若想生成一個不可讀磁碟檔案時,可以在檔案上做一些位操作。最簡單的方法是用下述方法,透過1的反碼運算,將每個位元組的每一位取反。

原位元組 00101100

第一次取反碼 11010011

第二次取反碼 00101100

注意,對同一行進行連續的兩次求反,總是得到原來的數字,所以第一次求反表示了位元組的編碼,第二次求反進行譯碼又得到了原來的值。

可以用下面的函式encode( )對字元進行編碼。

[例2 - 5 ]

char encode(ch)

char ch;

{

return (~ch);

}

2。6。5 ?運算子

C語言提供了一個可以代替某些if - then - else語句的簡便易用的運算子?。該運算子是三元的,其一般形式為:

EXP1? EXE2: EXP3

EXP1,EXP2和EXP3是表示式,注意冒號的用法和位置。

運算子“?”作用是這樣的,在計算EXP1之後,如果數值為True,則計算EXP2,並將結果作為整個表示式的數值;如果E XP1的值為Flase,則計算EXP3,並以它的結果作為整個表示式的值,請看下例:

x = 10;

y = x> 9? 100: 200;

例中,賦給y的數值是100,如果x被賦給比9小的值,y的值將為200,若用if - else語句改寫,有下面的等價程式:

x = 10;

if(x>9) y=100;

else y=200;

有關C語言中的其它條件語句將在第3章進行討論。

2。6。6 逗號運算子

作為一個運算子,逗號把幾個表示式串在一起。逗號運算子的左側總是作為void(無值),這意味著其右邊表示式的值變為以逗號分開的整個表示式的值。例如:

x = ( y = 3 , y + 1 ) ;

這行將3賦給y,然後將4賦給x,因為逗號運算子的優先順序比賦值運算子優先順序低,所以必須使用括號。

實際上,逗號表示操作順序。當它在賦值語句右邊使用時,所賦的值是逗號分隔開的表中最後那個表示式的值。例如,

y = 10;

x = (y = y - 5 , 2 5 / y ) ;

執行後,x的值是5,因為y的起始值是1 0,減去5之後結果再除以2 5,得到最終結果。

在某種意義上可以認為,逗號運算子和標準英語的and是同義詞。

2。6。7 關於優先順序的小結

表2 - 1 0列出了C語言所有運算子的優先順序,其中包括將在本書後面討論的某些運算子。注意,所有運算子(除一元運算子和?之外)都是左結合的。一元運算子( *,&和-)及運算子“?”則為右結合。

表2-10 C語言運算子的優先順序

最高階 ()[] →

!~ ++ —— -(type) * & sizeof

* / %

+ -

<< >>

<= >=

== !=

& ^ |

&&

||

= += -= *= /=

最低階,

2。7 表示式

表示式由運算子、常量及變數構成。C語言的表示式基本遵循一般代數規則,有幾點卻是與C語言緊密相關的,以下將分別加以討論。

2。7。1 表示式中的型別轉換

混合於同一表示式中的不同型別常量及變數,應均變換為同一型別的量。C語言的編譯程式將所有運算元變換為與最大型別運算元同類型。變換以一次一操作的方式進行。具體規則如下:

1 ) 所有char及short int 型量轉為int型,所有float轉換為double。

2) 如運算元對中一個為long double ,另一個轉換為long double。① 要不然,一個為double,另一個轉為doub le。② 要不然,一個為long,另一個轉為long。③ 要不然,一個為unsigned,另一個轉為unsigned。

一旦運用以上規則。每一對運算元均變為同類型。注意,規則2 )有幾種必須依次應用的條件。

圖2 - 1示出了型別轉換。首先, char ch轉換成int,且floatf 轉換成double;然後ch /i的結果轉換成doubl e,因為f * d是double;最後由於這次兩個運算元都是double,所以結果也是double。。

2。7。2 構成符cast

可以透過稱為cast的構成符強迫一表達式變為特定型別。其一般形式為:

(type)expression

( type)是標準C語言中的一個數據型別。例如,為確保表示式x / 2的結果具有型別float,可寫為:

(float)x / 2

通常認為cast是運算子。作為運算子, cast是一元的,並且同其它一元運算子優先順序相同。

雖然cast在程式中用得不多,但有時它的使用的確很有價值。例如,假設希望用一整數控制迴圈,但在執行計算時又要有小數部分。

[例2 - 6 ]

main()

{

int i;

for(i+1;i<=100;++i)

printf(“%d/2 is :%f”,i,(float)i/2);

}

若沒有cast( float),就僅執行一次整數除;有了cast就可保證在螢幕上顯示答案的小數部分。

2。7。3 空格與括號

為了增加可讀性,可以隨意在表示式中插入tab和空格符。例如,下面兩個表示式是相同的。

x = 10 / y *( 127 / x );

x = 10 / y *( 127 / x );

冗餘的括號並不導致錯誤或減慢表達式的執行速度。我們鼓勵使用括號,它可使執行順序更清楚一些。例如,下面兩個表示式中哪個更易讀一些呢?

x = y / 2 - 34 * temp & 127;

x = ( y / 2 ) - ( ( 34 * temp) & 127);

2。7。4 C語言中的簡寫形式

C語言提供了某些賦值語句的簡寫形式。例如語句:

x = x + 10;

在C語言中簡寫形式是:

x + = 10;

這組運算子對+ =通知編譯程式將X + 1 0的值賦予X。這一簡寫形式適於C語言的所有二元運算子(需兩個運算元的運算子)。在C語言中,variable=variable1 operator expression;與variable1 operator=expression相同。

請看另一個例子:

x = x - 1 0 0 ;

其等價語句是

x - = 100;

簡寫形式廣泛應用於專業C語言程式中,希望讀者能熟悉它。

運算子和表示式之間有什麼聯絡?標標課堂 2021-04-04

SQL Server資料中運算子與表示式

Top