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