第二章C語言編程基礎知識(2 / 3)

int p=5,q;

q=(++p)+(++p)+(++p);

其計算過程是先進行三次的p的自加,此時p的值為8,然後在自加後p等於8的基礎上進行p的三次相加,即8+8+8=24,即q的值為24。

3.算術表達式

算術表達式是由算術運算符和操作數所組成的表達式。在計算算術表達式時,其計算順序應按照操作符的優先次序進行,如果有括號的話,則括號應配對。對於自增減運算,要注意運算符的結合性,其中運算符++、--和-是自右向左結合,+、-、*、/和%是自左向右結合。

2.5.3 賦值運算符和賦值表達式

賦值運算符包括簡單賦值運算符和複合賦值運算符,複合賦值運算符又包括算術複合賦值運算符和位複合賦值運算符,如表2-5所示。

表2-5 賦值運算符

運算符分類 名 稱 賦值運算符 舉 例 等價於

簡單賦值 賦值 = Y=x

算術複合賦值 加賦值 += Y + =x Y = y-x

算術複合賦值 減賦值 - = Y - = x Y = y-x

算術複合賦值 乘賦值 * = Y * = x Y = y*x

算術複合賦值 除賦值 / = Y / =x Y = y/x

算術複合賦值 取餘賦值 %= Y % = x Y = y%x

位操作複合賦值 位與賦值 &= y& = x Y= y&x

位操作複合賦值 位或賦值 丨= y 丨= x y = y 丨x

位操作複合賦值 位異或賦值 ^= Y^=x Y = y > >x

位操作複合賦值 右移賦值 > > = y > > = x Y = y > > x

位操作複合賦值 左移賦值 < < = Y < < = x Y = y < < x

1.賦值運算符

賦值運算符“=”是將其右邊表達式的值賦給左邊的變量,賦值號左邊一定是變量,右邊是表達式。如果右邊表達式的類型與左邊變量的類型不一致時,則先將右邊表達式的值轉換為與左邊變量相同的類型,然後進行賦值。例如:

i=d+3

其中i為int型,d為double型。於是此運算的處理過程是先將3轉換為double型(3.0),再執行d+3.0,結果為double型,最後再把double的結果轉換為int型,並賦給i。

2.賦值表達式

由賦值運算符將一個變量和一個表達式連起來的式子叫賦值表達式。賦值表達式的一般形式如下:

v op expr

其中v是變量,op是賦值運算符,expr是表達式。例如,“x=10”是一個賦值表達式,其處理過程是:先計算賦值號右邊表達式(10)的值,其值為10,再將10賦給x,於是表達式“x=10”的值是10,其中x的值也是10。賦值號右邊的表達式還可以是賦值表達式。例如,下式是合法的:

x=10*(y=5)

按照賦值操作的結合規則(自右向左結合),首先處理表達式“(y=5)”,該表達式的值是5,整個賦值表達式的值為50。

賦值表達式中也可以包含複合賦值運算符,例如:

x+=y+=z*z

設x,y和z的初始值分別為10,20和30,此例等價於

x=x+(y=y+z*z);

其中(y=y+z*z)的值為920,y的值也為920,於是整個表達式的值為930,x也為930。對於如下的運算:

int t=5;

t+=t-=t*t;

對於這樣的表達式,其運算要注意其順序,這樣的表達式是右結合式,即先計算:

t-=t*t;

它相當於:

t=t-t*t;

此時的結果是:

t=5-5*5=-20

然後再計算:

t+=-20;

最後的結果是t=-40。

【例2-2】熟悉數據類型及其用法(本例重點要求掌握在輸入、輸出過程中容易出錯的地方)。

main()

{float x,y; / * 定義x和y為實型變量 * /

int i,j,k,m,n,p,q,s,t; / * 定義一係列整型變量 * /

x=3.6; / * 對x值進行初始化 * /

i =(int)x; / * 強製類型轉換 * /

y =(float)i; / * 強製類型轉換* /

printf("1- -[x=3.6,i =(int)x,y=(float)i]- -x=% f i=% d y=% f

",x,i,y);

k=i;

printf("2- -[k=i]- - -k=% d \ n",k);

j= + + i;

printf("3- -[j= + + i]- - - j= % d \ n",j);

m=k + +;

printf("4- -[m=k + +]- - -m=% d k= % d \ n",m,k);

p=m;

printf("5- -[p=m]- - - p=% d \ n",p);

n=(m+ +)+(m+ +)+(m+ +);

printf("6- -[n=(m + +)(m+ +)(m+ +)]- - -m=% d n=% d

",m,n);

q=(+ +p)+(+ +p)+(+ +p);

printf("7- -[q=(+ +p)(+ +p)(+ +p)]- - -p=% d q=% d \ n",m,n);

s=q+ + +p;

printf("8- -[s=q+ + +p]- - - s= % d p= % d q= % d \ n ",s,p,q);

printf("9- - s= % d s= % d s= % d \ n",s,s+ +,s- -);

t=s;

printf("10--[t=s]---t=% d \ n",t);

t + = t -= t * t;

printf("11--[t + =t - =t * t]---t=% d \ n",t);

}

程序運算結果如下:

1 - - [ x = 3.6,i =(int)x, y =(float)i ] - - x =3.6 i=3 y = 3.0

2 - - [ k = i ] - - - k = 3

3 - - [ j = + + i ] - - - j = 4

4 - - [ m= k + + ] - - - m = 3 k = 4

5 - - [ p = m ] - - - p =3

6 - - [ n = ( m + + ) + ( m + + ) ( m + + ) ] - - - m = 6 n = 9

7 - - [ q = ( + + p ) + ( + + p ) + ( + + p ) ] - - - p = 6 q = 18

8 - - [ s = q + + + p ] - - - s = 24 p = 6 q = 19

9 - - s =24 s= 23 s =24

10 - - [ t =s ] - - - t = 24

11 - - [ t + = t - = t * t ] - - - t = - 1104

上例中,語句:

s=q+++p;

相當於:

s=(q++)+p;

由於q的自加運算是後運算,因此,s的值應該是q+p的值,然後q的值再自增1。

對於語句:

printf("9--s=%ds=%d

",s,s + +,s - -);

它是右向結合,因此,先輸出s-的運算結果,然後輸出s++的運算結果,最後輸出s的值。

2.5.4 關係運算符和關係表達式

1.關係運算符

關係運算符是對兩個操作量進行大小比較的運算符,其操作結果是“真”或“假”。由於C語言中沒有邏輯類型的數據,所以通常以非零表示真,實際上經常用整型數“1”表示“真”,“0”表示“假”。C語言中有六種關係運算符,即:

?>=(大於等於)

?<=(小於等於)

?==(等於)

?!=(不等於)

?>(大於)

?<(小於)

2.關係表達式

關係表達式就是用關係運算符把操作對象連接起來而構成的式子,操作對象可以是各種表達式,對於關係表達式或邏輯表達式,應把其值理解為1(真)或0(假)。例如表達式:

5>(4<5)

由於(4<5)是“真”,所以其值為1,於是該表達式成立,其值為1(即“真”)。

又如,假設x=10,y=5,則表達式

x= =y+5 其值為“真”

(x=3)<5+y 其值也為“真”

x=y

下邊都是合法的關係表達式:

a>b a+5>b-3 (a=100)>(y=50) 'a'<'b' (a>b)>、(b

2.5.5 邏輯運算符和邏輯表達式

1.邏輯運算符

邏輯運算符是對邏輯量進行操作的運算符。邏輯量隻有兩個值,“真”和“假”,它們分別用1和0表示。C語言中有三個邏輯運算符,即:

?!(邏輯非)

?&&(邏輯與)

?||(邏輯或)

邏輯運算符&&和||是雙目運算符,!是單目運算符,它們的操作對象是邏輯量或表達式(可以是關係表達式或邏輯表達式),其操作結果仍是邏輯量。例如:

x && y當x和y均為“真”時,其結果為“真”,隻有二者均為“假”時,其結果才為“假”。

x | | y當x和y之一為“真”時,其結果為“真”,隻有二者均為“假”時,其結果才為“假”。

!(a>b)當(a>b)為假時,其結果為“真”,否則為“假”。

(x>y)&&(a>b)當x>y和a>b之中有一個滿足時,其結果為真。

(x>y)| |(a>b)當x>y和a>b之中有一個滿足時,其結果為真。

2.邏輯表達式

邏輯表達式是用邏輯運算符把操作對象(可以是關係表達式或邏輯表達式)連起來所構思的一種運算式子,其操作結果是“真(非零)”或“假(零)”。在處理邏輯表達式時要注意邏輯運算符的優先級及結合性,邏輯運算符的優先級從高到低的順序依次是“!”、“&&”、“||”。“&&”和“||”的優先級低於關係運算符和算術運算符,而“!”高於基本算術運算符。“&&”和“||”的結合性是自左至右,而“!”是自右至左,例如:

x>y&& ay)&&(a

x! =y && a>=c+5 相當於(x! =y)&&( a>=c+5)

! x && a = = c 相當於(! x)(&& a = = c)

有時為了提高程序的可讀性,經常把邏輯運算符兩邊的表達式加上一對括號,如上麵的“x>y&& ay)&&(a

在C語言中,邏輯表達式或關係表達式的取值,“真”和“假”用0表示。但在處理邏輯表達式中,當判斷一個量是否為“真”時,是看它是否為非0,對於非0則視為“真”,對於0則視為“假”。例如:

當x=5,y=1.5,z='a'時,則!x,!y,!z均為“假”,即為0。

當x=5,y=3時,x & & y的值為1,因為x和y均為非0。

2.5.6 三項條件運算符

三項條件運算符是C語言中惟一具有三個操作對象的運算符,它具有如下的語法形式:

表達式1? 表達式2: 表達式3

其處理過程是先處理“表達式1”,當“表達式1”為“真”時,則對“表達式2”進行計算;否則對“表達式3”進行計算。用三項條件運算符構成的表達式叫三頂條件運算表達式,其結果是一個算術值,它或者是“表達式2”,或者“表達式3”。例如:

a>8?b+10:b-20

先處理條件表達式a>8,當它為“真”時,則計算b+10,而此時該三項條件運算表達式的值為b+10;否則計算b-20,該三項條件運算表達式的結果為b-20。在處理三項條件運算表達式時應注意如下幾點:

?在三項條件運算表達式中,“表達式1”是條件表達式,而“表達式2”和“表達式3”可以是其他的表達式

?三項運算表達式準許嵌套,這種嵌套是右結合的,即先計算右邊的三項運算。例如:

int a,b,c,d,e

a=15;

b=20;

c=25;

d=30;

e=a>b?c:c>d?b:d

按照三頂條件運算符的結合規則,上邊二式相當於:

e=a>b?c:(c>d?b:d)

上述表達式中,先求解(c>d?b:d),由於c比d小,“表達式1”的結果為“假”,因此其結果為“表達式3”的值,即30,然後求解e=a>b?c:30,由於a比b小,此時“表達式1”的值仍為假,結果仍取“表達式3”的值,最後結果e=30。

?在程序中,常把三頂條件運算表達式的結果賦給某個變量。例如:

result=(x % 2= = 0)?0:1;

當x是偶數時,則result=0,否則result=1。

y=x>0?x:-x

該三項條件計算表達式將x的絕對值賦給y。

ch=(c>='a' & & c<='z')?c-'a'+'A':c

該式把c中字母轉換為大寫賦給ch變量。

2.5.7 其他運算符

1.逗號運算符和逗號表達式

C語言中逗號也是一種運算符。用逗號把幾個運算表達式連接起來所構成的表達式叫逗號表達式。例如:

a=15,b=a*5,z-=y,a+6

上式是下一個逗號表達式。它是由四個表達式結合而成。逗號表達式的運算次序是自左而右逐個進行運算,最後一個表達式的結果就是逗號表達式的運算結果。例如逗號表達式:

a=15,a*10,a+8

上式結果是158。

在C語言程序中,也可以用逗號表達式來給一個變量賦值。例如:

z=(x=15,y=x+25,y * x + 30)

那麼z的值是630。

2.求字節數運算符

sizeof是求其操作對象所占用字節數的運算符。它是在編譯源程序時,求出其操作對象所占字節數的,它實際上是一個函數。其操作對象可以是類型標識符,也可以是表達式。它有如下兩種表達形式:

sizeof(類型標識)

sizeof表達式

如:

sizeof(double)的值是8,表明雙精度浮點數占用8個字節。

float b[10];

sizeof(b)的值是40,因為一個float對象占4個字節。

sizeof(char)的值為1,說明字符型數據占1個字節。

2.6 位運算符

由於C語言是介於高級語言和彙編語言之間的一種中級語言,它是為開發係統軟件而設計的,它可以直接對地址進行運算,因此,C語言提供了位運算的功能。

計算機中的位運算是針對二進製代碼進行的。每一個二進製位的取值隻有0或1。位運算符的操作對象是一個二進製位集合,如一個字節(8bit)。C語言提供了如表2-7所示的位運算符。

表2-7 位運算符

運算符 名稱 使用格式

~ 按位取反 ~表達式

< < 左移位 表達式1< <表達式2

> > 右移位 表達式1> >表達式2

& 按位與 表達式1 &表達式2

^ 按位異或 表達式1^表達式2

丨 按位或 表達式1丨表達式2

2.6.1 按位取反運算符

按位取反運算符就是將其操作對象中的據有二進製位全部改變狀態,即“逢0變1,逢1變0”。例如,八進製數0217,(即二進製10001111),其按位取反後為八進製數0160(即二進製位01110000)。所以~0217的值是0160。又如,

unsigned char x=0137; / *即二進製01011111 * /

x=~ x /* x的二進製結果為10100000 * /

2.6.2 移位運算符

移位運算符有左移運算符和右移運算符。

1.左移運算符

左移運算符是將其操作對象向左移動指定的位數,每左移1位相當於乘以2,移n位相當於乘以2的n次方。一個二進製位組在左移時右邊補0,移幾位右邊補幾個0。其一般書寫格式為:

表達式1<<表達式2

其中“表達式1”是被左移對象,“表達式2”給出左移位數。例如,表達式x << 4的結果就是將x 左移4位。左邊移出的位被舍棄。例如,表達式0377<<4,其結果為0360,即11111111左移4位後為11110000。

2.右移運算符

右移運算符是將其操作數向右移動指定的位數,右移操作相當於除以2,右移n位相當於除以2的n次方。在進行右移時,右邊移出的二進製位被舍棄。其一般書寫格式為:

表達式1>>表達式2

其中“表達式1”是被移對象,“表達式2”給出移動位數。例如,表達式x>>2的結果就是將x右移2位。例如,表達式0377>>4的結果為017。它相當於將二進製數11111111右移4位,結果為00001111。

2.6.3 按位“與”、按位“或”、按位“異或”

1.按位“與”

按位“與”的一般書寫格式為:

表達式1&表達式2

其中“表達式1”和“表達式2”均為整型表達式。

按位“與”遵循這樣的原則:當兩個操作對象的相應二進製位都為1時,則該位的結果為1,否則為0,即“兩1為1,其餘為0”。值得注意的是,按位“與”的運算,兩個表達式之間用一個“&”符,而邏輯“與”,兩個表達式之間用兩個“&&”,這是初學者經常出錯的地方。例如:

15&26

第一個操作數的二進製表示為00001111,第二個操作數的二進製表示為00011010,按位“與”後的二進製表示為00001010。

我們可利用按位與來獲取指定位的值。例如,假設x是一般的unsigned類型的整型數(2個字節),我們想獲取其低字節的值時,隻需將x與0377相與既可。例如:

y=x & 0377

其中x的二進製表示為0101000101110010,0377的二進製表示為0000000011111111,y 的二進製表示為0000000001110010還可以利用按位“與”來測試指定的位是否為0。例如,想測試上例中x的從左數第四位是否為0,則隻需將它與010000(八進製)按位“與”(即y=x &010000)。若y為0說明被測位為0,否則為1。x的二進製表示為0101000101110010,010000的二進製表示為0001000000000000,計算結果為0001000000000000。

2.按位“或”

按位“或”遵循這樣的原則:當兩個操作對象的相應二進製位都為0時,則該對應位的按位“或”結果才為0,否則為1,可以簡記為“兩0為0,其餘為1”。例如:

35|41:

35的二進製表示為00000000001000011,41的二進製表示為0000000000101001,按位“或”的結果為0000000000101011。

按位“或”的一般書寫格式為:

表達式1|表達式2

其中“表達式1”和“表達式2”是整型表達式。

我們可利用按位“或”來將指定位設置為1。例如,將x的從右數第三位(二進製位)設置為1,則隻需執行如下表達式即可:

x = x | 04

x的二進製表示為0111100001000011,04的二進製表示為0000000000000100,按位“或”的結果為0111100001000111。

3.按位“異或”

按位“異或”遵循這樣的原則:當其兩個操作對象的相應位相同時,則該對應位“異或”的結果為0。可以簡記為“相同為0,不同為1”,即0^0=0,0^1=1,1^1=0。按位“異或”也可稱不進位加,即兩個操作對象執行二進製相加,但不向高位進位。例如:

73^81

73的二進製表示為0000000001001001,81的二進製表示為0000000001010001,按位“異或”結果為0000000000011000。所示“異或”的意思是判斷兩個相應的二進製位是否相“異”。如果相“異”則結果為“真”(即為1),否則為“假”(即為0)。利用按位“異或”可使一個數的各二進製位翻轉。例如要使x的各位翻轉,隻需執行如下的表達式:

x=x^0177777

其中:x的二進製表示為0101000101110010,“異或”後的結果為1010111010001101。

2.7 C語言的基本輸入/輸出函數

C語言中的基本輸入輸出函數,是初學者必須熟練掌握的基本內容之一。由於C語言本身不像其他某些高級語言一樣有輸入和輸出語句,其輸入和輸出是由標準的輸入和輸出函數完成的。本節將介紹標準函數庫中部分常用的輸入和輸出函數,這些函數的原則均在特定的頭文件中定義,因此,使用輸入和輸出函數,在程序的開頭要嵌入相應的頭文件。要正確使用各個函數,必須從以下幾方麵理解它們:

?函數的引用格式

?函數的功能

?函數參數的個數、類型、含義及順序

?返回值的類型及含義

?要使用的頭文件

標準函數雖然是外部函數,但引用時用戶不需另加說明,因為他們的說明已包含在相應的頭文件中。引用標準文件的輸入/輸出函數時,要求使用stdio.h頭文件。

2.7.1 字符輸入/輸出函數

1.字符輸入函數getchar()

(1)功能

該函數從標準輸入設備(通常是鍵盤)上讀入一字符。

(2)調用格式

c=getchar()

當執行此函數調用語句時,變量c獲得一個從標準設備上讀取的字符代碼值。當從鍵盤上輸入^z(即ctrl與z鍵同時按下)時,c得到的值是-1。^z稱文件結尾,在程序中經常使用符號常量EOF表示(End of File)。用此函數時,也要求在程序第一行有預編譯命令(也稱嵌入頭文件)#include

【例2-3】getchar()函數的應用。

# include < stdio.h >

main()

{

int c;

printf("input a character:");

c=getchar(); / * 從鍵盤讀入字符 * /

printf("The character inputed is % c\ n",c); / * 在屏幕上輸出字符 * /

}

運行該程序時,提示作者輸入一個字符(input a character),然後在終端上以字符格式輸出所輸入的字符。其操作及輸出情況如下:

input a character:A<CR>

A

2.字符輸出函數putchar()

(1)功能

該函數向標準輸出設備(通常是顯示終端)輸出一字符。使用此函數時,要求在程序首行有#include 預編譯命令。

(2)調用格式

putchar(c);

其中c是一個字符型變量或整型變量,其值被看作是要輸出字符的代碼,它被輸出到顯示終端上。