深入解析unsigned int 和 int
就如同int a;一樣,int 也能被其它的修飾符修飾。除void類型外,基本數(shù)據(jù)類型之前都可以加各種類型修飾符,類型修飾符有如下四種:
1.signed----有符號(hào),可修飾char、int。Int是默認(rèn)有符號(hào)的。
2.unsigned-----無符號(hào),修飾int 、char
3.long------長(zhǎng)型,修飾int 、double
4.short------短型,修飾int
我們主要來看一下signed和unsigned與int之間的聯(lián)系與區(qū)別。
什么叫做有符號(hào),什么叫做無符號(hào)
這個(gè)問題其實(shí)很簡(jiǎn)單,比如:5和-5,5沒有符號(hào),-5有符號(hào)。簡(jiǎn)單吧。但是在計(jì)算機(jī)中的這種符號(hào)可不簡(jiǎn)單。我們分別來看一下:
在說明有符號(hào)和無符號(hào)的區(qū)別之前,我們必須先知道溢出是怎么回事,因?yàn)橛袩o符號(hào)的根本原因可以說就是因?yàn)閿?shù)據(jù)出現(xiàn)了溢出現(xiàn)象導(dǎo)致的。
溢出:
我們知道數(shù)據(jù)在計(jì)算機(jī)中以二進(jìn)制存儲(chǔ),并且占據(jù)一定的空間,而這個(gè)空間屬于計(jì)算機(jī)分配的空間。
計(jì)算機(jī)給int分配32位或者16位(不同電腦可能不同)的空間,既然空間有限,那么數(shù)值就會(huì)有限制,就會(huì)存在最大值與最小值這一說,比如:假設(shè)int類型的分配16位,無符號(hào)類型的最大值為1111 1111 1111 1111(16個(gè)1),也就是65535,如果超過了65535,這就叫做溢出,那該怎么辦? 如果要輸出65536,那將會(huì)輸出個(gè)什么東西呢? 下面和大家一起看一下:
疑問:有的讀者會(huì)問:65535這么小啊,我記得自己在輸出比65535大好多的數(shù)也能夠輸出啊。
解答: 那就是有無符號(hào)的定義和你電腦編譯器的原因了。64位的電腦和32的電腦可是不一樣的哦。而且int占幾個(gè)字節(jié)是與電腦編譯器有關(guān)的。不過現(xiàn)在大部分電腦int占4個(gè)字節(jié),即32位,那么他的最大值可是32個(gè)1(二進(jìn)制)左右的數(shù)量級(jí),你實(shí)驗(yàn)過這么大的數(shù)嗎?
1.無符號(hào)整型(unsigned int)
(1)我們都知道整型是4個(gè)字節(jié)(有些編譯器不同,可能會(huì)是2個(gè)),即32位,無符號(hào)整型當(dāng)然也為32位。
(2)既然是32位,無符號(hào)整型的取值是32個(gè)0~32個(gè)1,即:0~4294967295
(3) 我們舉個(gè)例子:32位有點(diǎn)長(zhǎng),所以我們拿16位的unsigned short int 來舉例。
short int 是16位的,無符號(hào)的范圍是0~65535
就拿十進(jìn)制的32767(以下的所有舉例均拿這個(gè)數(shù)字來說事了)來說,它的二進(jìn)制為:
0111 1111 1111 1111
對(duì)于無符號(hào)的整型32767來說,它的二進(jìn)制的最高位稱為數(shù)據(jù)位,即那個(gè)0就是數(shù)據(jù)位,數(shù)據(jù)位是要參與運(yùn)算的,如果我們把0改成1,即16個(gè)1,它的十進(jìn)制就是65535(就是2的15次方+2的14次方...一直加到2的0次方),這是不同于有符號(hào)整型的。
(4) 為了進(jìn)行理解(3)中的含義,做一個(gè)程序說明:
#include <stdio.h>
main()
{
unsigned short int a=32767,b=a+1;//定義短整型無符號(hào)
printf("a=%u\nb=%u\n",a,b);//以無符號(hào)輸出
}

定義的時(shí)候a=32767,也就是0111 1111 1111 1111,輸出的依然是32767,
a+1=32768, 二進(jìn)制為1000 0000 0000 0000,輸入依然為32768。
根據(jù)(3)中講解的,無符號(hào)整型的二進(jìn)制最高位為數(shù)據(jù)位,數(shù)據(jù)位為0為1都是按照正常來算的。
2.有符號(hào)整型((signed)int)(1)int類型默認(rèn)是有符號(hào)的,所以int實(shí)際上是signed int ,我們通常省略signed
(2)有符號(hào)整型也是32位。
(3)它的取值范圍就與無符號(hào)整型不同了。它的范圍是-2147483648~2147483647這個(gè)范圍可以理解為無符號(hào)整型的一半變成了負(fù)數(shù)。
32位有點(diǎn)長(zhǎng),所以我們拿16位的short int 來舉例。
short int 是16位的,有符號(hào)的范圍是-32768~32767
這個(gè)時(shí)候可能就有人發(fā)問了,32768用二進(jìn)制表示為1000 0000 0000 0000,那么這個(gè)負(fù)的32768的負(fù)號(hào)又怎么理解呢?看下面
(4)舉個(gè)例子;
還是以32767為例子,它的二進(jìn)制為:
0111 1111 1111 1111
對(duì)于有符號(hào)整型32767來說,它的二進(jìn)制最高位稱為符號(hào)位(而不是數(shù)據(jù)位了),符號(hào)位顧名思義就是決定正負(fù)號(hào)的,規(guī)則:0是正,1為負(fù)。
(5)列舉一個(gè)程序理解(4)的內(nèi)容
#include <stdio.h>
main()
{
short int a=32767,b,c,d;//定義無符號(hào)類型。
b=a+1;
c=a+2;
d=a+3;
printf("a=%d\nb=%d\nc=%d\nd=%d\n",a,b,c,d);
}
可以看出此時(shí)的結(jié)果竟然是這個(gè)樣子的。為什么呢?怎么回事?
其實(shí)在計(jì)算機(jī)中,負(fù)數(shù)是并不存在的,它是以二進(jìn)制補(bǔ)碼的形式表示和存放。什么是補(bǔ)碼呢?
(6)什么是補(bǔ)碼,補(bǔ)碼的運(yùn)算。
我們還是列舉一個(gè)簡(jiǎn)單的例子吧!就用-6.
我們經(jīng)過以上的學(xué)習(xí)已經(jīng)知道負(fù)數(shù)的符號(hào)位為1,所以:
(1)-6的二進(jìn)制: 1000 0000 0000 0110(稱為原碼,原碼是計(jì)算機(jī)顯示給我的)
(2)對(duì)原碼求反碼:1111 1111 1111 1001(稱為反碼,保持符號(hào)位不變,將原碼中的0變1,1變0)
(3)對(duì)反碼加1:1111 1111 1111 1010(稱為補(bǔ)碼,補(bǔ)碼是計(jì)算機(jī)中存儲(chǔ)負(fù)數(shù)的形式)
在計(jì)算機(jī)中,如果存儲(chǔ)的二進(jìn)制是1111 1111 1111 1010,那么顯示在我們前臺(tái)的十進(jìn)制數(shù)字就是-6。即:負(fù)數(shù)在計(jì)算機(jī)中是以該負(fù)數(shù)的二進(jìn)制的補(bǔ)碼形式存儲(chǔ)的。
(7)了解了什么是補(bǔ)碼后,再來看我們上述說的那個(gè)程序:
32767的二進(jìn)制為:0111 1111 1111 1111
我們來計(jì)算一下c的值為什么會(huì)等于-32767。
c=32767+2,c的二進(jìn)制為:1000 0000 0000 0001(32767的二進(jìn)制+2),c的這個(gè)二進(jìn)制是在計(jì)算機(jī)中存儲(chǔ)的補(bǔ)碼,需要將它轉(zhuǎn)換為原碼,也就是將c的二進(jìn)制數(shù)減一再取反。得到的二進(jìn)制原碼為:1111 1111 1111 1111。我們已經(jīng)說過,符號(hào)位為1,表示負(fù)值,并不參加運(yùn)算,所以此二進(jìn)制的十進(jìn)制為:-32767。
但是,上述中,c的原碼的確是1111 1111 1111 1111,c在計(jì)算機(jī)中存儲(chǔ)的補(bǔ)碼也的確是1000 0000 0000 00010。但是-32767的由來卻有另一種理解,c的補(bǔ)碼是16位,32位編譯器中有32位的二進(jìn)制,也就是說在16位補(bǔ)碼的前面還有(32-16=16)位的虛位數(shù),并不屬于計(jì)算機(jī)給short int分配的空間,但是這16位的位數(shù)當(dāng)數(shù)表示正時(shí)為0,當(dāng)數(shù)表示負(fù)數(shù)時(shí)為1。并且前16位的數(shù)字全部都與二進(jìn)制倒數(shù)第8位的數(shù)字一致。也就是說:
c 的補(bǔ)碼是 1...1 1000 0000 0000 0010(1..1表示16個(gè)1)
我們可以這樣計(jì)算:-2的7次方+2的1次方=-32767,這種理解普遍被大眾所接受,而且避免了原碼的概念。
(8)通過程序也可以發(fā)現(xiàn)一個(gè)規(guī)律,int的取值范圍是-32768~32767,把頭尾連接起來形成一個(gè)環(huán)就可以了。
相關(guān)文章
C語言中用于產(chǎn)生隨機(jī)數(shù)的函數(shù)使用方法總結(jié)
這篇文章主要介紹了C語言中用于產(chǎn)生隨機(jī)數(shù)的函數(shù)使用方法總結(jié),分別介紹了rand()函數(shù)和srand()函數(shù)以及封裝出的arc4random()函數(shù),需要的朋友可以參考下2016-05-05c++ 形狀類Shape(派生出圓類Circle和矩形類Rectangle)
通過C++方式,建立一個(gè)形狀類Shape作為基類,派生出圓類Circle和矩形類Rectangle 求出面積并獲取相關(guān)信息2020-11-11Qt中const?QString轉(zhuǎn)換?char?*可能的坑
本文主要介紹了Qt中const?QString轉(zhuǎn)換?char?*可能的坑,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07