• struct结构体的字节长度,字节对齐


    1 unsigned short 等基本数据类型的字节大小

    • 整型数据即整数。整型数据的一般分类如下:
    • 基本型:类型说明符为int,在内存中占4个字节。
    • 短整型:类型说明符为short int或short。所占字节和取值范围均与基本型相同。
    • 长整型:类型说明符为long int或long,在内存中占4个字节。
    • 无符号型:类型说明符为unsigned。无符号型又可与上述三种类型匹配而构成:
    • 无符号基本型:类型说明符为unsigned int或unsigned。
    • 无符号短整型:类型说明符为unsigned short。
    • 无符号长整型:类型说明符为unsigned long。  
      下表列出了C语言中各类整型数据所分配的内存字节数及数的表示范围。

    image

    2 struct字节对齐的原则

    结构体计算要遵循字节对齐原则。
    结构体默认的字节对齐一般满足三个准则:

    1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
    2. 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
    3. 结构体的总大小为 结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)
      其实暂且不管这三原则,我的方法只要记住第三个,就是
      结构体大小结果要为成员中最大字节的整数倍。

    转载至:https://www.runoob.com/w3cnote/struct-size.html

    3 计算字节长度实例

    3.1 栗子1

    struct { char a; short b; char c; }S1;
    image
    所以对于 S1 结构体大小为 2*3=6,至于为什么第二个 char,多的那个字节不丢到,就是遵循第三个原则,就是结构体大小结果要为成员中最大字节的整数倍。
    S1=2*3=6

    3.2 栗子2

    struct { char a; char b; short c; }S2;
    image
    S2=2*2=4

    3.3 栗子3

    struct stu1 { int i; char c; int j; };
    因为 int 占 4 个,而 char 已经占了一个,不够,所以那三个只能多余占位。
    Stu1=3*4=12

    3.4 栗子4

    struct stu2 { int i; int j; char c; };
    Stu2=3*4=12

    4 结构体成员中含有结构体变量

    就是当结构体成员变量是另外一个结构体时,只要把结构体中成员为另一结构体作为整体相加就行。
    typedef struct A { char a1; short int a2; int a3; double d; };
    char=1;short int=2,int=4,double=8。
    A=16
    typedef struct B { long int b2; short int b1; A a; };

    而对于 B,先不要管 A a,也就是先去掉 A a 成员结构体 B 算出其为 8,所以最后结果为 8+16=24;24 才是最后结果。

    5 栗子5

    `

    #define LCD_C_SEGMENT_LINE_0                                                (0)
    #define LCD_C_SEGMENT_LINE_4                                                (4)
    ......
    #define LCD_C_SEGMENT_LINE_22                                               (22)
    
    
    /*! Start Segment used for each one of the digits */
    typedef enum
    {
    	HAL_LCD_DIGIT_1 = LCD_C_SEGMENT_LINE_0, /* Digit 1 in LCDMEM1 */
    	HAL_LCD_DIGIT_2 = LCD_C_SEGMENT_LINE_4, /* Digit 2 in LCDMEM3 */
    	HAL_LCD_DIGIT_3 = LCD_C_SEGMENT_LINE_8, /* Digit 3 in LCDMEM5 */
    	HAL_LCD_DIGIT_4 = LCD_C_SEGMENT_LINE_12, /* Digit 4 in LCDMEM7 */
    	HAL_LCD_DIGIT_5 = LCD_C_SEGMENT_LINE_18, /* Digit 5 in LCDMEM10 */
    	HAL_LCD_DIGIT_6 = LCD_C_SEGMENT_LINE_22, /* Digit 6 in LCDMEM12 */
    }HAL_LCD_DIGIT_t;
    
    
    / Struct that holds information on what is to be displayed to the LCD
    typedef struct
    {
    	char character[HAL_LCD_DIGIT_MAX];        // the characters to be displayed
    	HAL_LCD_DIGIT_t digit[HAL_LCD_DIGIT_MAX]; // digit index
    	bool decimal[HAL_LCD_DIGIT_MAX];          // place of decimal point in data
    	bool isminus;                             // sign of data
    }DISPLAY_DATA_t;
    
    
    void main()
    {
    	volatile uint32_t j=0,k=0;
    	DISPLAY_DATA_t displayData =
    	{
    		.character[0] = 0, .character[1] = 0, .character[2] = 0,
    		.character[3] = 0, .character[4] = 0, .character[5] = 0,
    
    		.digit[0] = HAL_LCD_DIGIT_1, .digit[1] = HAL_LCD_DIGIT_2,
    		.digit[2] = HAL_LCD_DIGIT_3, .digit[3] = HAL_LCD_DIGIT_4,
    		.digit[4] = HAL_LCD_DIGIT_5, .digit[5] = HAL_LCD_DIGIT_6,
    
    		.decimal[0] =  false, .decimal[1] =  false, .decimal[2] =  false,
    		.decimal[3] =  false, .decimal[4] =  false, .decimal[5] =  false,
    
    		.isminus = false,
    	};
    
    	#define aa 3
    	#define bb (5)
    	#define cc "test1"
    	#define dd (5.2)
    	#define ee (6.88)
    	#define ff 'A'
    	#define hh 70000
    	#define ii 8888888888
    
    	while(1)
    	{
    		j=sizeof(displayData);//26
    		k=sizeof(displayData.character);//6
    		j=sizeof(displayData.decimal);//6
    		k=sizeof(displayData.digit);//12
    		j=sizeof(displayData.isminus);//1
    		k=sizeof(displayData.character[6]);//1
    		j=sizeof(displayData.digit[5]);//2
    		k=sizeof(displayData.decimal[4]);//1
    		j=sizeof(aa);//2    short 3
    		k=sizeof(bb);//2    short 5
    		j=sizeof(cc);//6    字符串“test1”
    		k=sizeof(dd);//8    小数5.2
    		j=sizeof(ee);//8    小数6.88
    		k=sizeof(ff);//2    字符‘’
    		j=sizeof(hh);//4    int 70000
    		k=sizeof(ii);//8    long 8888888888
    	}
    	}
    }
    

    `

    • 知识点1:

      • define定义的整形变量的大小是根据整形变量所属的范围判断其大小的,short是两个字节,int是四个字节,long是八个字节,小数是八个字节。
      • 其中字符是两个字节,字符串是根据字符串实际长度计算的。
    • 知识点2:

      • 这个结构体的长度为什么是26。
      • 结构体的成员是数组,数组的话拆分为每一个元素的大小。结构体中最大的成员的字节长度是2,是short。
      • 所以字节是6+12+6+2=26。

    `

    DISPLAY_DATA_t displayData =
    {
    	.character[0] = 0, .character[1] = 0, .character[2] = 0,
    	.character[3] = 0, .character[4] = 0, .character[5] = 0,
    
    	.digit[0] = HAL_LCD_DIGIT_1, .digit[1] = HAL_LCD_DIGIT_2,
    	.digit[2] = HAL_LCD_DIGIT_3, .digit[3] = HAL_LCD_DIGIT_4,
    	.digit[4] = HAL_LCD_DIGIT_5, .digit[5] = HAL_LCD_DIGIT_6,
    
    	.decimal[0] =  false, .decimal[1] =  false, .decimal[2] =  false,
    	.decimal[3] =  false, .decimal[4] =  false, .decimal[5] =  false,
    
    	.isminus = false,
    };
    

    `

  • 相关阅读:
    目前流行的缺陷管理工具
    高性能WEB开发之Web性能测试工具推荐
    测试工具
    简单的事件示例代码
    C#常用代码片段备忘
    C# 获取变量或对象的栈与堆地址
    C#常用的命名规则汇总
    C# 成员默认访问权限(public、private、protected、internal)
    C# 学习路线
    简单的异常例子
  • 原文地址:https://www.cnblogs.com/xuyan123/p/14707991.html
Copyright © 2020-2023  润新知