日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2.2.3 C语言中的整数类型及类型转换(为什么强制类型转换值发生改变?带你从机器码的角度分析)

發布時間:2024/10/14 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2.2.3 C语言中的整数类型及类型转换(为什么强制类型转换值发生改变?带你从机器码的角度分析) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄:

    • 首先看一下c語言整數數據類型范圍
    • 1.有符號數和無符號數的轉換(相同字長)
    • 2.不同字長整數之間的轉換
      • (1)大字長變量向小字長變量強制類型轉換
      • (2)小字長變量向大字長變量強制類型轉換


首先看一下c語言整數數據類型范圍

注意:數值范圍沒有負數的則為無符號位的數,有負數范圍的則為有符號位的數

輸出時:
%u無符號十進制整數
%d有符號十進制整數
%0無符號八進制
%x無符號十六進制整數
在計算機中數據都是以補碼形式存儲的,%u無符號輸出,沒有符號位,是正數;%d有符號輸出,有符號位,符號位在最高位。

1.有符號數和無符號數的轉換(相同字長)

  • 我們在C語言中常利用強制類型轉換,有時候強制類型轉換的結果卻不是我們希望得到的,因為計算機存儲數據是以補碼形式存儲的。
  • 有時候強制類型轉換可能會改變數值,可能是數據類型有無符號位導致的。
  • 無符號位是正數就不用轉換,因為正數原碼=補碼
  • 有符號位的數,根據符號位是0還是1來判斷是否需要轉換,那么如果符號位是1,是負數就要轉換,數值當然會不同。
  • 現在我們看一段代碼來看一下這種特殊情況:
#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) {short x=-4321;unsigned short y=(unsigned short)x;printf("x=%d,y=%u\n",x,y);return 0; }

  • 我們可以看出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; }

  • 這里我們轉換成十六進制輸出
#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;//無符號數,直接取當前數據類型長度的原數字x的補碼長度,不用轉換成原碼輸出unsigned int v=u;printf("x=%d,y=%d\n",x,y); printf("u=%x,v=%u\x",u,v);return 0; }

  • 我們發現,短字長整數到長字長整數的轉換,不僅要使相應的位置相等,高位部分還會擴展為原數字的符號位。
  • 注意:char類型為8位ASCII碼整數,轉換成int型時,高位部分補0即可。ASCII碼由7位二進制數字組成。

總結

以上是生活随笔為你收集整理的2.2.3 C语言中的整数类型及类型转换(为什么强制类型转换值发生改变?带你从机器码的角度分析)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。