日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

C語言強制類型轉換規則實例詳解_C 語言

作者:qq_43133135 ? 更新時間: 2022-07-30 編程語言

整形之間的強制轉換

在強制類型轉換中,我們常用的整形強制轉換有無符號和有符號類型的強制轉換。所以首先我們得介紹一下計算機中存儲數字的方式,計算機中通常以補碼的形式來存儲數據,以8位數據為例,二進制與有符號數的對應關系為:

0 1 2 127 -128 -127 -1
0000 0000 0000 0001 0000 0010 0111 1111 1000 0000 1000 0001 1111 1111

無符號轉有符號

0 1 2 127 128 129 255
0000 0000 0000 0001 0000 0010 0111 1111 1000 0000 1000 0001 1111 1111

所以對于有符號數,首先最高位是正負的標志位。要將無符號數強制轉化為有符號數時,其內存上的二進制是不會改變的,只是我們對它的解釋變了,即無符號數128強制轉化有符號數即-128。

當然這樣引申出來的一種好處就是對于有符號數的判斷,如

char a;
...
if((a>=0)&&(a<80))
{
....
}

可以使用強制轉化,省去一個判斷條件

char a;
...
if( ((unsigned char)a) < 80)
{
....
}

有符號轉無符號

將有符號數變成無符號數時,情況也類似,如8位的有符號數120轉無符號也是120,但8位的-1轉無符號則為255。所以當我們在有符號數的計算中,想保留大于等于0的數,不能通過強制轉化來完成,必須得加判斷:

char a,b,d;
unsigned char c;
....
c=(unsigned char)(a+b);  (×):當運算結果小于0時c會異常,變成超級大數

d=a+b;
c = (d<0)?0:d;           (√)

不同長度數字轉化中的截斷

比如我有一個8位的有符號數-1,要轉換為一個16位的有符號數,那么結果仍舊是-1。首先我們要明確一點,那就是雖然8位的有符號數-1的二進制原本1111 1111,但載入32位的cpu中運算時,它將轉化為32位的有符號數進行運算,即int類型的-1。所以對于char類型的數據,即使運算結果超過了該類型,其實也不會發生異常:

char a=127,b=127,c=127,e;
int d;
....
e=a+b+c;   	 (×):當運算結果超過存儲類型的表示范圍時,會因截斷產生錯誤
d=a+b+c;     (√):32位的int類型足夠存儲結果。

所以我們如果把不同長度的數字進行類型轉換,只有兩個步驟:

1、將該數表示為32位
2、將32位數截斷為結果類型

不過,可以確定的一點就是,進行第一步時,數的值不會發生變化:

比如8位有符號數-1(1111 1111)將轉化為32位的-1(1111 1111 1111 1111 … 1111 111)。
而8位的無符號數255(1111 1111)轉為32位時,也仍舊是255:(0000 0000…0000 0000 1111 111)。

但進行第二步轉換時,值會由于截斷而發生變化,而這個截斷一般是高位截斷(舍棄高位,保留低位):

如int類型的255(0000 0000 … 0000 0000 1111 1111)轉化為8為的unsigned char類型時,前面的0將被截斷,只保留低8位,即255(1111 1111),當然,若是轉為8為的有符號char類型,則為-1(1111 1111)。截斷是二進制層面的位數截斷,與實際值無關。

整形與浮點數的強制類型轉換

我們都知道浮點數float類型一般遵循ieee754標準,有符號位,階碼和尾數:

與整形相同,符號位是1時代表負數,是0則為正數。而階碼代表小數點在哪兒,類似于科學計數法100會被表示為 1.0 × 10^2。詳細的這里不介紹了,我們重點放在強制轉化上:

對于一個int類型的數,只要在浮點數的表示范圍內,便可以正確的轉為浮點數格式。

但是對于一個浮點類型的數,在轉化為整形時,則會只保留整數位,如:

int a= (int)0.1;    即a=0
int a= (int)1.1;    即a=1
int a= (int)1.5;    即a=1
int a= (int)-1.5;   即a=-1

所以如果要四舍五入之類的的,則不能靠強制轉換,得用相關的函數。當然若是轉為其他整形,則結果將有32位的整形結果進行截斷得到。

當然,強制轉換和 floor 這個函數的功能其實很像,floor函數的功能是向下取整:

int a= floorf(0.1);    即a=0
int a= floorf(1.1);    即a=1
int a= floorf(1.5);    即a=1

對于大于0的浮點數,他倆其實可以替換,而當小于0時,他倆區別很大:

int a= floorf(-0.1);    即a=-1
int a= floorf(-1.1);    即a=-2

int a=(int)-0.1;        即a=0
int a=(int)-1.1;        即a=-1

強制轉化的結果,會產生正負0這種概念,如-0.9到0.9強制轉化結果都為0。使用強制轉化時會產生越界輸出

總結

原文鏈接:https://blog.csdn.net/qq_43133135/article/details/122883705

欄目分類
最近更新