網站首頁 編程語言 正文
前言
想要弄清什么是無符號,什么是有符號,就需要先知道數據在計算機內是如何存儲的
數據是如何儲存的
在計算機內,數據都是以二進制的零一串的形式儲存的,并且稱帶符號的二進制數稱為機器數
整數機器數有3種形式:原碼、反碼、補碼
- 二進制的最高位是符號位:0代表正數,1代表負數。“無符號”和“有符號“中的”符號“就值得是這個符號位。
- 按照一個數的正負,直接寫出它的二進制表示形式就是原碼
- 正數的原碼、反碼、補碼是相同的
- 負數的原碼、反碼、補碼要經過計算的
- 反碼:原碼的符號位不變,其他位按位取反
- 補碼:反碼+1
- 在內存中存儲的形式是補碼
int n = 10
,整形占四個字節(32bit)
00000000000000000000000000001010 原碼
00000000000000000000000000001010 反碼
00000000000000000000000000001010 補碼int n = -10
10000000000000000000000000001010 原碼
111111111111111111111111111111110101 反碼
111111111111111111111111111111110110 補碼
什么叫無符號
前面已經知道,數據是以二進制的形式儲存在內存之中,并且二進制的最高位為符號位
在C語言中,將基本數據類型劃分為
signed
(有符號)和unsigned
(無符號)兩類
在signed
類中,有符號,顧名思義就是二進制的最高位代表著符號位,即0位正數,1為負數。
而在unsigned
中,無符號,就是二進制的最高位不是符號位,它是0或1并不代表著這個二進制數為正或負
- 初始化變量int a = 10它等價于signed int a =10因為關鍵字signed在定義的時候可以省略,C語言中默認是有符號數所以我們以往定義的整形變量都是有符號數字
- 如果想要定義一個無符號數,就必須加關鍵字unsigned,定義一個無符號的10:unsigned int a = 10
- 這里需要注意的一點是:因為無符號數字沒有符號位這個概念,數字連符號都沒有了沒有正負之分,所以它只能表示正數
- 但是無符號數字也能存放負數,這點是無符號數字中最”妙“的點
接下來用unsigned int a = 10
和unsigned int a = -10
舉例進行介紹
10為正數,三碼都一樣,所以10的補碼為
00000000000000000000000000001010
,表面上看有無符號的10的補碼都一致,但是本質上無符號的最高位不是符號位
-10
的原碼為10000000000000000000000000001010
原碼除了符號位,其他取反加1得到反碼:111111111111111111111111111111110101
反碼加1得到補碼:111111111111111111111111111111110110
unsigned int a = -10
然后把-10的補碼存到a
中,所以此時無符號變量a
中存放著:111111111111111111111111111111110110
因為a
為無符號變量,所以111111111111111111111111111111110110
的最好位1
不代表著符號,所以a
的本質就是一個正數,正數原碼、補碼、反碼相同,所以111111111111111111111111111111110110
就是a
所表示數字的原碼,所以輸出時,就會把這個二進制序列直接輸出。
接下來輸出一下無符號a
的值:
int main() { unsigned int a = -10; printf("%u\n", a); //無符號的數用%u輸出 return 0; }
結果為:
這是一個很大的數,我們用計算器驗證一下二進制序列111111111111111111111111111111110110
的十進制數是多少:
所以無符號a輸出的結果就是以-10的補碼為原碼的正數的十進制
例題
例1
一下代碼的結果是:
#include <stdio.h> int i; int main() { i--; if (i > sizeof(i)) { printf(">\n"); } else { printf("<\n"); } return 0; }
A.>
B.<
C.不輸出
D.程序有問題
在C語言中,全局變量,沒有初始化,默認為0,i--
后,i
結果為-1,sizeof(i)
按照i類型大小是4,所以按照此分析,結果應為B,但B選項是錯誤的
正確選項其實為A
因為sizeof
返回值類型為無符號整形,因此編譯器會自動將左側的i
轉換為無符號的整形數據,-1的無符號整形是一個非常大的正數,肯定超過4,所以正確選項為A
例2
//輸出的結果是什么? int i= -20; unsigned int j = 10; printf("%d\n", i+j); //按照補碼的形式進行運算,最后格式化成為有符號整數
- i的原碼是:100000000000000000000000000010100
- i的反碼是:1111111111111111111111111111111101011
- i的補碼是:1111111111111111111111111111111101100
- j 的補碼是:000000000000000000000000000001010
- i+j的補碼是:1111111111111111111111111111111110110
- i+j的原碼是: 100000000000000000000000000001010
- i+j的值為-10,輸出-10
例3
//輸出結果? unsigned int i; for(i = 9; i >= 0; i--) { printf("%u\n",i); }
答案:死循環
分析:因為i
為一個無符號的int
,所以當i
為0時,再減1不會變成負數,反而會變成一個極大的數,必定大于0,然后這個極大的數逐漸-1,當再次等于0時,循環上述的操作,所以此程序是死循環。
總結
原文鏈接:https://blog.csdn.net/weixin_64116522/article/details/127896522
相關推薦
- 2023-10-16 forEach方法如何跳出循環和for方法跳出循環
- 2022-11-21 Kotlin?Fragment的具體使用詳解_Android
- 2022-03-16 Docker安裝Nginx問題及錯誤分析_docker
- 2022-04-14 Python實現簡單購物車小程序_python
- 2022-03-14 使用npm安裝淘寶鏡像(npm配置淘寶鏡像)
- 2023-01-10 Go語言rune與字符串轉換的密切關系解析_Golang
- 2022-04-16 統計C語言二叉樹中葉子結點個數_C 語言
- 2022-05-11 使用git命令上傳代碼_其它綜合
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支