第一篇:4.2 C語言中的強(qiáng)制類型轉(zhuǎn)換
一、自動類型轉(zhuǎn)換
● 字符型變量的值實質(zhì)上是一個8位的整數(shù)值,因此取值范圍一般是-128~127,char型變量也可以加修飾符unsigned,則unsigned char 型變量的取值范圍是0~255(有些機(jī)器把char型當(dāng)做unsighed char型對待,取值范圍總是0~255)?!?如果一個運(yùn)算符兩邊的運(yùn)算數(shù)類型不同,先要將其轉(zhuǎn)換為相同的類型,即較低類型轉(zhuǎn)換為較高類型,然后再參加運(yùn)算,轉(zhuǎn)換規(guī)則如下圖所示。double ←── float 高 ↑ long ↑ unsigned ↑
int ←── char,short 低
● 圖中橫向箭頭表示必須的轉(zhuǎn)換,如兩個float型數(shù)參加運(yùn)算,雖然它們類型相同,但仍要先轉(zhuǎn)成double型再進(jìn)行運(yùn)算,結(jié)果亦為double型。縱向箭頭表示當(dāng)運(yùn)算符兩邊的運(yùn)算數(shù)為不同類型時的轉(zhuǎn)換,如一個long 型數(shù)據(jù)與一個int型數(shù)據(jù)一起運(yùn)算,需要先將int型數(shù)據(jù)轉(zhuǎn)換為long型,然后兩者再進(jìn)行運(yùn)算,結(jié)果為long型。所有這些轉(zhuǎn)換都是由系統(tǒng)自動進(jìn)行的,使用時你只需從中了解結(jié)果的類型即可。這些轉(zhuǎn)換可以說是自動的,但然,C語言也提供了以顯式的形式強(qiáng)制轉(zhuǎn)換類型的機(jī)制?!?當(dāng)較低類型的數(shù)據(jù)轉(zhuǎn)換為較高類型時,一般只是形式上有所改變,而不影響數(shù)據(jù)的實質(zhì)內(nèi)容,而較高類型的數(shù)據(jù)轉(zhuǎn)換為較低類型時則可能有些數(shù)據(jù)丟失。
二、賦值中的類型轉(zhuǎn)換
當(dāng)賦值運(yùn)算符兩邊的運(yùn)算對象類型不同時,將要發(fā)生類型轉(zhuǎn)換,轉(zhuǎn)換的規(guī)則是:把賦值運(yùn)算符右側(cè)表達(dá)式的類型轉(zhuǎn)換為左側(cè)變量的類型。具體的轉(zhuǎn)換如下:(1)浮點型與整型
● 將浮點數(shù)(單雙精度)轉(zhuǎn)換為整數(shù)時,將舍棄浮點數(shù)的小數(shù)部分,只保留整數(shù)部分。
將整型值賦給浮點型變量,數(shù)值不變,只將形式改為浮點形式,即小數(shù)點后帶若干個0。注意:賦值時的類型轉(zhuǎn)換實際上是強(qiáng)制的。(2)單、雙精度浮點型
● 由于C語言中的浮點值總是用雙精度表示的,所以float 型數(shù)據(jù)只是在尾部加0延長為doub1e型數(shù)據(jù)參加運(yùn)算,然后直接賦值。doub1e型數(shù)據(jù)轉(zhuǎn)換為float型時,通過截尾數(shù)來實現(xiàn),截斷前要進(jìn)行四舍五入操作。
(3)char型與int型
● int型數(shù)值賦給char型變量時,只保留其最低8位,高位部分舍棄。
● chr型數(shù)值賦給int型變量時,一些編譯程序不管其值大小都作正數(shù)處理,而另一些編譯程序在轉(zhuǎn)換時,若char型數(shù)據(jù)值大于127,就作為負(fù)數(shù)處理。對于使用者來講,如果原來char型 數(shù)據(jù)取正值,轉(zhuǎn)換后仍為正值;如果原來char型值可正可負(fù),則轉(zhuǎn)換后也仍然保持原值,只是數(shù)據(jù)的內(nèi)部表示形式有所不同。
(4)int型與1ong型
● long型數(shù)據(jù)賦給int型變量時,將低16位值送給int型變量,而將高16 位截斷舍棄。(這里假定int型
占兩個字節(jié))。
將int型數(shù)據(jù)送給long型變量時,其外部值保持不變,而內(nèi)部形式有所改變。
(5)無符號整數(shù)
● 將一個unsigned型數(shù)據(jù)賦給一個占據(jù)同樣長度存儲單元的整型變量時(如:unsigned→int、unsigned long→long,unsigned short→short),原值照賦,內(nèi)部的存儲方式不變,但外部值卻可能改變?!?將一個非unsigned整型數(shù)據(jù)賦給長度相同的unsigned型變量時,內(nèi)部存儲形式不變,但外部表示時總是無符號的。
/*例:賦值運(yùn)算符舉例 */ main(){ unsigned a,b;
int i,j;
a=65535;
i=-1;
j=a;
b=i;
printf(“(unsigned)%u→(int)%dn”,a,j);
printf(“(int)%d→(unsigned)%un”,i,b);}
運(yùn)行結(jié)果為:
(unsigned)65535→(int)-1(int)-1→(unsigned)65535
● 計算機(jī)中數(shù)據(jù)用補(bǔ)碼表示,int型量最高位是符號位,為1時表示負(fù)值,為0時表示正值。如果一個無符號數(shù)的值小于32768則最高位為0,賦給 int型變量后、得到正值。如果無符號數(shù)大于等于32768,則最高位為1,賦給整型變量后就得到一個負(fù)整數(shù)值。反之,當(dāng)一個負(fù)整數(shù)賦給unsigned 型變量時,得到的無符號值是一個大于32768的值。
● C語言這種賦值時的類型轉(zhuǎn)換形式可能會使人感到不精密和不嚴(yán)格,因為不管表達(dá)式的值怎樣,系統(tǒng)都自動將其轉(zhuǎn)為賦值運(yùn)算符左部變量的類型。
● 而轉(zhuǎn)變后數(shù)據(jù)可能有所不同,在不加注意時就可能帶來錯誤。這確實是個缺點,也遭到許多人們批評。但不應(yīng)忘記的是:c面言最初是為了替代匯編語言而設(shè)計的,所以類型變換比較隨意。當(dāng)然,用強(qiáng)制類型轉(zhuǎn)換是一個好習(xí)慣,這樣,至少從程序上可以看出想干什么。
==
在C語言中,不同數(shù)據(jù)類型的運(yùn)算對象進(jìn)行混合運(yùn)算,或者需要將一個表達(dá)式的結(jié)果轉(zhuǎn)換成期望的類型時,就需要依據(jù)數(shù)據(jù)類型轉(zhuǎn)換規(guī)則進(jìn)行轉(zhuǎn)換。具體有以下幾種情況:
2.8.1各類數(shù)值型數(shù)據(jù)間混合運(yùn)算時的類型轉(zhuǎn)換規(guī)則
整型、實型、字符型數(shù)據(jù)間可以混合運(yùn)算。在這種情況下,需要將不一致的數(shù)據(jù)類型轉(zhuǎn)
換成一致的數(shù)據(jù)類型,然后進(jìn)行運(yùn)算。為了保證運(yùn)算精度,系統(tǒng)在運(yùn)算時的轉(zhuǎn)換規(guī)則是將存儲長度較短的運(yùn)算對象轉(zhuǎn)換成存儲長度較長的類型,然后再進(jìn)行處理。這種轉(zhuǎn)換是系統(tǒng)自動進(jìn)行的,具體如圖2-9所示。
double ←── float 高 ↑ long ↑ unsigned ↑
int ←── char,short 低
對圖2-9的說明如下:
1)縱向箭頭表示必定會進(jìn)行的轉(zhuǎn)換,如float型數(shù)據(jù)必先轉(zhuǎn)換為double型數(shù)據(jù),然后與其他操作數(shù)進(jìn)行運(yùn)算。與此類似,char型或short型數(shù)據(jù)必先轉(zhuǎn)換為int型數(shù)據(jù),然后進(jìn)行運(yùn)算。
2)橫向箭頭表示當(dāng)運(yùn)算對象為不同類型數(shù)據(jù)時的轉(zhuǎn)換方向,如int型數(shù)據(jù)與unsigned型數(shù)據(jù)進(jìn)行運(yùn)算,int型轉(zhuǎn)換為unsigned型后方可進(jìn)行運(yùn) 算。int型數(shù)據(jù)與double型數(shù)據(jù)進(jìn)行運(yùn)算,int型直接轉(zhuǎn)換為double型后進(jìn)行運(yùn)算,不能理解為先轉(zhuǎn)換為unsigned int型,然后轉(zhuǎn)換為long int型,最后再轉(zhuǎn)換為double型。
2.8.2 賦值時的類型轉(zhuǎn)換
當(dāng)賦值運(yùn)算符兩側(cè)的類型不同時,需進(jìn)行類型轉(zhuǎn)換,這種轉(zhuǎn)換也是系統(tǒng)自動進(jìn)行的。具體轉(zhuǎn)換原則如下:
1)float、double型賦值給int型:直接截斷小數(shù)。
例如:int i=f+0.6;f的值4.0,右邊算術(shù)表達(dá)式運(yùn)算后的結(jié)果為一個值為4.6的double型數(shù)據(jù),根據(jù)上述轉(zhuǎn)換原則,直接舍棄小數(shù),所以i的值為4。2)int、char型賦值給float、double型:補(bǔ)足有效位以進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換。
例如:float f=4;float為7位有效數(shù)字,所以f的值為4.000000。3)char型(1字節(jié))賦值給int型(2字節(jié)):數(shù)值賦給int的低8位,高8位補(bǔ)0。
4)long int型賦值給int型:long int截斷低字節(jié)給int型。
5)int 型賦值給long int:賦給long int的低16位,如果int的最高位是0,則long int的高16位全為0;如果int的最高位是1,則long int的高8位全為1(稱為“符號擴(kuò)展”)。
6)unsigned int型賦值給int型:直接傳送數(shù)值。
7)非unsigned數(shù)據(jù)型賦值給位數(shù)相同的unsigned 數(shù)據(jù):直接傳送數(shù)值。
2.8.3 強(qiáng)制類型轉(zhuǎn)換
除了以上的兩種自動類型轉(zhuǎn)換外,在C語言中,允許強(qiáng)制類型轉(zhuǎn)換,將某一數(shù)據(jù)的數(shù)據(jù)類型轉(zhuǎn)換為指定的另一種數(shù)據(jù)類型。強(qiáng)制轉(zhuǎn)換是用強(qiáng)制轉(zhuǎn)換運(yùn)算符進(jìn)行的,強(qiáng)制轉(zhuǎn)換運(yùn)算符為:(類型名),強(qiáng)制轉(zhuǎn)換運(yùn)算符組成的運(yùn)算表達(dá)式的一般形式為:
(類型名)(表達(dá)式)例如:
(int)(x + y)//將x+y的值轉(zhuǎn)換成整型,即取整數(shù)部分。(float)x + y //將x轉(zhuǎn)換成單精度型。
強(qiáng)制轉(zhuǎn)換運(yùn)算符優(yōu)先級比算術(shù)運(yùn)算符高。同表達(dá)式中數(shù)據(jù)類型的自動轉(zhuǎn)換一樣,強(qiáng)制類型轉(zhuǎn)換也是臨時轉(zhuǎn)換,對原運(yùn)算對象的類型沒有影響。
例如,已知有變量定義:int b=7;float a=2.5,c=4.7;求下面算術(shù)表達(dá)式的值。
a+(int)(b/3*(int)(a+c)/2.0)%4;
根據(jù)運(yùn)算符結(jié)合性規(guī)則,上述表達(dá)式要自左之右執(zhí)行,b/3為2,2*int(a+c)為14,14/2.0為7.0,強(qiáng)制類型轉(zhuǎn)換后為7,7%4為3;a的值2.5與3相加,最終結(jié)果為5.5。
第二篇:c語言中swap問題小結(jié)
#include
printf(“swap1: x:%d,y:%dn”,x,y);//形參傳值,不能交換,實際傳過去是拷貝的一份,沒改變主函數(shù)中x,y swap2(&x,&y);
printf(“swap2: x:%d,y:%dn”,x,y);//不能交換,函數(shù)中只是地址交換了下,地址指向的內(nèi)容沒有交換 swap3(&x,&y);
printf(“swap3: x:%d,y:%dn”,x,y);//能交換,地址指向的內(nèi)容進(jìn)行了交換 swap4(&x,&y);
printf(“swap4: x:%d,y:%dn”,x,y);//能交換,地址指向的內(nèi)容進(jìn)行交換 swap5(&x,&y);
printf(“swap5: x:%d,y:%dn”,x,y);//能交換,地址指向的內(nèi)容進(jìn)行交換 return 0;} swap1: x:4,y:3 swap2: x:4,y:3 swap3: x:3,y:4 swap4: x:4,y:3 swap5: x:3,y:4
第三篇:C語言中的文本Txt操作
對于文件使用方式有以下幾點說明:
1)文件使用方式由r,w,a,t,b,+六個字符拼成,各字符的含義是:
r(read):
讀
w(write):
寫
+:
讀和寫
a(append):
追加
t(text):
文本文件,可省略不寫
b(banary):
二進(jìn)制文件
2)用“r”打開一個文件時,該文件必須已經(jīng)存在,且只能從該文件讀出。
3)用“w”打開的文件只能向該文件寫入。若打開的文件不存在,則以指定的文件名建立該文件,若打開的文件已經(jīng)存在,則將該文件刪去,重建一個新文件。
4)若要向一個已存在的文件追加新的信息,只能用“a”方式打開文件。但此時該文件必須是存在的,否則將會出錯。
5)在打開一個文件時,如果出錯,fopen將返回一個空指針值NULL。在程序中可以用這一信息來判別是否完成打開文件的工作,并作相應(yīng)的處理。
將一個txt文本里的數(shù)排序再輸出到另一個文本里
#include“stdio.h” #include“stdlib.h” main(){
FILE *p1,*p2;int a[10],i,j,temp;if((p1=fopen(“E:in.txt”,“r”))==NULL)
{
printf(“cannot open filen”);
exit(0);} if((p2=fopen(“E:out.txt”,“w”))==NULL){
printf(“cannot open filen”);
exit(0);} for(i=0;i<10;i++)fscanf(p1,“%d”,&a[i]);for(i=0;i<10;i++){
for(j=0;j<10-i;j++)
if(a[j]>a[j+1])
temp=a[j+1];
a[j+1]=a[j];
a[j]=temp;}
for(i=0;i<10;i++)fprintf(p2,“%d”,a[i]);}
第四篇:C語言中union應(yīng)用總結(jié)
C語言中union應(yīng)用總結(jié)
定義共用體的類型變量的一般形式為: union 共用體名 {
成員列表; }變量列表; 例如: union data {
int i;
unsigned char c[4];
float f;};union data a;//定義union類型的變量
共用體變量a中的成員i、c、f三個變量在內(nèi)存中從同一個地址開始存儲,即在同一個內(nèi)存中可以用來存放幾種不同類型的數(shù)據(jù);共用體變量a所占內(nèi)存的長度等于最長成員的長度,這里c[4]和f的長度都為4字節(jié)。例如進(jìn)行如下賦值: a.i = 100;a.f = 100.5;那么此時共用體變量a中的成員i已經(jīng)沒有值了,因為存儲該值的內(nèi)存現(xiàn)在已經(jīng)被用來存儲成員f的值了。共用體成員間是共享內(nèi)存的,對共用體的一個成員賦值,其他成員的值跟著發(fā)生變化。利用共用體成員間是共享內(nèi)存的這一特性,有以下幾種應(yīng)用:
1、在需要將浮點數(shù)據(jù)轉(zhuǎn)移時,使用共同體,按4個字節(jié)的char型數(shù)據(jù)傳輸,帶來通信效率的提高。一般浮點數(shù)發(fā)送方法:是將浮點數(shù)放大一定的倍數(shù),再取整,再按整數(shù)的高低位傳輸。還需要傳輸這個放大的倍數(shù),如果浮點數(shù)是個負(fù)數(shù)的話,還要將符號位一并發(fā)送。接收方收到這幾條報文后,才能將數(shù)據(jù)還原。但是接收方還原的浮點數(shù)據(jù)與發(fā)送方發(fā)送的浮點數(shù)不一樣,因為小數(shù)位數(shù)發(fā)生變化。使用共同體就不會出現(xiàn)這個問題了,在 接收方,使用共同體,將收到到的4個char數(shù)據(jù)賦值給a.c數(shù)組,a.f就是還原的數(shù)據(jù),這個數(shù)據(jù)和發(fā)送的數(shù)據(jù)是一樣的,也不管發(fā)送的浮點數(shù)是正還是負(fù)。如有a.f =-12.34;則a.c[0] = 0xa4, a.c[1] = 0x70, a.c[2] = 0x45, a.c[3] = 0xc1。如有a.c[0] = 0xa4, a.c[1] = 0x70, a.c[2] = 0x45, a.c[3] = 0xc1,則a.f =-12.34。使用這種方式傳輸浮點數(shù),數(shù)據(jù)是不會丟失的,報文也更簡單。
2、將浮點數(shù)保存到文件中時,保存為4個字節(jié)的char型數(shù)據(jù),節(jié)約空間。如果保存為文本需要占用的字節(jié)數(shù)等于數(shù)值的字符的個數(shù),有可能占用1~20字節(jié),而用共用體的char型數(shù)據(jù),占用的空間大小固定為4字節(jié),對大量浮點數(shù)據(jù)的存儲,節(jié)約的空間更多,分析保存的浮點數(shù)也是很方便的。
3、用在強(qiáng)制類型轉(zhuǎn)換上。如將int數(shù)據(jù)轉(zhuǎn)為float,可以這樣使用union: a.i =1234;賦值后,a.f就是轉(zhuǎn)換后的值等于1234。
第五篇:C語言中的EOF
C語言中的EOF EOF是指文件的結(jié)束符,是一個宏定義.對于鍵盤輸入來說,getchar()只有在遇到文本結(jié)束標(biāo)記(ASCII編碼為26)時才會返回EOF,其它情況都會返回一個輸入符號值。所以對于這種程序,要想讓循環(huán)信息運(yùn)行,只能輸入這個文本結(jié)束標(biāo)記。輸入這個標(biāo)記有多種方法,常用的就是按F6鍵,或者按Ctrl-Z組合鍵,或者打開數(shù)字小鍵盤之后按住Alt鍵再依次按小鍵盤上的26兩個數(shù)字鍵最后放開Alt鍵,等,都可以輸入這個文本結(jié)束標(biāo)記。
借助于getchar 與putchar 函數(shù),可以在不了解其它輸入/輸出知識的情況下編寫出數(shù)量驚人的有用的代碼。最簡單的例子就是把輸入一次一個字符地復(fù)制到輸出,其基本思想如下: 讀一個字符
while(該字符不是文件結(jié)束指示符)輸出剛讀入的字符 讀下一個字符
將上述基本思想轉(zhuǎn)換為C語言程序為: #include
字符在鍵盤、屏幕或其它的任何地方無論以什么形式表現(xiàn),它在機(jī)器內(nèi)部都是以位模式存儲的。char 類型專門用于存儲這種字符型數(shù)據(jù),當(dāng)然任何整型(int)也可以用于存儲字符型數(shù)據(jù)。因為某些潛在的重要原因,我們在此使用int類型。
這里需要解決如何區(qū)分文件中有效數(shù)據(jù)與輸入結(jié)束符的問題。C語言采取的解決方法是:
在沒有輸入時,getchar 函數(shù)將返回一個特殊值,這個特殊值與任何實際字符都不同。這個值稱為EOF(end of file,文件結(jié)束)。我們在聲明變量c 的時候,必須讓它大到足以存放getchar函數(shù)返回的任何值。這里之所以不把c聲明成char類型,是因為它必須足夠大,除了能存儲任何可能的字符外還要能存儲文件結(jié)束符EOF。因此,我們將c聲明成int類型。
EOF 定義在頭文件
對于經(jīng)驗比較豐富的C 語言程序員,可以把這個字符復(fù)制程序編寫得更精煉一些。在C語言中,類似于c = getchar()之類的賦值操作是一個表達(dá)式,并且具有一個值,即賦值后左邊變量保存的值。也就是說,賦值可以作為更大的表達(dá)式的一部分出現(xiàn)。如果將為c賦值的操作放在while循環(huán)語句的測試部分中,上述字符復(fù)制程序便可以改寫成下列形式: #include
c =(getchar()!= EOF)