日本高清不卡中文字幕-一起草草视频在线观看-亚洲精品一区二区三区色-国产亚洲精品免费视频

您好,歡迎進(jìn)入深圳市穎特新科技有限公司官方網(wǎng)站!

您現(xiàn)在的位置:首頁(yè) 新聞資訊 >> 新聞?lì)^條 >> C語(yǔ)言中的正負(fù)數(shù)及其輸出
新聞資訊
NEWS INFORMATION

C語(yǔ)言中的正負(fù)數(shù)及其輸出

發(fā)布時(shí)間:2019-05-22

在數(shù)學(xué)中,數(shù)字有正負(fù)之分。在C語(yǔ)言中也是一樣,short、int、long 都可以帶上正負(fù)號(hào),例如:

//負(fù)數(shù)
short a1 = -10;
short a2 = -0x2dc9;  //十六進(jìn)制
//正數(shù)
int b1 = +10;
int b2 = +0174;  //八進(jìn)制
int b3 = 22910;
//負(fù)數(shù)和正數(shù)相加
long c = (-9) + (+12);

如果不帶正負(fù)號(hào),默認(rèn)就是正數(shù)。

符號(hào)也是數(shù)字的一部分,也要在內(nèi)存中體現(xiàn)出來(lái)。符號(hào)只有正負(fù)兩種情況,用1位(Bit)就足以表示;C語(yǔ)言規(guī)定,把內(nèi)存的最高位作為符號(hào)位。以 int 為例,它占用 32 位的內(nèi)存,0~30 位表示數(shù)值,31 位表示正負(fù)號(hào)。如下圖所示:


在編程語(yǔ)言中,計(jì)數(shù)往往是從0開(kāi)始,例如字符串 "abc123",我們稱第 0 個(gè)字符是 a,第 1 個(gè)字符是 b,第 5 個(gè)字符是 3。這和我們平時(shí)從 1 開(kāi)始計(jì)數(shù)的習(xí)慣不一樣,大家要慢慢適應(yīng),培養(yǎng)編程思維。

C語(yǔ)言規(guī)定,在符號(hào)位中,用 0 表示正數(shù),用 1 表示負(fù)數(shù)。例如 int 類型的 -10 和 +16 在內(nèi)存中的表示如下:


short、int 和 long 類型默認(rèn)都是帶符號(hào)位的,符號(hào)位以外的內(nèi)存才是數(shù)值位。如果只考慮正數(shù),那么各種類型能表示的數(shù)值范圍(取值范圍)就比原來(lái)小了一半。

但是在很多情況下,我們非常確定某個(gè)數(shù)字只能是正數(shù),比如班級(jí)學(xué)生的人數(shù)、字符串的長(zhǎng)度、內(nèi)存地址等,這個(gè)時(shí)候符號(hào)位就是多余的了,就不如刪掉符號(hào)位,把所有的位都用來(lái)存儲(chǔ)數(shù)值,這樣能表示的數(shù)值范圍更大(大一倍)。

C語(yǔ)言允許我們這樣做,如果不希望設(shè)置符號(hào)位,可以在數(shù)據(jù)類型前面加上 unsigned 關(guān)鍵字,例如:

unsigned short a = 12;
unsigned int b = 1002;
unsigned long c = 9892320;

這樣,short、int、long 中就沒(méi)有符號(hào)位了,所有的位都用來(lái)表示數(shù)值,正數(shù)的取值范圍更大了。這也意味著,使用了 unsigned 后只能表示正數(shù),不能再表示負(fù)數(shù)了。

如果將一個(gè)數(shù)字分為符號(hào)和數(shù)值兩部分,那么不加 unsigned 的數(shù)字稱為有符號(hào)數(shù),能表示正數(shù)和負(fù)數(shù),加了 unsigned 的數(shù)字稱為無(wú)符號(hào)數(shù),只能表示正數(shù)。

請(qǐng)讀者注意一個(gè)小細(xì)節(jié),如果是unsigned int類型,那么可以省略 int ,只寫(xiě) unsigned,例如:

unsigned n = 100;

它等價(jià)于:

unsigned int n = 100;

無(wú)符號(hào)數(shù)的輸出

無(wú)符號(hào)數(shù)可以以八進(jìn)制、十進(jìn)制和十六進(jìn)制的形式輸出,它們對(duì)應(yīng)的格式控制符分別為:

 unsigned shortunsigned intunsigned long
八進(jìn)制 %ho %o %lo
十進(jìn)制 %hu %u %lu
十六進(jìn)制 %hx 或者 %hX %x 或者 %X %lx 或者 %lX


上節(jié)我們也講到了不同進(jìn)制形式的輸出,但是上節(jié)我們還沒(méi)有講到正負(fù)數(shù),所以也沒(méi)有關(guān)心這一點(diǎn),只是“籠統(tǒng)”地介紹了一遍,F(xiàn)在本節(jié)已經(jīng)講到了正負(fù)數(shù),那我們就再深入地說(shuō)一下。

嚴(yán)格來(lái)說(shuō),格式控制符和整數(shù)的符號(hào)是緊密相關(guān)的,具體就是:

  • %d 以十進(jìn)制形式輸出有符號(hào)數(shù);
  • %u 以十進(jìn)制形式輸出無(wú)符號(hào)數(shù);
  • %o 以八進(jìn)制形式輸出無(wú)符號(hào)數(shù);
  • %x 以十六進(jìn)制形式輸出無(wú)符號(hào)數(shù)。


那么,如何以八進(jìn)制和十六進(jìn)制形式輸出有符號(hào)數(shù)呢?很遺憾,printf 并不支持,也沒(méi)有對(duì)應(yīng)的格式控制符。在實(shí)際開(kāi)發(fā)中,也基本沒(méi)有“輸出負(fù)的八進(jìn)制數(shù)或者十六進(jìn)制數(shù)”這樣的需求,我想可能正是因?yàn)檫@一點(diǎn),printf 才沒(méi)有提供對(duì)應(yīng)的格式控制符。

下表全面地總結(jié)了不同類型的整數(shù),以不同進(jìn)制的形式輸出時(shí)對(duì)應(yīng)的格式控制符(--表示沒(méi)有對(duì)應(yīng)的格式控制符)。

 shortintlongunsigned shortunsigned intunsigned long
八進(jìn)制 -- -- -- %ho %o %lo
十進(jìn)制 %hd %d %ld %hu %u %lu
十六進(jìn)制 -- -- -- %hx 或者 %hX %x 或者 %X %lx 或者 %lX


有讀者可能會(huì)問(wèn),上節(jié)我們也使用 %o 和 %x 來(lái)輸出有符號(hào)數(shù)了,為什么沒(méi)有發(fā)生錯(cuò)誤呢?這是因?yàn)椋?/p>

  • 當(dāng)以有符號(hào)數(shù)的形式輸出時(shí),printf 會(huì)讀取數(shù)字所占用的內(nèi)存,并把最高位作為符號(hào)位,把剩下的內(nèi)存作為數(shù)值位;
  • 當(dāng)以無(wú)符號(hào)數(shù)的形式輸出時(shí),printf 也會(huì)讀取數(shù)字所占用的內(nèi)存,并把所有的內(nèi)存都作為數(shù)值位對(duì)待。


對(duì)于一個(gè)有符號(hào)的正數(shù),它的符號(hào)位是 0,當(dāng)按照無(wú)符號(hào)數(shù)的形式讀取時(shí),符號(hào)位就變成了數(shù)值位,但是該位恰好是 0 而不是 1,所以對(duì)數(shù)值不會(huì)產(chǎn)生影響,這就好比在一個(gè)數(shù)字前面加 0,有多少個(gè) 0 都不會(huì)影響數(shù)字的值。

如果對(duì)一個(gè)有符號(hào)的負(fù)數(shù)使用 %o 或者 %x 輸出,那么結(jié)果就會(huì)大相徑庭,讀者可以親試。

可以說(shuō),“有符號(hào)正數(shù)的最高位是 0”這個(gè)巧合才使得 %o 和 %x 輸出有符號(hào)數(shù)時(shí)不會(huì)出錯(cuò)。

再次強(qiáng)調(diào),不管是以 %o、%u、%x 輸出有符號(hào)數(shù),還是以 %d 輸出無(wú)符號(hào)數(shù),編譯器都不會(huì)報(bào)錯(cuò),只是對(duì)內(nèi)存的解釋不同了。%o、%d、%u、%x 這些格式控制符不會(huì)關(guān)心數(shù)字在定義時(shí)到底是有符號(hào)的還是無(wú)符號(hào)的:

  • 你讓我輸出無(wú)符號(hào)數(shù),那我在讀取內(nèi)存時(shí)就不區(qū)分符號(hào)位和數(shù)值位了,我會(huì)把所有的內(nèi)存都看做數(shù)值位;
  • 你讓我輸出有符號(hào)數(shù),那我在讀取內(nèi)存時(shí)會(huì)把最高位作為符號(hào)位,把剩下的內(nèi)存作為數(shù)值位。


說(shuō)得再直接一些,我管你在定義時(shí)是有符號(hào)數(shù)還是無(wú)符號(hào)數(shù)呢,我只關(guān)心內(nèi)存,有符號(hào)數(shù)也可以按照無(wú)符號(hào)數(shù)輸出,無(wú)符號(hào)數(shù)也可以按照有符號(hào)數(shù)輸出,至于輸出結(jié)果對(duì)不對(duì),那我就不管了,你自己承擔(dān)風(fēng)險(xiǎn)。

下面的代碼進(jìn)行了全面的演示:

  1. #include <stdio.h>
  2. int main()
  3. {
  4. short a = 0100; //八進(jìn)制
  5. int b = -0x1; //十六進(jìn)制
  6. long c = 720; //十進(jìn)制
  7. unsigned short m = 0xffff; //十六進(jìn)制
  8. unsigned int n = 0x80000000; //十六進(jìn)制
  9. unsigned long p = 100; //十進(jìn)制
  10. //以無(wú)符號(hào)的形式輸出有符號(hào)數(shù)
  11. printf("a=%#ho, b=%#x, c=%ld\n", a, b, c);
  12. //以有符號(hào)數(shù)的形式輸出無(wú)符號(hào)類型(只能以十進(jìn)制形式輸出)
  13. printf("m=%hd, n=%d, p=%ld\n", m, n, p);
  14. return 0;
  15. }

運(yùn)行結(jié)果:
a=0100, b=0xffffffff, c=720
m=-1, n=-2147483648, p=100

對(duì)于絕大多數(shù)初學(xué)者來(lái)說(shuō),b、m、n 的輸出結(jié)果看起來(lái)非常奇怪,甚至不能理解。按照一般的推理,b、m、n 這三個(gè)整數(shù)在內(nèi)存中的存儲(chǔ)形式分別是:

當(dāng)以 %x 輸出 b 時(shí),結(jié)果應(yīng)該是 0x80000001;當(dāng)以 %hd、%d 輸出 m、n 時(shí),結(jié)果應(yīng)該分別是 -7fff、-0。但是實(shí)際的輸出結(jié)果和我們推理的結(jié)果卻大相徑庭,這是為什么呢?

注意,-7fff 是十六進(jìn)制形式。%d 本來(lái)應(yīng)該輸出十進(jìn)制,這里只是為了看起來(lái)方便,才改為十六進(jìn)制。

其實(shí)這跟整數(shù)在內(nèi)存中的存儲(chǔ)形式以及讀取方式有關(guān)。b 是一個(gè)有符號(hào)的負(fù)數(shù),它在內(nèi)存中并不是像上圖演示的那樣存儲(chǔ),而是要經(jīng)過(guò)一定的轉(zhuǎn)換才能寫(xiě)入內(nèi)存;m、n 的內(nèi)存雖然沒(méi)有錯(cuò)誤,但是當(dāng)以 %d 輸出時(shí),并不是原樣輸出,而是有一個(gè)逆向的轉(zhuǎn)換過(guò)程(和存儲(chǔ)時(shí)的轉(zhuǎn)換過(guò)程恰好相反)。

也就是說(shuō),整數(shù)在寫(xiě)入內(nèi)存之前可能會(huì)發(fā)生轉(zhuǎn)換,在讀取時(shí)也可能會(huì)發(fā)生轉(zhuǎn)換,而我們沒(méi)有考慮這種轉(zhuǎn)換,所以才會(huì)導(dǎo)致推理錯(cuò)誤。

上一篇:N76E003之SPI

下一篇:N76E003之IAP

聯(lián)系方式0755-82591179

傳真:0755-82591176

郵箱:vicky@yingtexin.net

地址:深圳市龍華區(qū)民治街道民治大道973萬(wàn)眾潤(rùn)豐創(chuàng)業(yè)園A棟2樓A08

屏边| 新平| 浙江省| 饶阳县| 宁津县| 米林县| 疏勒县| 新野县| 贵港市| 新野县| 台安县| 博湖县| 石屏县| 柘城县| 天津市| 柳江县| 榆社县| 万宁市| 石嘴山市| 武强县| 正阳县| 朝阳区| 怀集县| 连南| 赤壁市| 伊金霍洛旗| 英超| 株洲市| 清涧县| 区。| 顺平县| 大宁县| 靖西县| 渝北区| 宜良县| 贺兰县| 丹寨县| 浦北县| 滁州市| 奈曼旗| 贞丰县|