謝邀。
1個字節(Byte)等于8個位(bit)似乎已經是程序員間的常識了,很少有人質疑這一點。但是作為C語言程序員,我們常常要在不同的硬件平臺上做底層開發,應該明白:1個字節等于8個位只是慣例而已,C語言標準并沒有定義這一點。
有些編譯器并不遵守這個慣例,例如,在Texas的C55xDSP的平臺上,1個字節等于16個位。在這個平臺上,各種數據類型占用的位數有些奇怪:
以longlong為例,在該平臺上longlong之所以等于40bit,而不是我們常用的64bit,是因為它們的ALU是40bit寬,因此編譯器規定longlong為40bit可以降低功耗和提升效率。
C語言操作位
C語言沒有類似于Java的“垃圾回收”等高級編程語言特性,也不像python那樣無需顯示聲明類型就能使用變量,因此在很多人看來,C語言有些“低級”。但是C語言的這些“低級”也是C語言的優點——使用C語言開發程序,程序員能夠準確知道究竟使用了多少資源,以及哪些資源還在內存里,哪些已經被釋放。換句話說,C語言程序具備資源的使用確定性。
因此,C語言特別適合用于一些資源比較匱乏的項目開發中。在這些項目中,以嵌入式項目為代表,一般都需要嚴格控制內存的使用——使用1個字節(Byte)就能存放的值,絕對不定義2個字節寬度的變量。甚至,一些“摳門”的C語言程序員會將1個字節掰成若干個位(bit)使用。
所以,在C語言程序開發中,常常需要操作某個變量特定的位(bit),這對于C語言來說當然沒有任何難度,各種移位操作就能夠方便的解決該類需求,例如:
上面第二行C語言代碼將status的第3個位(bit2)設置為1,第三行C語言代碼將status的第1個位(bit0)設置為0??梢钥闯?,借助于位運算,C語言可以比較簡單的操作status的指定位。不過,C語言這種操作位的方法有時候看起來不夠直觀——至少沒有直接賦值那么直觀。
那C語言有沒有更加直觀的位操作方法呢?
上面的例子通過移位、以及或與非等操作實現對變量status的位操作,但是看起來卻不是那么直觀,那么C語言有沒有更加直觀的位操作方法呢?似乎可以借助C語言的聯合體(union)和位域(bitfield)語法,間接的實現位操作,請看下面的C語言代碼:
此例中status和bits結構體共享一個字節的內存空間,結構體bits利用C言中的位域語法將一個字節的內存空間拆分成8個位,這種情況下,要讀寫status的位就非常簡單了,請看下面的C語言示例代碼:
編寫main()函數,測試通過位域操作status的位,相關C語言代碼如下,請看:
main()函數一開始將status置為0,然后將它的bit1和bit3設置為1,也就相當于將status設置為0x0a,編譯并執行這段C語言代碼,得到如下輸出:
一切與預期一致,這樣就實現了以“賦值”的形式,操作C語言中的位,而且看起來比“移位與或非操作”更加直觀,所以這樣的操作更好了?
自然要看情況,比如在開頭提到的幾種已經平臺上,上述C語言代碼就不再適用了,另外,就算在1個字節等于8個位的硬件平臺上,單個字節的8個位是如何分布的也是沒有明確標準的。這就導致上面這種基于位域的操作位的方法不具備可移植性。
不過,這種方法又的確可以帶來一些方便,具體取舍由題主決定了。
歡迎在評論區一起討論,質疑。文章都是手打原創,每天最淺顯的介紹C語言、linux等嵌入式開發,喜歡我的文章就關注一波吧,可以看到最新更新和之前的文章哦。