算術轉化和整型提公升的奧秘

2021-07-28 06:48:53 字數 3351 閱讀 5680

首先請大家先思考一下3個問題,問題相互之間是有關聯的。

1,整型字面值是屬於整型家族9種中的哪一種呢?

2,什麼是算術轉換?如何轉換的?

3,什麼是整型提公升?如何提公升的?為什麼會有整形提公升?

下面解答上述問題。

1,整型字面值是屬於整型家族9種中的哪一種呢?

答案取決於字面值時如何書寫的。比如在整數字面值後面後面新增字元l或l,可以使這個整數被解釋為long整型值,字元u或u則用於把數值制定為unsigned整型值。如果在乙個字面值後面各新增這兩組字元中的乙個,那麼它就解釋為unsigned long整型值。

整型字面值可能int,long或unsigned long。在預設情況下,它是最短型別但能完整容納這個值。

例如:在監視中,我們可以明確的看到編譯器對於整型字面值在計算時是如何儲存的

可以看出即便是再小的數,也會當做是int型,隨著整數的增大,整數的型別也會隨著變大。直到超出最大範圍。

2,什麼是算術轉換?如何轉換的?

算術轉化:如果某個操作符的各個運算元屬於不通過的型別,那麼除非其中乙個運算元轉換為另外乙個運算元的型別,否則操作就無法進行。

下面的層次體系稱為尋常算術轉換(usual arithmetic conversion)

long double

double

float

unsigned long int

unsigned int

intvs文件中常用算術轉換規定。

如果任一運算元是 long double 型別,則將另乙個運算元轉換為 long double 型別。

如果未滿足上述條件,並且任一運算元是 double 型別,則將另乙個運算元轉換為 double 型別。

如果未滿足上述兩個條件,並且任一運算元是 float 型別,則將另乙個運算元轉換為 float 型別。

如果未滿足上述三個條件(所有運算元都不是浮點型),則對運算元執行整型轉換,如下所示:

如果任一運算元是 unsigned long 型別,則將另乙個運算元轉換為 unsigned long 型別。

如果未滿足上述條件,並且任一運算元是 long 型別且另乙個運算元是 unsigned int 型別,則將兩個運算元都轉換為 unsigned long型別。

如果未滿足上述兩個條件,並且任一運算元是 long型別,則將另乙個運算元轉換為 long 型別。

如果未滿足上述三個條件,並且任一運算元是 unsigned int型別,則將另乙個運算元轉換為 unsigned int 型別。

如果未滿足上述任何條件,則將兩個運算元轉換為 int 型別。

換句話說就是:

如果某個運算元的型別在上面這個列表中排名較低,那麼它首先將轉換成另外乙個運算元的型別然後執行。

例子:

int a = -1;

unsigned int b = 0xffffffff;

char c = -1;

if (a > b)

printf("a > b\n");

else if (a == b)

printf("a = b\n");

else

printf("a < b\n");

if (c > sizeof(c))

printf("c > sizeof(c)\n");

輸出:

解析:結果並沒有按照我們想的大小來比較,而是發生了我們沒有看見的隱式算術轉換。

int型別a和unsigned int型別b來運算元''兩邊,比較時,其中a發生算術轉換暫時變為unsigned int a.而-1的補碼和0xffffffff的補碼相同,所以兩數相同。輸出a = b;

同理。sizeof()返回值為size_t型別的1, unsigned int。char c會變為unsigned int c,然後與unsigned int 1比較大小,自然是大於1.

3,什麼是整型提公升?為什麼會有整形提公升?如何提公升的?

概念:c的整型算術運算總是至少以預設整數型別的精度(int)來進行的。為了獲取這個精度,表示式中的字元型和短整型運算元在使用之前被轉化為普通整型,這種轉化稱為整型提公升(integral promotion)。換句話說,在表示式計算時,各種整型首先要提公升為int型別,如果int型別不足以表示則要提公升為unsigned int型別,然後進行表示式的運算。

存在原因:通常情況下,在32位平台下,在對int型別的數值做運算時,cpu的運算速度是最快的。c語言是乙個注重效率的語言,所以它會做整型提公升,使得程式執行速度更快。

提公升規則:有符號的在左邊補上符號位,無符號的在左邊補上0。

想要知道有沒有整型提公升,關鍵還是要看彙編

例子:注意下圖中的彙編語句,對比char和int的不同

可以發現,在初始化a,b,aa,bb時,都是用整型字面值賦值。對於a,b來說只是擷取了其中一部分。但不影響獲得後a,b的內容。

重點:對比 char c = a+b;和int cc = aa+bb;這兩行**的彙編不同;

乙個是movsx,乙個是mov;

movsx:表示帶符號擴充套件,並傳送。

即:在計算c時,a和b進行了符號擴充套件,b和c的值被提公升為普通整型,然後再執行加法運算。加法運算的結果將被截斷,然後在儲存於c中。

下面給出乙個整型提公升方面的經典例子。

char c;

unsigned char uc;

unsigned short us;

c = 128;

uc = 128;

us = c + uc;

printf("ox%x\n", us);

us = (unsigned char)c + uc;

printf("0x%x\n", us);

us = c + (char)uc;

printf("0x%x\n", us);

各位可以試著練練手,畫畫圖。然後與答案對比下。

答案:注意有無符號數字的儲存形式。

如何整型提公升的

注:算術變換和整形提公升的區別:

算術變換主要針對操作符兩邊運算元型別不同,用來解決型別不匹配問題。

整型提公升主要針對運算元是否便於計算,用來解決計算求值問題。

C專家程式設計 整型提公升與尋常算術轉換

1 字元和整型 整型提公升 如果char short int或者int型位段 bit field 包括它們有符號或無符號變型,以及列舉型別,可以使用在需要int或者unsigned int的表示式中。如果int可以完整表示源型別的所有值,那麼該源型別的值就轉換為int,否則轉換為unsigned i...

如何提公升CPM的轉化

不論付費還是免費獲得的 最終目的是為了轉化 變現。為什麼公司自 的轉化比較弱,因為沒有人喜歡看硬廣,公司自 內容的定位往往像銅豌豆一樣硬的不得了。老闆要是看到你發與公司產品關聯不大的內容,多半要找你談話的,在企業負責人眼裡,公司的自 就應該發企業的各種榮譽,資質 好評,這就是俗稱的自嗨。切記,使用者...

表示式隱式型別和整型提公升

算術轉換 c的整型算術運算總是至少以預設整型型別的精度來進行的。為了獲得這個精度,表示式中的字元和短整型運算元在使用之前被轉換為普通整型,這種轉換稱為整型提公升。表示式的整型運算要在cpu的相應運算器件內執行,cpu內整型運算器 alu 的運算元的位元組長度 一般就是int的位元組長度,同時也是cp...