2.2.3 C语言中的整数类型及类型转换(为什么强制类型转换值发生改变?带你从机器码的角度分析)
生活随笔
收集整理的這篇文章主要介紹了
2.2.3 C语言中的整数类型及类型转换(为什么强制类型转换值发生改变?带你从机器码的角度分析)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄:
- 首先看一下c語言整數數據類型范圍
- 1.有符號數和無符號數的轉換(相同字長)
- 2.不同字長整數之間的轉換
- (1)大字長變量向小字長變量強制類型轉換
- (2)小字長變量向大字長變量強制類型轉換
首先看一下c語言整數數據類型范圍
注意:數值范圍沒有負數的則為無符號位的數,有負數范圍的則為有符號位的數
輸出時:
%u無符號十進制整數
%d有符號十進制整數
%0無符號八進制
%x無符號十六進制整數
在計算機中數據都是以補碼形式存儲的,%u無符號輸出,沒有符號位,是正數;%d有符號輸出,有符號位,符號位在最高位。
1.有符號數和無符號數的轉換(相同字長)
- 我們在C語言中常利用強制類型轉換,有時候強制類型轉換的結果卻不是我們希望得到的,因為計算機存儲數據是以補碼形式存儲的。
- 有時候強制類型轉換可能會改變數值,可能是數據類型有無符號位導致的。
- 無符號位是正數就不用轉換,因為正數原碼=補碼
- 有符號位的數,根據符號位是0還是1來判斷是否需要轉換,那么如果符號位是1,是負數就要轉換,數值當然會不同。
- 現在我們看一段代碼來看一下這種特殊情況:
- 我們可以看出y值和x值沒有一點關系,咱們將其都轉換成二進制,我們便知道了為什么。且看二進制轉換表;
我在自己的電腦上測試了一下,由于電腦是64位,所以轉換就是64個二進制數,至于為什么16位往左所有數都是1,這就涉及到了符號擴展,詳情可參考我之前的一篇文章符號擴展
- 去掉符號位補碼轉原碼為下圖所示:
- 其中x為補碼,y為無符號二進制真值,正數的補碼=原碼。因為數在計算機中都是以補碼形式存儲的,正數的補碼是自身,負數的補碼需要轉換,具體轉換參考原碼、反碼、補碼、移碼轉換規則
- unsigned short 為無符號整數,所以它沒有符號位,全是數值位,是正數。
- 而short是有符號的整數,有符號位,符號位在最高位,需要將補碼轉換成原碼輸出。
- 可以看出,強制類型轉換結果相應位置的值不變,僅僅只改變了解釋這些位的方式,是short解釋,還是unsigned short 解釋,這兩種方式。
同樣的我們再看一段代碼仔細揣摩揣摩:
#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) {unsigned short x=65535;short y=(short)x;printf("x=%u,y=%d\n",x,y);return 0; }
- 相應位置數值相等,但是表示結果不同,那是因為解釋方式不同;unsigned short 和short兩種解釋 方式。
2.不同字長整數之間的轉換
(1)大字長變量向小字長變量強制類型轉換
#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) {int x=165537,u=-34991; //int 4B short y=(short)x,v=(short)u; // short 2Bprintf("x=%d,y=%d\n",x,y); printf("u=%d,v=%d\n",u,v);return 0; }- 當大字長變量向小字長變量強制類型轉換時,系統將多余的高位字長部分直接截斷舍去,低位直接賦值
(2)小字長變量向大字長變量強制類型轉換
#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) {short x=-4321; // short 2Bint y=x; // int 4Bunsigned short u=(unsigned short)x;unsigned int v=u;printf("x=%d,y=%d\n",x,y); printf("u=%u,v=%u\n",u,v);return 0; }- 這里我們轉換成十六進制輸出
- 我們發現,短字長整數到長字長整數的轉換,不僅要使相應的位置相等,高位部分還會擴展為原數字的符號位。
- 注意:char類型為8位ASCII碼整數,轉換成int型時,高位部分補0即可。ASCII碼由7位二進制數字組成。
總結
以上是生活随笔為你收集整理的2.2.3 C语言中的整数类型及类型转换(为什么强制类型转换值发生改变?带你从机器码的角度分析)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2.2.2 定点数的运算(移位、原码和补
- 下一篇: 2.2.4 数据的的存储和排列