国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
“整數(shù)數(shù)據(jù)類型”+“各種類型的編碼”+“類型轉(zhuǎn)換” 的細(xì)節(jié)過程

http://blog.csdn.net/deep_explore/article/details/6025586

2010

總感覺數(shù)據(jù)類型和編碼過程的概念在腦子里比較模糊。。。。所以細(xì)細(xì)來研究一下很有必要了!

 

(一)理解整數(shù)數(shù)據(jù)類型的含義和編碼方法

 

C 中的整數(shù)類型可以分為有符號整數(shù)和無符號整數(shù):

有符號整數(shù)類型(5種):                                               同義詞

                                signed char ----------------------------

                                int------------------------------------------signed,signed int

                                short---------------------------------------short int, signed int, signed short int

                                long----------------------------------------long int, signed long, signed long int

                                long long----------------------------------long long int, signed long long, signed long long int

無符號整數(shù)類型(6種):

                                _Bool---------------------------------------bool

                                unsigned char---------------------------

                                unsigned int------------------------------unsigned

                                unsigned short---------------------------unsigned short int

                                unsigned long----------------------------unsigned long int

                                unsinged long long--------------------- unsigned long long int

也就是說,有本質(zhì)上區(qū)別的整數(shù)類型有5+6一共11種。

在32位的機(jī)器上(比如我自己的機(jī)器Intel P7350),也就是說,“虛擬內(nèi)存空間”的地址范圍是:

0000    0000    0000    0000    0000    0000    0000    0000    (最小值)

1111    1111    1111    1111    1111    1111    1111    1111    (最大值)4294967295(類型是無符號的)

1           2           3           4            5           6           7           8           (該行計(jì)數(shù),不然眼都花了?。?/p>

所以在32位地址空間大約為4GB,而我的機(jī)器內(nèi)存才2GB。其實(shí)這就是計(jì)算機(jī)中“字長(word size)”的概念:字長就是計(jì)算機(jī)內(nèi)存地址能編碼的最大比特位(這里是32)。

整數(shù)數(shù)據(jù)類型是怎樣編碼的呢?

無符號類型的編碼很明確

無論是無符號還是有符號的字符類型都有8位(1個字節(jié))

對于其他的數(shù)據(jù)類型,C只定義了最小的存儲空間大小。short至少為2個字節(jié),long至少占4個字節(jié),long long至少占8個字節(jié)。這里的“至少”的含義short可以是>2個字節(jié)的,long可以>4個字節(jié)的,long long 可以大于8個字節(jié)的。各自類型實(shí)際占了多少類型,這個到底取決于CPU還是編譯器呢? 我來考察一下我的編程環(huán)境吧。(我用的CPU是Intel P7350,編譯是GCC4.1.2

)下面是我的測試程序:

  1 #include<stdio.h>
  2 int
  3 main()
  4 {
  5         printf("sizeof(short)=%d/n", sizeof(short));
  6         printf("sizeof(int)=%d/n", sizeof(int));
  7         printf("sizeof(long)=%d/n", sizeof(long));
  8         printf("sizeof(long long)=%d/n", sizeof(long long));
  9         printf("sizeof(unsigned int)=%d/n", sizeof(unsigned int));
 10         printf("sizeof(unsigned short)=%d/n", sizeof(unsigned short));
 11         printf("sizeof(unsigned long)=%d/n", sizeof(unsigned long));
 12         printf("sizeof(unsigned long long)=%d/n", sizeof(unsigned long long));
 13
 14         return 0;
 15 }


運(yùn)行的結(jié)果是:

 

 

[root@localhost ~]# ./a.out
sizeof(short)=2
sizeof(int)=4
sizeof(long)=8
sizeof(long long)=8
sizeof(unsigned int)=4
sizeof(unsigned short)=2
sizeof(unsigned long)=8
sizeof(unsigned long long)=8

 

可以看到long 與long long 的長度是一樣的,并且有符號與無符號是等長的!

盡管不同的環(huán)境下,各種數(shù)據(jù)類型的長度不是一成不變的,但是遵循下面的規(guī)則:

 sizeof(short)  <=  sizeof(int)  <=  sizeof(long)  <=  sizeof(long long)

 

其實(shí),整數(shù)類型(這里不包含布爾類型11-1=10)聲明的本質(zhì)是告訴編譯器2個信息:(1)在內(nèi)存中要取的位數(shù)   (2)第一位是不是符號位。下面看看在我的環(huán)境下的整數(shù)類型編碼情況:

現(xiàn)介紹一下3個基本概念:(注意:原碼,反碼, 補(bǔ)碼是無符號的時候都是一樣的,這樣的編碼主要是針對有符號而言的?。?/p>

原碼--------------符號位+實(shí)際二進(jìn)制值,如-3原碼1000 0011 (以8位為例)。

反碼--------------原碼(不包含符號位)取反      -3反碼1111 1100

補(bǔ)碼--------------反碼+1                                  -3補(bǔ)碼 1111 1101

所以,有符號的數(shù)的補(bǔ)碼比反碼大1。

所以對于有符號的數(shù)的編碼方法就有了兩種:

(1)one's complement (反碼表示法)

(2)two's complement ( 補(bǔ)碼表示法)

現(xiàn)在有一個問題:為什么不直接用原碼表示?主要是為了解決“+0” 和“-0”的問題!我們要把“-0”給變成其他數(shù)!

如果用原碼表示8位有符號數(shù):1 1111111(-127)--------1 0000000(-0)~0 0000000(+0)----------0 1111111(+127)

如果用反碼表示8位有符號數(shù):1 0000000(-127)--------1 1111111(-0)~0 1111111(+0)----------0 0000000(+127)

如果用補(bǔ)碼表示8位有符號數(shù):1 0000001(-127)--------1 0000000(-0)~0 0000000(+0)----------0 0000001(+127)

可以看出:如果把補(bǔ)碼的“-0”放在最前面(-127)前面,正好可以表示-128!再把1的補(bǔ)碼(0 1111111)與127的補(bǔ)碼位置掉換!這樣就是從 1 0000000(-128)~0 1111111(127)連續(xù)的序列。(在這里真是佩服編碼的設(shè)計(jì)者!很巧妙)

而反碼的數(shù)據(jù)處理就比較麻煩了。補(bǔ)碼是從-127到127連續(xù)上升的,除了在“-0”、“1”、“127”的位置。只要進(jìn)行3個數(shù)字的移動就可以確保出現(xiàn)遞增序列。反碼只需要在補(bǔ)碼的基礎(chǔ)上減去1得到的序列! 反碼沒有補(bǔ)碼來的直觀簡潔,所以幾乎現(xiàn)在所有的機(jī)器都都采用補(bǔ)碼來表示有符號數(shù)!

 

 

(二)類型轉(zhuǎn)換的過程細(xì)節(jié)-細(xì)細(xì)揣摩

無符號之間的轉(zhuǎn)換很簡單,只要改變空間字節(jié)大小就OK。

重點(diǎn)是有符號與無符號之間的轉(zhuǎn)換問題:

        強(qiáng)制類型轉(zhuǎn)換的本質(zhì)是:參數(shù)位表示不變,變化的是它的解釋方法。

下面的程序證明了這一點(diǎn):

  1 #include<stdio.h>
  2 int
  3 main()
  4 {
  5         int i = -3;
  6         unsigned j = (unsigned)i;
  7         printf("%#x:%d/n", i, i);
  8         printf("%#x:%u/n", j, j);
  9         return 0;
 10 }
運(yùn)行結(jié)果:

0xfffffffd:-3
0xfffffffd:4294967293
i和j的位表示相同,變化了的是它的解釋方法。

 

最后總結(jié)一些注意點(diǎn):

(1)在賦值的時候,如果要表達(dá)無符號的意圖,那么就要在數(shù)的后面加“U”或“u”,否則將當(dāng)成是有符號來處理。

(2)在一個表達(dá)式中同時出現(xiàn)有符號和無符號的時候的處理辦法是:有符號數(shù)將被強(qiáng)制的轉(zhuǎn)換成了無符號數(shù)了。所以將出現(xiàn)一些奇怪的事情。

 如果誰能找出下面的BUG,我想他會非常的興奮,起碼我是這樣。。。。。

 

  1 #include<stdio.h>
  2
  3 float sum_float( float a[], unsigned length )
  4 {
  5         int i;
  6         float sum = 0;
  7
  8         for( i = 0; i <= length - 1; i++ ){
  9                 sum += a[i];
 10         }
 11
 12         return sum;
 13
 14 }
 15 int main()
 16 {
 17         float a[4] = { 1.1, 2.2, 3.3, 4.4 };
 18         printf("%f/n", sum_float (a, 0));
 19         return 0;
 20 }

 

(當(dāng)length=0的時候,出現(xiàn)內(nèi)存溢出的錯誤,因?yàn)檎Z句i<=length-1中的length為無符號數(shù),所以i,1都將被轉(zhuǎn)換成無符號數(shù),這也不會有問題,這里的BUG出現(xiàn)在length = 0的情況。按道理返回的是0.00..但是這里得到運(yùn)行結(jié)果是“Segmentation fault(段錯誤)”,原因在于length-1的結(jié)果-1將被轉(zhuǎn)換成無符號數(shù),然而unsigned類型并不能存放這么大的數(shù),所以出現(xiàn)了內(nèi)存溢出的錯誤!)

如果把for( i = 0; i <= length - 1; i++ )換成for( i = 0; i < length ; i++ )就會避免這樣的BUG!但這也不是個好辦法,避免這樣的錯誤的辦法就是絕對不要用無符號的數(shù)。這不能說明無符號數(shù)沒有用途,在有的地方無符號數(shù)是非常有用的!比如,把字看成是位的集合而沒有任何數(shù)字意義事,還有當(dāng)實(shí)現(xiàn)模運(yùn)算和多精度運(yùn)算時,無符號數(shù)也非常有用。

 

 

 

 

 

 

 

 

 

 

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
【重要】關(guān)于有符號數(shù)與無符號數(shù)的一些總結(jié)
C語言進(jìn)階1-數(shù)據(jù)在內(nèi)存中的存儲_c語言宏定義的數(shù)據(jù)存在哪里
C語言基本數(shù)據(jù)之整型
C 數(shù)據(jù)類型 整理
(C語言中的“物種”)樂創(chuàng)DIY C語言講義?——3.2節(jié)
64位有符號與無符號類型的整數(shù)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服