C語言運算中的資料型別自動轉換原則

2021-08-21 03:35:37 字數 3667 閱讀 9442

1、隱式轉換

c在以下四種情況下會進行隱式轉換:

1、算術表示式中,低型別能夠轉換為高型別。

2、賦值表示式中,右邊表示式的值自動隱式轉換為左邊變數的型別,並賦值給他。

3、函式呼叫中引數傳遞時,系統隱式地將實參轉換為形參的型別後,賦給形參。

4、函式有返回值時,系統將隱式地將返回表示式型別轉換為返回值型別,賦值給呼叫函式。

2、算數運算的隱式轉換

算數運算中,首先有如下型別轉換規則:

1、字元必須先轉換為整數(c語言規定字元型別資料和整型資料之間可以通用) 。

2、short型轉換為int型(同屬於整型) 。

3、float型資料在運算時一律轉換為雙精度(double)型,以提高運算精度(同屬於實型) 。

其次,有下面的規則。

當不同型別的資料進行操作時,應當首先將其轉換成相同的資料型別,然後進行操作,轉換規則是由低階向高階轉換。轉換規則如下圖所示:

有符號數與無符號數之間運算問題

以下實驗均在virual c++6中執行通過

這個問題測試是否懂得c語言中的整數自動轉換原則,有些開發者懂得極少這些東西。當表示式中存在有符號型別和無符號型別時所有的運算元都自動轉換為無符號型別。因此,從這個意義上講,無符號數的運算優先順序要高於有符號數,這一點對於應當頻繁用到無符號資料型別的嵌入式系統來說是丰常重要的。

首先進行乙個實驗,分別定義乙個signed int型資料和unsigned int型資料,然後進行大小比較:

unsigned int a=20;

signed int b=-130;

a>b?還是b>a?實驗證明b>a,也就是說-130>20,為什麼會出現這樣的結果呢?

這是因為在c語言操作中,如果遇到無符號數與有符號數之間的操作,編譯器會自動轉化為無符號數來進行處理,因此a=20,b=4294967166,這樣比較下去當然b>a了。

再舉乙個例子:

unsigned int a=20;

signed int b=-130;

cout< < b+30 << std::endl

輸出為-100。

而對於浮點數來說,浮點數(float,double)實際上都是有符號數,unsigned 和signed字首不能加在float和double之上,當然就不存在有符號數根無符號數之間轉化的問題了。

一、unsigned int變數跟int型別的變數運算時得出的結果是什麼型別的?

1、先看乙個有趣的例子:

int a = 3;

unsigned int b = -6;

printf("%d\n", a+b);

if((a+b)>0)

else

return 0;

}

執行結果:

-3 yes

1 2

3 看到這個執行結果,很多小夥伴開始疑惑了?unsigned int型別怎麼可以賦值乙個-6?既然列印出來結果是-3<0,為什麼還列印出來是yes?有這些問題的小夥伴且聽我娓娓道來。

(1)必須知道的是:

①int型別和unsigned int型別的差別。unsigned int型別比int型別的容量大是因為,unsigned int是無符號型別的,所以最高位不表示正負,而int型別的最高位是表示正負的,1表示負數,0表示正數。

②計算機中負數的儲存方式——其補碼。在計算機中,負數儲存的方式都是以其其補碼形式儲存,例如:6在計算機的儲存形式是0000 0000 0000 0110(32位計算機中),而-6是1000 0000 0000 0110 (32位機下)(最高位是符號位),補碼也就是1111 1111 1111 1010(32位計算機中),補碼=原碼取反+1。

③賦值乙個負數給unsigned int型別的變數,它的意思就是將-6這個數的補碼形式(1111 1111 1111 1010(32位機下))形式存到乙個叫b的空間中,下次我讀取這個數的時候,是使用b這個名字,按照b這個名字的型別來讀取的,所以當b是unsigned int型別的時候,就不考慮最高位是符號位,則b = 1111 1111 1111 1010(32位機下)(因為是無符號),當b是int型別的時候,考慮最高位是符號位(1為負數,0為正數),當發現是1的時候也就是負數的時候,計算機會把它轉換成為原碼從而讀出是-6。所以乙個變數的型別是決定讀取這個變數儲存的數的方式。

④隱式轉換。當unsigned int型別與int型別運算時,如果沒有指出轉換的型別,它會進行「隱式轉換」轉換為unsigned int型別,也可以記住,不同型別進行運算時,沒指出轉換的型別時,它會往容量大的那總型別轉換,因為這樣可以更加容易避免溢位嘛。

(2)**分析:

首先,定義了乙個 int a = 3 。a的儲存以3的二進位制形式儲存。 unsigned int b = -6 。b的儲存是以其補碼儲存的,也就是1111 1111 1111 1010(32位機下)。當執行a+b的時候,printf函式要求指定列印出%d,所以,a以int(%d)型別讀取出來,也就是3;b也是以int(%d)型別讀取出來,也就是-6,所以3+(-6)=-3,發現列印結果是-3。而在後面的 if((a+b)>0) 判斷中,(a+b)中並沒有指定讀取的型別,所以就進行隱式轉換,a就轉成unsigned int型別,也就是3;b轉成unsigned int型別,因為b本來的儲存是1111 1111 1111 1010(32位機下),轉成unsigned int型別時不考慮符號位,所以就直接以補碼的形式轉化,也就是65530(32位機下),所以a+b=65533>0,輸出yes。

二、總結

①當乙個int型別的a與unsigned int型別的b相運算時,例如:a+b的時候,如果直接是a+b的話,各個變數就會隱式轉換成為unsigned int的型別再相加。

②當用print函式指定列印的時候,例如:printf(」%d\n」,a+b),就要各個變數轉換為%d的型別再想加。

③當用乙個int c型別去裝這個結果時,如:c=a+b,同理,a和b會根據c的型別去分別轉換跟c一致的型別再去運算。

有如下程式:

void main()

輸出結果為:

15 4294967295

-1 其實運算a+b或者c+b時都是現將其轉化成unsigned int型再進行運算的,

a的補碼為0xffffffff,當將其轉化為無符號數時為4294967295

b的補碼為0x00000010,兩個相加會溢位,結果為0x0000000f,即15

c的補碼為0xffffffef,轉化為無符號數為4294967279,c和b相加為4294967295。它是-1的補碼

其實我們可以肉眼先求出-17+16=-1,然後求出-1的unsigned 值

又有如下:

1. #include

2. /*

3. 當表示式中存在符號型別和無符號型別時

4. 所有的運算元都自動轉換為無符號型別

5. */

6. char getchar(int x,int y)

13. void main()

輸出結果為:

c1 = 1 c2= 2 c3= 2 c4= 1

注意:(-7)+7=0,其unsigned 的值還是0

但是 (-8)+7=-1,其unsigned的值遠遠大於0

C語言運算中的資料型別自動轉換原則

1 隱式轉換 c在以下四種情況下會進行隱式轉換 1 算術表示式中,低型別能夠轉換為高型別。2 賦值表示式中,右邊表示式的值自動隱式轉換為左邊變數的型別,並賦值給他。3 函式呼叫中引數傳遞時,系統隱式地將實參轉換為形參的型別後,賦給形參。4 函式有返回值時,系統將隱式地將返回表示式型別轉換為返回值型別...

php運算資料型別自動轉換

空字串 或 數字0 或0.0 字元 0 或 0 空值 null 沒有成員的陣列 其餘都轉換成布林型 true,包含資源 如果字串為合法的數字字串,則直接轉換成整型 浮點型 如果字串中包含.或 e或e,則轉換成浮點型 否則轉換成整型 非法的數字字串轉換成數值0 布林型true 轉換成數字 1,fals...

C語言資料型別轉換

自動轉換發生在不同資料型別的量混合運算時,由編譯系統自動完成。自動轉換遵循以下規則 若參與運算量的型別不同,則先轉換成同一型別,然後進行運算。轉換按資料長度增加的方向進行,以保證精度不降低。如int型和long型運算時,先把int量轉成long型後再進行運算。所有的浮點運算都是以雙精度進行的,即使僅...