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,
};

`


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM