結構體的定義和使用和位段的使用
結構體(struct),也叫結構,是由一系列具有相同型別或不同型別的資料構成的資料集合。
比如:描述一個學生,可能需要描述他的學號,姓名,成績等。
一. 宣告及定義結構體變數
有三種方法定義結構體變數
1. 先宣告結構體型別,再定義該型別的變數,例如:
struct student
{
char name[20];
char sex[5];
char number[30];
double score[50];
}a1,a2;
2 宣告的同時定義,例如
struct student { char name[20]; char sex[5]; char number[30]; double score[50]; }a1,a2;
3. 不指定型別名直接定義結構體型別變數,匿名定義,只能用一次
empty
二.結構體變數的初始化
1直接初始化
struct student
{
char name[20];
char sex[5];
char number[30];
double score[5];
};
int main()
{
struct student n = { "zhangsan", "nan", "201512030223", {100,100,100,100,100} };
return 0;
}
2.用typedef定義後用改變後的型別名定義
用typedef將原來的型別名struct student 改為student 在定義
typedef struct student
{
char name[20];
char sex[5];
char number[30];
double score[5];
}student;
int main()
{
student n = { "lisi ", "nan", "201512030224", { 60, 60, 60, 60, 60 } };
return 0;
}
三. 結構體在記憶體中的儲存
typedef struct student { char name[20]; char sex[5]; char number[30]; double score[5]; }student; int main() { printf("%d\n",sizeof(student)); system("pause"); return 0; }
這個程式執行的結果是96
為什麼那?
記憶體對齊的3條規則(要牢記):
1、結構的第一個成員永遠都放在結構的0偏移處。
偏移就是往後挪,n偏移就是從系統預設開始分配記憶體的地方往後挪n個位元組,0偏移就是挪0個,也就是相當於沒有挪。
2、從第二個成員開始,都要對齊到某個某個對齊數的整數倍處。
對齊數:結構體成員自身大小和預設對齊數的較小值。
預設對齊數:VS-----8 linux-----4
3、結構體的總大小必須是最大對齊數的整數倍。
4. 如果嵌套了結構體的情況,巢狀的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是最大對齊數(含巢狀結構體的對齊數)的整數倍。例如:
#define _CRT_SECURE_NO_WARNINGS 1
#include
typedef struct student
{
char name[20];//0-19
char sex[5];//20-24
char number[30];//25-54
double score[5];//56-95
}student;//總大小為96
struct student1
{
student a;//0-95
char b;//96
};
//總大小為97,但是必須為最大步數(double)的整數倍
//所以大小為104
int main()
{
printf("%d\n",sizeof(struct student1));
system("pause");
return 0;
}
記憶體對齊的原因吧。
1、平臺原因(移植原因):不是所有的硬體平臺都能訪問任意地址上的任意資料,某些硬體平臺只能在某些地址處去某些特定型別的資料,否則跑出硬體異常。
2、效能原因:資料結構(尤其是棧)應該儘可能地在自然邊界上對齊。原因在於訪問未對齊的記憶體,處理器需要作兩次記憶體訪問;而對齊的記憶體訪問僅需要訪問。
五. 位段
1、位段成員必須宣告為int,signed int,unsigned int型別,在成員名的後面是一個冒號的一個整數,這個整數該位段所佔用的大小。
2、首先,位段的成員在記憶體裡面儲存是從左到右還是從右到左的是不確定的,其次,當一個宣告指定兩個位段,第二個位段無法儲存在第一個的剩餘位上時,第二個位段直接儲存於下一個位元組上還是將第一個位段剩餘的空間佔滿後剩下的儲存到下一個位元組也是不確定的。
因此,位段不能跨平臺使用。
struct syudent
{
char a : 2;
char b : 5;
char c : 7;
};
在vs平臺上這個位段的大小為2個位元組