C語(yǔ)言有符號(hào)和無(wú)符號(hào)在內(nèi)存中的存儲(chǔ)方式區(qū)別小結(jié)
在 C 語(yǔ)言中,?有符號(hào)類(lèi)型(如 signed char、signed int)和無(wú)符號(hào)類(lèi)型(如 unsigned char、unsigned int)在內(nèi)存中的存儲(chǔ)方式本質(zhì)上沒(méi)有區(qū)別——它們都是以二進(jìn)制位的形式存儲(chǔ)數(shù)值的。
兩者的核心差異體現(xiàn)在對(duì)二進(jìn)制位的解釋規(guī)則上,而非物理存儲(chǔ)的二進(jìn)制內(nèi)容本身。
關(guān)鍵結(jié)論:
- ?存儲(chǔ)方式相同?:無(wú)論是有符號(hào)還是無(wú)符號(hào)類(lèi)型,相同位數(shù)的變量在內(nèi)存中占用的存儲(chǔ)空間(字節(jié)數(shù))完全一致,且二進(jìn)制位的排列方式也完全相同。
- ?解釋規(guī)則不同?:有符號(hào)類(lèi)型使用“補(bǔ)碼”規(guī)則解釋二進(jìn)制位(最高位為符號(hào)位),而無(wú)符號(hào)類(lèi)型將所有二進(jìn)制位視為“純數(shù)值位”。
具體分析:
1. 存儲(chǔ)的本質(zhì):二進(jìn)制位
計(jì)算機(jī)內(nèi)存中只能存儲(chǔ)二進(jìn)制位(0 或 1)。對(duì)于任意一個(gè)整型變量(無(wú)論是否有符號(hào)),其內(nèi)存中的內(nèi)容都是一組固定長(zhǎng)度的二進(jìn)制位。例如:
- 一個(gè) 32 位的
int(有符號(hào))或unsigned int(無(wú)符號(hào))變量,內(nèi)存中都占用 4 字節(jié)(32 位),存儲(chǔ)的是 32 個(gè)連續(xù)的二進(jìn)制位。 - 一個(gè) 8 位的
signed char或unsigned char變量,內(nèi)存中都占用 1 字節(jié)(8 位),存儲(chǔ) 8 個(gè)二進(jìn)制位。
?示例?:
假設(shè)變量 a是 int類(lèi)型(有符號(hào)),值為 -1;變量 b是 unsigned int類(lèi)型(無(wú)符號(hào)),值為 4294967295(在 32 位系統(tǒng)中)。它們?cè)趦?nèi)存中的二進(jìn)制位完全相同(32 位全為 1),但編譯器會(huì)根據(jù)變量的類(lèi)型(有符號(hào)/無(wú)符號(hào))對(duì)其進(jìn)行不同的解釋。
2. 有符號(hào)類(lèi)型的解釋規(guī)則:補(bǔ)碼
有符號(hào)整數(shù)采用補(bǔ)碼(Two's Complement)?規(guī)則存儲(chǔ)和運(yùn)算,其核心特點(diǎn)是:
- ?最高位為符號(hào)位?:0 表示正數(shù),1 表示負(fù)數(shù)。
- ?數(shù)值范圍?:對(duì)于
n位有符號(hào)整數(shù),范圍是[-2^(n-1), 2^(n-1)-1](例如 32 位int的范圍是[-2^31, 2^31-1])。 - ?負(fù)數(shù)的表示?:負(fù)數(shù)通過(guò)其絕對(duì)值的補(bǔ)碼(取反加 1)存儲(chǔ)。例如,-1 在 32 位
int中表示為0xFFFFFFFF(全 1)。
3. 無(wú)符號(hào)類(lèi)型的解釋規(guī)則:純數(shù)值
無(wú)符號(hào)整數(shù)的所有二進(jìn)制位均被視為數(shù)值位,沒(méi)有符號(hào)位。其特點(diǎn)是:
- ?數(shù)值范圍?:對(duì)于
n位無(wú)符號(hào)整數(shù),范圍是[0, 2^n - 1](例如 32 位unsigned int的范圍是[0, 2^31-1]到[0, 2^32-1])。 - ?直接映射?:二進(jìn)制位的值直接對(duì)應(yīng)十進(jìn)制數(shù)值。例如,32 位全 1 的二進(jìn)制位在
unsigned int中被解釋為4294967295(即 232−1)。
4. 關(guān)鍵差異的具體表現(xiàn)
雖然存儲(chǔ)的二進(jìn)制位相同,但有符號(hào)和無(wú)符號(hào)類(lèi)型的差異會(huì)在以下場(chǎng)景中體現(xiàn):
?賦值與轉(zhuǎn)換?:當(dāng)有符號(hào)數(shù)和無(wú)符號(hào)數(shù)混合運(yùn)算時(shí),有符號(hào)數(shù)會(huì)被隱式轉(zhuǎn)換為無(wú)符號(hào)數(shù)(可能導(dǎo)致意外結(jié)果)。
示例:
int a = -1;
unsigned int b = a; // a 的二進(jìn)制位是全 1,轉(zhuǎn)換為 unsigned int 后為 4294967295
printf("%u\n", b); // 輸出 4294967295(而非 -1)?溢出行為?:
- 無(wú)符號(hào)整數(shù)溢出時(shí),結(jié)果會(huì)“回繞”(模運(yùn)算)。例如,
unsigned int x = 0xFFFFFFFF; x + 1;結(jié)果為0(32 位系統(tǒng))。 - 有符號(hào)整數(shù)溢出是未定義行為?(Undefined Behavior, UB),編譯器可能優(yōu)化導(dǎo)致不可預(yù)測(cè)的結(jié)果。
?比較操作?:混合比較有符號(hào)和無(wú)符號(hào)數(shù)時(shí),有符號(hào)數(shù)會(huì)被轉(zhuǎn)換為無(wú)符號(hào)數(shù),可能導(dǎo)致邏輯錯(cuò)誤。
示例:
int a = -1;
unsigned int b = 1;
if (a < b) { // a 被轉(zhuǎn)換為 unsigned int(值為 4294967295),比較結(jié)果為 false
printf("a < b\n");
} else {
printf("a >= b\n");// 實(shí)際輸出此分支
}總結(jié)
有符號(hào)和無(wú)符號(hào)類(lèi)型在內(nèi)存中的二進(jìn)制存儲(chǔ)內(nèi)容完全相同,區(qū)別僅在于編譯器對(duì)二進(jìn)制位的解釋規(guī)則?(補(bǔ)碼 vs 純數(shù)值)。理解這一點(diǎn)的關(guān)鍵是區(qū)分“存儲(chǔ)的二進(jìn)制位”和“編譯器對(duì)二進(jìn)制位的解釋方式”,避免因類(lèi)型混用導(dǎo)致的邏輯錯(cuò)誤。
到此這篇關(guān)于C語(yǔ)言有符號(hào)和無(wú)符號(hào)在內(nèi)存中的存儲(chǔ)方式區(qū)別小結(jié)的文章就介紹到這了,更多相關(guān)C語(yǔ)言有符號(hào)和無(wú)符號(hào)存儲(chǔ)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C語(yǔ)言實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)串(堆分配存儲(chǔ)表示法)實(shí)例詳解
- C語(yǔ)言讀取和存儲(chǔ)bmp格式圖片
- C語(yǔ)言詳解float類(lèi)型在內(nèi)存中的存儲(chǔ)方式
- C語(yǔ)言中的字符串?dāng)?shù)據(jù)在C中的存儲(chǔ)方式
- C語(yǔ)言二進(jìn)制思想以及數(shù)據(jù)的存儲(chǔ)
- C語(yǔ)言實(shí)現(xiàn)二叉鏈表存儲(chǔ)
- C語(yǔ)言 數(shù)據(jù)結(jié)構(gòu)之連續(xù)存儲(chǔ)數(shù)組的算法
- C語(yǔ)言中數(shù)據(jù)的存儲(chǔ)詳解
- C語(yǔ)言 存儲(chǔ)類(lèi)詳解及示例代碼
相關(guān)文章
一篇文章帶你了解C語(yǔ)言文件操作中的幾個(gè)函數(shù)
這篇文章主要介紹了使用C語(yǔ)言操作文件的基本函數(shù)整理,包括創(chuàng)建和打開(kāi)以及關(guān)閉文件的操作方法,需要的朋友可以參考下,希望能夠給你帶來(lái)幫助2021-09-09
C++實(shí)現(xiàn)簡(jiǎn)單的計(jì)算器小功能
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單的計(jì)算器小功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
C++消息隊(duì)列(定義,結(jié)構(gòu),如何創(chuàng)建,發(fā)送與接收)
這篇文章主要介紹了C++消息隊(duì)列(定義,結(jié)構(gòu),如何創(chuàng)建,發(fā)送與接收),消息隊(duì)列是一種先進(jìn)先出的隊(duì)列型數(shù)據(jù)結(jié)構(gòu),實(shí)際上是系統(tǒng)內(nèi)核中的一個(gè)內(nèi)部鏈表2022-08-08
C語(yǔ)言將24小時(shí)制轉(zhuǎn)換為12小時(shí)制的方法
這篇文章主要介紹了C語(yǔ)言將24小時(shí)制轉(zhuǎn)換為12小時(shí)制的方法,涉及C語(yǔ)言針對(duì)時(shí)間的相關(guān)操作技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-07-07
VisualStudio2022提交git代碼的方法實(shí)現(xiàn)
本文主要介紹了VisualStudio2022提交git代碼的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
c語(yǔ)言中如何修改文件中間的幾個(gè)字節(jié)
工作中碰到一個(gè)問(wèn)題,如何只修改文件中間的幾個(gè)字節(jié),而其他的內(nèi)容不變。這個(gè)問(wèn)題看似簡(jiǎn)單,但是很多人估計(jì)都不知道怎么做。我開(kāi)始seek到文件的特定的位置,然后寫(xiě)文件,但是使用的文件打開(kāi)模式不對(duì),文件不是被清空,就是被截?cái)?,達(dá)不到效果2020-10-10
利用OpenCV實(shí)現(xiàn)局部動(dòng)態(tài)閾值分割
這篇文章主要為大家詳細(xì)介紹了利用OpenCV實(shí)現(xiàn)局部動(dòng)態(tài)閾值分割,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
C++在C語(yǔ)言基礎(chǔ)之上增強(qiáng)的幾個(gè)實(shí)用特性總結(jié)
這篇文章主要介紹了C++在C語(yǔ)言基礎(chǔ)之上增強(qiáng)的幾個(gè)實(shí)用特性總結(jié),包括C++中更強(qiáng)的類(lèi)型約束以及結(jié)構(gòu)體方面等一些更加高級(jí)的特性,需要的朋友可以參考下2016-03-03

