網(wǎng)站首頁 編程語言 正文
前言
想要弄清什么是無符號(hào),什么是有符號(hào),就需要先知道數(shù)據(jù)在計(jì)算機(jī)內(nèi)是如何存儲(chǔ)的
數(shù)據(jù)是如何儲(chǔ)存的
在計(jì)算機(jī)內(nèi),數(shù)據(jù)都是以二進(jìn)制的零一串的形式儲(chǔ)存的,并且稱帶符號(hào)的二進(jìn)制數(shù)稱為機(jī)器數(shù)
整數(shù)機(jī)器數(shù)有3種形式:原碼、反碼、補(bǔ)碼
- 二進(jìn)制的最高位是符號(hào)位:0代表正數(shù),1代表負(fù)數(shù)?!盁o符號(hào)”和“有符號(hào)“中的”符號(hào)“就值得是這個(gè)符號(hào)位。
- 按照一個(gè)數(shù)的正負(fù),直接寫出它的二進(jìn)制表示形式就是原碼
- 正數(shù)的原碼、反碼、補(bǔ)碼是相同的
- 負(fù)數(shù)的原碼、反碼、補(bǔ)碼要經(jīng)過計(jì)算的
- 反碼:原碼的符號(hào)位不變,其他位按位取反
- 補(bǔ)碼:反碼+1
- 在內(nèi)存中存儲(chǔ)的形式是補(bǔ)碼
int n = 10
,整形占四個(gè)字節(jié)(32bit)
00000000000000000000000000001010 原碼
00000000000000000000000000001010 反碼
00000000000000000000000000001010 補(bǔ)碼int n = -10
10000000000000000000000000001010 原碼
111111111111111111111111111111110101 反碼
111111111111111111111111111111110110 補(bǔ)碼
什么叫無符號(hào)
前面已經(jīng)知道,數(shù)據(jù)是以二進(jìn)制的形式儲(chǔ)存在內(nèi)存之中,并且二進(jìn)制的最高位為符號(hào)位
在C語言中,將基本數(shù)據(jù)類型劃分為
signed
(有符號(hào))和unsigned
(無符號(hào))兩類
在signed
類中,有符號(hào),顧名思義就是二進(jìn)制的最高位代表著符號(hào)位,即0位正數(shù),1為負(fù)數(shù)。
而在unsigned
中,無符號(hào),就是二進(jìn)制的最高位不是符號(hào)位,它是0或1并不代表著這個(gè)二進(jìn)制數(shù)為正或負(fù)
- 初始化變量int a = 10它等價(jià)于signed int a =10因?yàn)殛P(guān)鍵字signed在定義的時(shí)候可以省略,C語言中默認(rèn)是有符號(hào)數(shù)所以我們以往定義的整形變量都是有符號(hào)數(shù)字
- 如果想要定義一個(gè)無符號(hào)數(shù),就必須加關(guān)鍵字unsigned,定義一個(gè)無符號(hào)的10:unsigned int a = 10
- 這里需要注意的一點(diǎn)是:因?yàn)闊o符號(hào)數(shù)字沒有符號(hào)位這個(gè)概念,數(shù)字連符號(hào)都沒有了沒有正負(fù)之分,所以它只能表示正數(shù)
- 但是無符號(hào)數(shù)字也能存放負(fù)數(shù),這點(diǎn)是無符號(hào)數(shù)字中最”妙“的點(diǎn)
接下來用unsigned int a = 10
和unsigned int a = -10
舉例進(jìn)行介紹
10為正數(shù),三碼都一樣,所以10的補(bǔ)碼為
00000000000000000000000000001010
,表面上看有無符號(hào)的10的補(bǔ)碼都一致,但是本質(zhì)上無符號(hào)的最高位不是符號(hào)位
-10
的原碼為10000000000000000000000000001010
原碼除了符號(hào)位,其他取反加1得到反碼:111111111111111111111111111111110101
反碼加1得到補(bǔ)碼:111111111111111111111111111111110110
unsigned int a = -10
然后把-10的補(bǔ)碼存到a
中,所以此時(shí)無符號(hào)變量a
中存放著:111111111111111111111111111111110110
因?yàn)?code>a為無符號(hào)變量,所以111111111111111111111111111111110110
的最好位1
不代表著符號(hào),所以a
的本質(zhì)就是一個(gè)正數(shù),正數(shù)原碼、補(bǔ)碼、反碼相同,所以111111111111111111111111111111110110
就是a
所表示數(shù)字的原碼,所以輸出時(shí),就會(huì)把這個(gè)二進(jìn)制序列直接輸出。
接下來輸出一下無符號(hào)a
的值:
int main() { unsigned int a = -10; printf("%u\n", a); //無符號(hào)的數(shù)用%u輸出 return 0; }
結(jié)果為:
這是一個(gè)很大的數(shù),我們用計(jì)算器驗(yàn)證一下二進(jìn)制序列111111111111111111111111111111110110
的十進(jìn)制數(shù)是多少:
所以無符號(hào)a輸出的結(jié)果就是以-10的補(bǔ)碼為原碼的正數(shù)的十進(jìn)制
例題
例1
一下代碼的結(jié)果是:
#include <stdio.h> int i; int main() { i--; if (i > sizeof(i)) { printf(">\n"); } else { printf("<\n"); } return 0; }
A.>
B.<
C.不輸出
D.程序有問題
在C語言中,全局變量,沒有初始化,默認(rèn)為0,i--
后,i
結(jié)果為-1,sizeof(i)
按照i類型大小是4,所以按照此分析,結(jié)果應(yīng)為B,但B選項(xiàng)是錯(cuò)誤的
正確選項(xiàng)其實(shí)為A
因?yàn)?code>sizeof返回值類型為無符號(hào)整形,因此編譯器會(huì)自動(dòng)將左側(cè)的i
轉(zhuǎn)換為無符號(hào)的整形數(shù)據(jù),-1的無符號(hào)整形是一個(gè)非常大的正數(shù),肯定超過4,所以正確選項(xiàng)為A
例2
//輸出的結(jié)果是什么? int i= -20; unsigned int j = 10; printf("%d\n", i+j); //按照補(bǔ)碼的形式進(jìn)行運(yùn)算,最后格式化成為有符號(hào)整數(shù)
- i的原碼是:100000000000000000000000000010100
- i的反碼是:1111111111111111111111111111111101011
- i的補(bǔ)碼是:1111111111111111111111111111111101100
- j 的補(bǔ)碼是:000000000000000000000000000001010
- i+j的補(bǔ)碼是:1111111111111111111111111111111110110
- i+j的原碼是: 100000000000000000000000000001010
- i+j的值為-10,輸出-10
例3
//輸出結(jié)果? unsigned int i; for(i = 9; i >= 0; i--) { printf("%u\n",i); }
答案:死循環(huán)
分析:因?yàn)?code>i為一個(gè)無符號(hào)的int
,所以當(dāng)i
為0時(shí),再減1不會(huì)變成負(fù)數(shù),反而會(huì)變成一個(gè)極大的數(shù),必定大于0,然后這個(gè)極大的數(shù)逐漸-1,當(dāng)再次等于0時(shí),循環(huán)上述的操作,所以此程序是死循環(huán)。
總結(jié)
原文鏈接:https://blog.csdn.net/weixin_64116522/article/details/127896522
相關(guān)推薦
- 2022-08-27 一文讀懂Android?Kotlin的數(shù)據(jù)流_Android
- 2022-10-14 SpringCloud 服務(wù)注冊(cè) Eureka 與 負(fù)載均衡 RestTemplate
- 2022-04-06 Android中卡頓優(yōu)化布局詳細(xì)介紹_Android
- 2022-06-12 Android?Flutter利用貝塞爾曲線畫一個(gè)小海豚_Android
- 2022-06-12 使用jquery實(shí)現(xiàn)別踩白塊小游戲的方法實(shí)例_jquery
- 2022-04-09 解決使用docker權(quán)限不足需要加sudo問題,Got permission denied whil
- 2022-11-14 swiftui開發(fā)之padding默認(rèn)值設(shè)置詳解_Swift
- 2022-07-13 求兩個(gè)降序單鏈表的并集(利用原有鏈點(diǎn))
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支