網站首頁 編程語言 正文
一、位段是什么
位段的聲明和結構是類似的,有兩個不同
1.位段的成員必須是 int、unsigned int 或signed int 。
2.位段的成員名后邊有一個冒號和一個數字。
舉例如下:
struct A
{
int _a:2;
int _b:5;
int _c:10;
int _d:30;
};
這個A就是一個位段。
但是結構體可以根據結構體內存對齊確定一個結構體的大小,但是位段的大小怎么確定呢?
位段A的大小是多少呢?
printf("%d\n", sizeof(struct A));
我們利用sizeof操作符來測一下這個A位段的大小是8個字節
但是根據常理來說應該是16個字節呀,我們和結構體對比分析
struct s
{
int a;
int b;
int c;
int d;
};
int main()
{
printf("%d\n", sizeof(struct s));//16個字節
return 0;
}
對比發現位段不是根據他的數據類型來分配內存的。接下來我們看看位段是怎么分配內存的。
二、位段的內存分配
2.1位段內存分配的原則
- 位段的成員可以是 int unsigned int signed int 或者是 char (屬于整形家族)類型
- 位段的空間上是按照需要以4個字節( int )或者1個字節( char )的方式來開辟的。
- 位段涉及很多不確定因素,位段是不跨平臺的,注重可移植的程序應該避免使用位段。ps:雖然位段是不跨平臺的,但是我們可以根據平臺的不同編寫不同的代碼
struct A
{
int _a:2; //雖然a是int型但是他所分配的內存根據冒號之后的數字確定,a冒號后面是2,所以他只占用2個比特位
int _b:5; //同理,b成員只需要5個比特位
int _c:10; //10個比特位
int _d:30; //30個比特位
};
??那么我們發現這個字段A一共需要47個比特位,好像6個字節就可以完成存儲,但是事實并非如此,我們根據位段的內存分配原則,位段的成員是int類型所以按照需要以4個字節的方式開辟,我們先開辟4個字節的空間,即32個比特位,我們可以存儲a,b,c但是存儲d的時候發現內存不夠了,我們再次按照需求再一次開辟4個字節的空間,最終開辟了8個字節的空間而非6個字節的空間來存儲位段A。
??但是a,b,c存儲之后還剩下15個比特位,這些比特位還用不用呢?
??答案是不確定的,每個編譯器的處理方式都是不一樣的,在VS環境下就浪費掉了,位段依舊有很多的不確定性。下面用圖例理想表示一下在VS環境下位段的存儲:
代碼如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
struct S
{
char a : 3; //a占3個比特位,以下同理
char b : 4;
char c : 5;
char d : 4;
};
int main()
{
//printf("%d\n", sizeof(struct S));
struct S s = { 0 };
s.a = 10; // 賦值給位段的成員
s.b = 12;
s.c = 3;
s.d = 4;
return 0;
}
2.2位段內存分配圖解
假設內存都是由低位向高位使用的,即從右向左使用:
我們將這3個字節的內存中都用0進行初始化:
struct S s = {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> 0 };
三、位段的跨平臺問題
int 位段被當成有符號數還是無符號數是不確定的。
int的最高位原本是符號位,但是int位段是有符號數還是無符號數是不確定的。位段中最大位的數目不能確定。(16位機器最大16,32位機器最大32,寫成27,在16位機器會出問題。
(16位機器最大可以處理16位數據,尋址空間也只有16位,但是如果傳入27位數據就會出問題)
ps:int在16位操作系統下占2個字節。位段中的成員在內存中從左向右分配,還是從右向左分配標準尚未定義。
上圖只是假設我們從右向左使用,但是分配表示尚未定義,所以也是不確定的。當一個結構包含兩個位段,第二個位段成員比較大,無法容納于第一個位段剩余的位時,是舍棄剩余的位還是利用,這是不確定的。
總結:
??跟結構相比,位段可以達到同樣的效果,但是可以很好的節省空間,但是有跨平臺的問題存在。
??犧牲了它的可移植性,但是節省了空間,可以根據需求選擇。
??為什么說和結構相比,位段可以節省空間呢?
代碼如下(示例):
struct A
{
int _a:2; //雖然a是int型但是他所分配的內存根據冒號之后的數字確定,a冒號后面是2,所以他只占用2個比特位
int _b:5; //同理,b成員只需要5個比特位
int _c:10; //10個比特位
int _d:30; //30個比特位
};
??比如這個代碼,假設a的取值只可能是0,1,2,3,如果用結構寫的話會給a分配4個字節的空間也就是32個比特位,但是a最大需要的比特位是2位,所以會大大造成浪費,并且結構體還存在結構體內存對齊問題,犧牲了空間提高了時間效率。
四、位段的使用
總結
??位段的介紹到此結束,總結一下就是位段相比較結構體節省了空間但是失去了可移植性,存在了跨平臺的問題,我們可以根據自身的需求來選擇是否使用位段,同時位段廣泛使用在計算機網絡方面,如果想變強就需要學會合理使用位段,加油 少年們!
原文鏈接:https://blog.csdn.net/MDLYB/article/details/126949959
相關推薦
- 2023-04-27 React中useState值為對象時改變值不渲染問題_React
- 2023-03-27 淺談Rust?+=?運算符與?MIR?應用_Rust語言
- 2024-01-15 spring boot jpa 執行test測試,發現執行未報錯但是事務會自動回滾
- 2022-05-15 Python?文件與文件對象及文件打開關閉_python
- 2023-07-26 node中的內置模塊path和fs
- 2022-07-23 C++強制類型轉換的四種方式_C 語言
- 2022-12-27 C語言實現二叉樹鏈式結構的示例詳解_C 語言
- 2022-07-21 nginx?配置指令之location使用詳解_nginx
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支