您好,登錄后才能下訂單哦!
梓益C語言學習筆記之結構體-共用體-枚舉
有人說,我們需要將不同類型的數據組合成一個整體,于是,就有了結構體
一、結構體的概念:
一種或多種基本類型或構造類型的數據的集合。
二、定義方法:
先定義結構體類型,再去定義結構體變量
struct 結構體類型名{
成員列表
};
如:
struct stu{
int num;
char name[20];
char sex;
};
struct stu lucy,bob,lilei;//定義了三個struct stu類型的變量
每個變量都有三個成員,分別是num name sex
通常咱們將一個結構體類型重新起個類型名,用新的類型名替代原先的類型
**最常用的定義結構體的方法是:
typedef struct stu{
int num;
char name[20];
char sex;
}STU;
STU lucy;
三、初始化及使用:
typedef struct stu{
int num;
char name[20];
char sex;
}STU;
STU lucy={101,"lucy",'f'};
STU bob;
bob.num=101;//bob是個結構體變量,但是bob.num是個int 類型的變量
bob.name 是個字符數組,是個字符數組的名字,代表字符數組的地址,是個常量
bob.name ="bob";//是不可行,是個常量
strcpy(bob.name,"bob");
四、結構體數組
結構體數組是個數組,由若干個相同類型的結構體變量構成的集合
1、結構體數組的定義方法:
struct stu{
int num;
char name[20];
char sex;
};
struct stu edu[3];//定義了一個struct stu 類型的結構體數組edu,
這個數組有3個元素分別是edu[0] 、edu[1]、edu[2]
可以這樣賦值:STU edu[3]={
{101,"Lucy",78},
{102,"Bob",59.5},
{103,"Tom",85}
};
2、數組元素的使用
edu[0].num =101;//用101給edu數組的第0個結構體變量的num賦值
strcpy(edu[1].name,"lucy");
五、結構體指針
即結構體的地址,結構體變量存放內存中,也有起始地址
定義一個變量來存放這個地址,那這個變量就是結構體指針變量。
1、結構體指針變量的定義方法:
struct stu{
int num;
char name[20];
};
struct stu * p;//定義了一個struct stu *類型的指針變量,變量名是p,p占4個字節,用來保存結構體變量的地址編號
使用: struct stu boy;
p=&boy;
訪問結構體變量的成員方法:
boy.num=101;//可以,通過結構體變量名.成員名
(*p).num=101;//可以,*p相當于p指向的變量boy
p->num=101;//可以,指針->成員名
通過結構體指針來引用指針指向的結構體的成員,前提是指針必須先指向一個結構體變量。
六、結構體內存分配
為什么要有字節對齊?
用空間來換時間,提高cpu讀取數據的效率
結構體變量大小是所有成員之和
規則1:結構體分配內存時哪個基本類型的成員占字節數多,就以它的大小為單位開辟內存,
在gcc中出現了double類型的,例外
1:成員中只有char型數據 ,以1字節為單位開辟內存。
2:成員中出現了short int 沒有更大字節數的基本類型數據以2字節為單位開辟內存
3、出現了int float 沒有更大字節的基本類型數據的時候以4字節為單位開辟內存。
4、出現了double類型的數據
情況1:
在vc里,以8字節為單位開辟內存。
情況2:
在gcc里,以4字節為單位開辟內存。
無論是那種環境,double型變量,占8字節。
注意:
如果在結構體中出現了數組,數組可以看成多個變量的集合。
如果出現指針的話,沒有占字節數更大的類型的,以4字節為單位開辟內存。
在內存中存儲結構體成員的時候,按定義的結構體成員的順序存儲。
例1:struct stu{
char sex;
int age;
}lucy;
lucy的大小是4的倍數。
規則2:字節對齊
1:char 1字節對齊 ,即存放char型的變量,內存單元的編號是1的倍數即可。
2:short int 2字節對齊 ,即存放short int 型的變量,起始內存單元的編號是2的倍數即可。
3:int 4字節對齊 ,即存放int 型的變量,起始內存單元的編號是4的倍數即可
4:long int 在32位平臺下,4字節對齊 ,即存放long int 型的變量,起始內存單元的編號是4的倍數即可
5:float 4字節對齊 ,即存放float 型的變量,起始內存單元的編號是4的倍數即可
6:double
1.vc環境下
8字節對齊,即存放double型變量的起始地址,必須是8的倍數,double變量占8字節
2.gcc環境下
4字節對齊,即存放double型變量的起始地址,必須是4的倍數,double變量占8字節。
注意3:當結構體成員中出現數組的時候,可以看成多個變量。
注意4:開辟內存的時候,從上向下依次按成員在結構體中的位置順序開辟空間
例1:
struct stu{
char a;
short b;
int c;
}temp;
例3://temp 8個字節
#include<stdio.h>
struct stu{
char a;
short int b;
int c;
}temp;
結果分析:
a的地址和b的地址差2個字節
b的地址和c的地址差2個字節
例4:temp的大小為12個字節
#include<stdio.h>
struct stu{
char a;
int c;
short int b;
}temp;
結果分析:
a和c的地址差4個字節
c和b的地址差4個字節
例5:
struct stu{
char buf[10];
int a;
}temp;
//temp占 16個字節
例6:
struct stu{
char a;
double b;
}temp;
temp:
在vc中占 16個字節 a和b的地址差8個字節
在gcc中占 12個字節 a和b的地址差4個字節
#include<stdio.h>
struct stu{
char a;
double b;
}temp;
指定對齊原則:
使用#pragma pack改變默認對其原則
#pragma pack (value)
1.value只能是:1 2 4 8等
2.指定對齊值與數據類型對齊值相比取較小值
說明:咱們制定一個value
1:以多少個字節為單位開辟內存
結構體成員中,占字節數最大的類型長度和value比較,
取較小值,為單位開辟內存
例7:
#pragma pack(2)
struct stu{
char a;
int b;
} ;
以2個字節為單位開辟內存
#include<stdio.h>
#pragma pack(2)
struct stu{
char a;
int b;
}temp;
int main()
{
printf("%d\n",sizeof(temp));
printf("%p\n",&(temp.a));
printf("%p\n",&(temp.b));
return 0;
}
temp的大小為6個字節
a和b的地址差2個字節
如:如果指定對齊值:
設為1:則short、int、float等均為1
設為2:則char仍為1,short為2,int 變為2
七、位段
在結構體中,以位為單位的成員,咱們稱之為位段(位域)。
struct packed_data{
unsigned int a:2;
unsigned int b:6;
unsigned int c:4;
unsigned int d:4;
unsigned int i;
} data;
對于位段成員的引用如下:
data.a =2
賦值時,不要超出位段定義的范圍;
如段成員a定義為2位,最大值為3,即(11)2
所以data.a =5,就會取5的低兩位進行賦值 101
八、共用體
**每次只能使用共用體的一個變量
幾種不同類型的變量存到同一段內存單元中,幾個變量所使用空間相互重疊
? 這種幾個不同的變量共同占用一段內存的結構,在C語言中,被稱作“共用體”類型結構
? 共用體所有成員占有同一段地址空間
共用體的大小是其占內存長度最大的成員的大小
typedef union data{
short int i;
char ch;
float f;
}DATA;
DATA temp2;
共用體temp2占4個字節,即i、ch、f共用4個字節
九、枚舉
將變量的值一一列舉出來,變量的值只限于列舉出來的值的范圍內
例:
定義枚舉類型 week
enum week //枚舉類型
{
mon,tue,wed,thu,fri,sat,sun
};
enum week workday,weekday;//枚舉變量
workday與weekday只能取sun….sat中的一個
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。