当前位置:网站首页>017 basics of C language: bit field and typedef
017 basics of C language: bit field and typedef
2022-06-27 04:25:00 【Prison plan progress 50%】
List of articles
One : summary
Some data does not need to occupy a complete character when stored , It only needs to occupy one or several binary bits . For example, the switch only has two states: power on and power off , use 0 and 1 That is enough , That is to say, use a binary . Formally based on this consideration ,C The language also provides a data structure called bit field .
So what is a bit field ?
In the definition of structure , We can specify the number of binary digits occupied by a member variable (Bit), This is the bit domain .
for example :
struct bs{
unsigned m;
unsigned n: 4;
unsigned char ch: 6;
}
: The following number is used to limit the number of digits occupied by the member variable . member m There is no limit to , According to the data type, it can be calculated that it occupies 4 Bytes (Byte) Of memory . member n、ch By : The following number limits ,
You can no longer calculate length by data type , They occupy, respectively 4、6 position (Bit) Of memory .
n、ch The value range of is very limited , If the data is a little bigger, it will overflow .
example :
#include <stdio.h>
int main(){
struct bs{
unsigned m;
unsigned n: 4;
unsigned char ch: 6;
} a = {
0xad, 0xE, '$'};
// First output
printf("%#x, %#x, %c \n", a.m, a.n, a.ch);
// Change the value and output again
a.m = 0xb8901c;
a.n = 0x2d;
a.ch = 'z';
printf("%#x, %#x, %c\n", a.m, a.n, a.ch);
return 0;
}
result :
┌──(rootkali)-[~/Desktop/c_test]
└─# ./weiyu
0xad, 0xe, $
0xb8901c, 0xd, :
about n and ch, The first output is complete , The second output data is incomplete .
On the first output ,n、ch The values of 0xE、0x24(‘$’ Corresponding ASCII Code for 0x24), Converted to binary is 1110、10 0100, No more than the number of digits , It can output normally .
On the second output ,n、ch The value of a 0x2d、0x7a(‘z’ Corresponding ASCII Code for 0x7a), To binary, they are 10 1101、111 1010, It's out of the limit . The excess is cut off directly , be left over 1101、11 1010, Convert to hexadecimal to 0xd、0x3a(0x3a The corresponding character is :).
C Language standards , The width of a bit field cannot exceed the length of the data type it is attached to . informally , Member variables are typed , This type limits the maximum length of a member variable ,: The following number cannot exceed this length .C The language standard also states that , Only a limited number of data types can be used in bit fields . stay ANSI C in , These data types are int、signed int and unsigned int(int The default is signed int); here we are C99,_Bool It's also supported . But the compiler has been extended in the specific implementation , Extra support char、signed char、unsigned char as well as enum type , So the above code doesn't match C Language standards , But it can still be supported by the compiler .
Two : Bit field storage
C The language standard does not specify the specific storage mode of bit field , Different compilers have different implementations , But they all try to compress storage space .
The specific storage rules of bit fields are as follows :
1) When adjacent members are of the same type , If the sum of their bit widths is less than that of the type sizeof size , Then the next member is next to the previous member , Until it can't hold ; If the sum of their bit widths is greater than that of the type sizeof size ,
Then the following members will start with the new storage unit , The offset is an integral multiple of the size of the type .
In the following bit field bs For example :
#include <stdio.h>
int main(){
struct bs{
unsigned m: 6;
unsigned n: 12;
unsigned p: 4;
};
printf("%d\n", sizeof(struct bs));
return 0;
}
Running results :
4
m、n、p The types of unsigned int,sizeof As the result of the 4 Bytes (Byte), That is to say 32 bits (Bit).m、n、p The sum of the bit width of is 6+12+4 = 22, Less than 32, So they're stored next to each other , There's no gap in the middle .
2) When the types of adjacent members are different , Different compilers have different implementations ,GCC Will compress storage , and VC/VS Can't .
Look at the bit field below bs:
#include <stdio.h>
int main(){
struct bs{
unsigned m: 12;
unsigned char ch: 4;
unsigned p: 4;
};
printf("%d\n", sizeof(struct bs));
return 0;
}
stay GCC The result of running under is 4, Three members are stored next to each other ; stay VC/VS The result of running under is 12, The three members are stored according to their respective types ( It is the same as when the positioning width is not specified ).
3) If members are interspersed with non bit domain members , Not so compressed . For example, for the following bs:
struct bs{
unsigned m: 12;
unsigned ch;
unsigned p: 4;
};
Under each compiler sizeof The result is 12.
3、 ... and : Nameless bit field
A bit domain member can have no name , Only data type and bit width are given , As shown below :
struct bs{
int m: 12;
int : 20; // This bit domain member cannot use
int n: 4;
};
Nameless bit fields are usually used to fill in or adjust the position of members . Because there is no name , Nameless bit fields cannot be used .
In the example above , If no bit width is 20 Anonymous members of ,m、n It's going to be next to the storage ,sizeof(struct bs) As the result of the 4; With this 20 Bit as fill ,m、n Will be stored separately ,sizeof(struct bs) As the result of the 8.
Four :typedef
C Language provides typedef keyword , Allow a new alias for a data type , It's like giving people “ nickname ” equally . The purpose of aliasing is not to improve the efficiency of the program , But for coding convenience .
For example, the name of a structure is stu, If you want to define a structure variable, you have to write it like this :struct stu stu1;
struct It seems superfluous , But if you don't write, you will report an error . If struct stu It's a nickname STU, It's easy to write :STU stu1; This way of writing is more concise , The meaning is also very clear , Whether in the standard header file or later programming practice , Will make extensive use of this alias .
Grammar format :typedef oldName newName;
for example :
typedef int INTEGER;
INTEGER a, b;
a = 1;
b = 2;
INTEGER a, b; Equivalent to int a, b;
And so on , Define an alias for the structure type :
typedef struct stu{
char name[20];
int age;
char sex;
} STU;
STU yes struct stu Another name for , It can be used STU Define structure variables :
STU body1,body2;
It is equivalent to :
struct stu body1, body2;
difference :
typedef and #define
#define yes C Instructions , Used to define aliases for various data types , And typedef similar , But they are different :
- typedef Limited to defining symbol names for types ,#define Not only can you define aliases for types , You can also define aliases for numbers , For example, we can define 1 by ONE
- typedef Is interpreted by the compiler ,#define Statements are processed by the precompiler .
Here is #define The simplest use of :
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int main( )
{
printf( "Value of TRUE : %d\n", TRUE);
printf( "Value of FALSE : %d\n", FALSE);
return 0;
}
When the above code is compiled and executed , It will produce the following results :
Value of TRUE : 1
Value of FALSE : 0
边栏推荐
- How to make ef core 6 support dateonly type
- Kotlin Compose 自定义 CompositionLocalProvider CompositionLocal
- 如何系统学习LabVIEW?
- Mysql database foundation: DQL data query language
- Network structure and model principle of convolutional neural network (CNN)
- 015 C语言基础:C结构体、共用体
- 007 C语言基础:C运算符
- math_ Number set (number set symbol) and set theory
- WPF 开源控件库Extended WPF Toolkit介绍(经典)
- 018 C语言基础:C文件读写
猜你喜欢

微服务系统设计——微服务调用设计

Microservice system design -- distributed cache service design

【C语言】关键字的补充

日志收集系統
![[数组]BM94 接雨水问题-较难](/img/2b/1934803060d65ea9139ec489a2c5f5.png)
[数组]BM94 接雨水问题-较难

Microservice system design - service fusing and degradation design

微服务系统设计——分布式事务服务设计

1.5 use of CONDA

MATLAB | 基于分块图布局的三纵坐标图绘制

Microservice system design -- service registration, discovery and configuration design
随机推荐
2022-06-26: what does the following golang code output? A:true; B:false; C: Compilation error. package main import “fmt“ func main() { type
MySql的开发环境
Static timing analysis OCV and time derive
Kotlin Compose 自定义 CompositionLocalProvider CompositionLocal
Qchart note 2: add rollover display
1.5 use of CONDA
轨道姿态常用编程缩写
733. 图像渲染
如何让 EF Core 6 支持 DateOnly 类型
【Unity】UI交互组件之按钮Button&可选基类总结
022 C语言基础:C内存管理与C命令行参数
日志收集系統
012 C language foundation: C array
[BJDCTF2020]The mystery of ip
第1章 绪论
差点因为 JSON.stringify 丢了奖金...
快速掌握 ASP.NET 身份认证框架 Identity - 通过邮件重置密码
办公室VR黄片,骚操作!微软HoloLens之父辞职!
There are two problems when Nacos calls microservices: 1 Load balancer does not contain an instance for the service 2. Connection refused
Ldr6028 OTG data transmission scheme for mobile devices while charging