為什麼對byte的操作會得到int的結果

2021-01-07 騰訊網

蠍子

下面的討論,適用於C/C++/C#,我決定使用C#代碼來演示,為什麼?我覺得這段時間對C#這位兄弟的關注還是太少了。

有些人會抱怨,為什麼下面的代碼會觸發編譯器的警告:

他們會說:」對一個byte的操作,按理說,結果應該也是一個byte呀,為什麼會是一個int?」

要小心了大兄弟,你要求的東西,可能實際上並不是你真正想要的。

此話怎講?

就依你,假設我們生活在這樣一個世界:對任何byte類型變量的操作也會產生byte類型的結果。

如下圖所示:

這這個理想世界,變量i的值將會是16。為什麼?

因為兩個byte類型的變量相加,也會產生一個byte的結果,因為這裡存在整型溢出,所以,你會得到16這個結果。驚不驚喜?

類似的:int j = -b;

變量j的值實際上是224,而不是你所預期的-32,也是同樣的整型溢出原因導致的。

所以,請再問問自己,這真的是我想要的嗎?

讓我們來考察下列更加讓人防不勝防的代碼:

在我們的理想世界中,一旦這場遊戲的次數操作了255,則計算結果就是錯誤的。

為了解決這個問題,你可以這樣解決,雖然看起來代碼有點醜陋了:

所以,無論你如何精簡代碼,你都不得不添加上述這些強制類型轉換的代碼。

讓我這樣說白了吧:出於安全方面的考慮而出現的語法錯誤(例如,你知道不會產生溢出,但是你不得不加上強制類型轉換),比那些根本摸不著頭腦的運行時錯誤(例如,你忘記在計算工資的代碼中添加類型轉換,直到財務部的大姐問你為什麼本月工資發錯數了),要好吧。

總結

行,服了。

我們還是回到這個世界吧:對byte的操作會得到int的結果。

最後

Raymond Chen的《The Old New Thing》是我非常喜歡的博客之一,裡面有很多關於Windows的小知識,對於廣大Windows平臺開發者來說,確實十分有幫助。

本文來自:《Why do operations on 「byte」 result in 「int」?》

相關焦點

  • 為什麼對byte的操作會得到int的結果|代碼|整型|編譯器|windows...
    他們會說:「對一個byte的操作,按理說,結果應該也是一個byte呀,為什麼會是一個int?」  這這個理想世界,變量i的值將會是16。為什麼?因為兩個byte類型的變量相加,也會產生一個byte的結果,因為這裡存在整型溢出,所以,你會得到16這個結果。驚不驚喜?  類似的:int j = -b;變量j的值實際上是224,而不是你所預期的-32,也是同樣的整型溢出原因導致的。  所以,請再問問自己,這真的是我想要的嗎?
  • byte,short,char做運算時,得到的結果時int類型
    byte可以自動轉為shortchar不能轉為short(因為char是沒有負數的,而short是有負數的,所以char不能轉為short)char可以轉為intchar可以直接用數字賦值:範圍0-65535byte short不能自動轉為charbyte,short,char做運算時,得到的結果時int類型(包括自己和自己做運算)這是因為這三者在做運算的時候很容易超出自身範圍,所以在編譯期就報錯,不要等到運行才報錯byte a = 1;
  • Java 教程|byte 轉換 int 時為何與 0xff 進行與運算
    直接 Integer.toHexString(b[ i ]);,將 byte 強轉為 int 不行嗎?答案是不行的。6作為4的補數改寫為加法:9+6=15(去掉高位1,也就是減10)得到5.,如果不進行 &0xff,那麼當一個 byte 會轉換成 int 時,由於 int 是32位,而 byte 只有8位這時會進行補位,例如補碼11111111的十進位數為 -1 ,轉換為int時變為 11111111111111111111111111111111,好多1啊,呵呵!
  • java大於127byte值轉int
    因為java沒有無符號數,所以在byte值大於127時,java表達的是負數。例如:byte b = (byte)152;// b的值在java中表達的是:-104,二進位值是:10011000。int i = b;// i 的值 在java中表達的是:-104,二進位值是:11111111111111111111111110011000如果想要 i 的值等於152,需要以下運算:/*** byte轉int,
  • Go 中 string 轉 []byte 的陷阱
    1由於 s,s1 指向同一份數組,所以在 s1上進行 append a 操作時(底層數組[0]=a),也是 s 所指向數組的操作,但 s 本身不會有任何變化。這也是 Go 中  append 的寫法都是:append 函數會返回 s1,需要重新賦值給 s。如果不賦值的話,s 本身記錄的數據就滯後了,再次對其 append,就會從滯後的數據開始操作。雖然看起是 append,實際上確是把上一次 append 的值給覆蓋了。
  • Java中byte做&0xff運算的原因及解析
    (buf[pos++] & 0xff) : -1;}上面的源碼可能有的人會犯迷糊0xff的二進位是1111 1111 (8bit),一個byte也是8bit,上面的操作buf[pos++] & 0xff是將一個byte類型的數字&0xff,那麼得到的結果應該是還是這個byte類型數字本身呀?
  • java安全編碼指南之:Number操作
    Number的範圍每種Number類型都有它的範圍,我們看下java中Number類型的範圍:考慮到我們最常用的int操作,雖然int的範圍夠大,但是如果我們在做一些int操作的時候還是可能超出int的範圍。超出了int範圍會發送什麼事情呢?看下面的例子:運行結果:-2147482649。
  • JDK 源碼閱讀 :ByteBuffer
    Java堆緩衝區本質上就是byte數組,所以實現會比較簡單。而堆外內存涉及到JNI代碼實現,較為複雜,本次我們以HeapByteBuffer為例來分析Buffer的相關操作,後續專門分析DirectByteBuffer。ByteBuffer的類圖如下:
  • ByteBuf 和 ByteBuffer的比對
    而byteBuffer實際上存儲的時候是將數據存儲為了byte[]數組的格式,此時position會在每一次put操作之後自增+1操作,因此此時position位於第四個索引下標,列印的時候也就顯示為3。而capacity和limit兩個屬性則是在一開始初始化操作的時候就定義好了的,目前依舊保持為5不變。
  • 關於java中byte取值範圍最小值為什麼是-128而不是-127引發的思考
    我們都知道java 的byte佔4個字節,1個字節8位。而計算機表示數據都是以二進位的形式表示。那麼一個byte表示的二進位應該為0000 0000 -1111 1111,又因為最高位代表符號位,那麼一個byte表示的範圍就應該為(-2^7-1)-(2^7-1)即-127到127怎麼會有-128呢?
  • 圖解ByteBuffer
    使用ByteBuffer最核心的方法是put(byte)和get()。分別是往ByteBuffer裡寫一個字節,和讀一個字節。值得注意的是,ByteBuffer的讀寫模式是分開的,正常的應用場景是:往ByteBuffer裡寫一些數據,然後flip(),然後再讀出來。這裡插兩個Channel方面的對象,以便更好的理解Buffer。
  • CSharp 基礎知識系列-IO篇 流的操作
    前言繼續之前的C# IO流,在前幾篇小短片中我們大概看了下C# 的基礎IO也對文件、目錄和路徑的操作有了一定的了解。這一篇開始,給大家演示一下流的各種操作。以文件流為例,一起來看看如何操作吧。list = new List<byte>();while(true){int length = program.Read(buffers, 0, buffers.Length);if(length <=0)
  • int 和 integer:裝箱和拆箱的過程,會用到什麼方法
    2、為什麼需要包裝類很多人會有疑問,既然Java中為了提高效率,提供了八種基本數據類型,為什麼還要提供包裝類呢?這個問題,其實前面已經有了答案,因為Java是一種面向對象語言,很多地方都需要使用對象而不是基本數據類型。
  • 使用Golang操作文件的那些事兒
    例如咱們常見的文件後綴名.exe,.txt,'.word'…等等文件的基本操作可簡單分為增、刪兩類,也就是咱們所說的CURD(增刪改查),也是基於此兩類操作。可簡單理解為打開文件夾、CURD、關閉文件夾。結束~golang對於文件基本上都是基於Golang的os模塊,那讓我們一起了解一下,那麼Golang是如何對文件進行操作呢。
  • 彙編入門學習筆記 (十二)—— int指令、埠
    jcxz lpret add [bp+2],bxlpret: pop bp iretlpend: nop code endsend startassume cs:codecode segmentstart: mov ax,0b800h mov es,ax mov di,160*12 mov bx,offset s - offset se mov cx,80s: mov byte
  • 為什麼指針被譽為 C 語言靈魂?
    不了解的對指針的理解就停留在「指針就是變量的地址」這句話,會比較害怕使用指針,特別是各種高級操作。而了解內存模型的則可以把指針用得爐火純青,各種 byte 隨意操作,讓人直呼 666。同時,在這裡提點小問題:既然指針的本質都是變量的內存首地址,即一個 int 類型的整數。那為什麼還要有各種類型呢?比如 int 指針,float 指針,這個類型影響了指針本身存儲的信息嗎?這個類型會在什麼時候發揮作用?
  • c語言基本數據類型short、int、long、char、float、double
    現在我們聯想一下,short、int、long、char、float、double 這六個東東是不是很像不同類型的藕煤器啊?拿著它們在內存上咔咔咔,不同大小的內存就分配好了,當然別忘了給它們取個好聽的名字。