???1.結構體
???個人認為結構體和數組特別相似,只不過結構體和數組的區別在于結構體的成員可以是不同類型,而數組成員類型是相同的。
???(1)結構體的聲明
struct tag
{成員列表
}值列表;
struct
{int a;char b;float c;
}x;struct
{int a;char b;float c;
}a[5 ],*p;
???(2)結構體成員
?????結構體成員可以是int,float,double,char等基本類型,也可以是數組,指針,甚至結構體,枚舉等都可以。結構體成員在訪問的時候采用結構結構體.成員名的方式來訪問如:
#include<stdio.h>
struct Student
{char name[20 ];int age;int grade;
};
int main()
{struct Student student;.printf ("%s\n" , student.name);printf ("%d\n" , student.age);printf ("%d\n" , student.grade);return 0 ;
}
???由上可以看出,結構體的定義通過struct 結構體名來定義一個變量,但需要注意,單獨的聲明一個結構體類型,系統不為之開辟空間。
???舉個例子
struct Student
{char name[20 ];int age;int grade;
};
struct Student student;
???(3)結構體成員的訪問
????結構體成員的訪問采用.的方式訪問,當有結構體指針的時候必須先對其解引用或者是結構體指針名 -> 成員名才可對其成員訪問。
????舉個例子
#include<stdio.h> struct Student
{char name[20 ];int age;int grade;
};
int main()
{struct Student student;.stuct Student* student1;printf ("%s\n" , student.name);printf ("%d\n" , student.age);printf ("%d\n" , student.grade);printf ("%d\n" , (*student1).grade);printf ("%d\n" , student1 -> age);return 0 ;
}
???(4)結構體的自引用
struct Student
{char name[20 ];char sex[5 ];int age;struct Student* student;
};
typedef struct Student
{char name[20 ];char sex[5 ];int age;struct Student* Next;
}Student;
???(5)結構體的初始化
struct Student
{char name[20 ];char sex[5 ];int age;int grade;
};
struct Student student = {"張三" , "男" , 20 , 90 };
struct Student student1;
strcpy (student1.name, "李四" );
strcpy (student1.sex, "男" );
student1,age = 20 ;
student1.grade = 89 ;
???(6)結構體的內存對齊
???結構體大小的計算
????幾條規則
????????1.結構體的第一個成員始終對齊于偏移量為0的地址(offsetof(結構體名, 成員名))處
????????2.后面的結構體成員對齊與某個數字(對齊數)的整數倍的地質處。其中對齊數在VS上默認是8,在Linux上默認是4。其中*對齊數* = 默認對齊數和自身成員大小的較小值
????????3.結構體的總大小為最大對齊數
????????4.結構體如果嵌套了結構體,嵌套的結構體對齊到自己的最大對齊數的整數倍的地址處。
????舉個例子
#include<stdio.h>
int main()
{struct S1{char c1;int i;char c2;};struct S2{char c1;char c2;int i;};struct S3{double d;char c;int i;};struct S4{char c1;struct S3 s3;double d;};printf ("%d\n" , sizeof (struct S1));printf ("%d\n" , sizeof (struct S2));printf ("%d\n" , sizeof (struct S3));printf ("%d\n" , sizeof (struct S4));return 0 ;
}
?????不同平臺對地址的訪問要求不同,不是所有的硬件平臺都可以訪問任意地址的數據,有的硬件平臺規定某些平臺只能訪問某些特定的數據,所以當訪問不正確是會出現錯誤,而且如果沒有內存對其,有的數據本來一次可以訪問到,但卻要兩次訪問,這樣大大降低了內存的訪問速度,因此便有了結構體的內存對其。
???(7)結構體傳參
?????結構體在傳參時為了節省內存,在傳參時采用地址傳參,同時要對其成員進行訪問時可以通過對其地址解引用的方式訪問其成員
???(8)結構體的位段
?????舉個例子
struct A
{int _a:2 ;int _b:5 ;int _c:10 ;int _d:30 ;
};
printf ("%d\n" ,sizeof (struct A));
????A.位段的內存分配
?????a.位段成員只能是整型家族int,unsigned int , signed int,char
?????b.不跨平臺
?????c.按一字節或四字節方式分配
????B位段中的問題
??????a.將其當成有符號還是無符號不確定
??????b.成員內存從左分配還是從右分配不確定
??????c.當包含多個位段時,前一個位段所剩余內存應該舍棄還是保存都不確定
??????d.位段中最大位的數目不同機器不同
???2.枚舉
???(1)枚舉定義
??????將有限個可能取值都一一列舉出來
enum Sex
{MALE,FEMALE,SECRET
};
???(2)枚舉的優點
??????A.增加代碼可讀性和可維護性
??????B.比起宏定義來,枚舉對類型檢查較為嚴謹
??????C.使用方便,一次可以定義多個變量
??????D.具有一定的封裝代碼作用
???3.聯合體
???(1)聯合特點
??????聯合體公用一塊內存空間
#include<stdio.h> int main()
{union Un1{char c[5 ];int i;};union Un2{short c[7 ];int i;};printf ("%d\n" , sizeof (union Un2));return 0 ;
}