一、结构体
1、结构体类型设计
c语言提供了基本数据类型,比如char,bool,short int,int ,long int,long long,float,double,long double都称为内置数据类型。程序员可以用结构体来封装一些属性。
结构体举例
struct student//struct用来声明这是结构体类型,而student就是类型名,或结构体名。
{
//里面存放的数据可以是基本数据类型,也可以是其他结构体类型,可以进行嵌套
char s_name[10];
char s_id[10];
int s_age;
};//最后的分号不能少,比如int a;
注意: 结构体本身并不占用空间,结构体变量才会占用
2、结构体变量的初始化
a、 ex:
int main()
{
struct student s1 = { "liujin","520",18 };
struct student s2 = { "yuke","521",18 };
}
结构体变量名最然不同,但基本属性都是相同的,因此可以相互赋值。
**b、**结构体可以进行嵌套ex:
int main()
{
struct student s1 = { "liujin","520",18 };
struct student s2 = { "yuke","521",18 };
s1=s2;
}
结构体的嵌套
struct brithday
{
int year;
int month;
int day;
};
struct student
{
char s_name[10];
char s_id[10];
int s_age;
struct birthday a1;
};
int main()
{
struct student s1={"liujin","521",18,{2001,1,1}};
struct student s2=s1;//相同结构体类型之间可以相互赋值
}
注意 :不能在结构体中在再定义一个本结构体类型的变量,这样的话会无限套娃,计算sizeof的时候也不能计算出,但是可以在里面定义一个结构体类型的指针,因为指针的大小是个固定的,可以放在结构体里。
3、 结构体变量成员的访问
1、定义结构体变量来访问,用{ }来进行初始化
2、用已定义的结构体变量来初始化
3、相同类型的结构体变量之间可以相互赋值
结构体变量和指针
struct student
{
char s_name[10];
char s_id[10];
int s_age;
struct birthday a1;
};
struct student s1={"liujin","520",18,{2001,1,1}};
struct student *p=&s1;
//两种访问写法
(*p).s_name="yuke";
p->s_age=17;
原因:.的优先级高于*因此要用(*p).相当于p->; ->称为指向符
4、结构体和函数
struct Brithday
{
int year;
int month;
int day;
};
struct student
{
char s_name[10];
char s_id[10];
int s_age;
struct Brithday a1;
};
void Print(struct student* p)
{
printf("%s %s %d %d,%d,%d", p->s_name, p->s_id,p->s_age, p->a1);
}
int main()
{
struct student s1 = { "liujin","520",18,{2001,1,1} };
struct student s2 = { "yuke","521",18 };
struct student* p = &s1;
Print(p);
}
函数中用结构体类型做形参时,将结构体转换成指针类型可以,加快读取速率。
5、结构体大小
struct student
{
char name;
char id;
int age;
double score;
};
struct student s1;
sizeof(s1);//16
规则:
1、结构体变量首地址必须是成员内最大基本数据类型所占字节数的整数倍。
2、结构体变量成员的偏移量都是该成员基本数据字节数的整数倍
3、结构体变量所占空间的大小必须是该结构成员变量内,所占字节数最大基本数据类型的整数倍。
指定对齐方式
改变对齐方式
#pragma pack(n) //n必须是1 2 4 8…必须是2的幂次
.
.
#pragma pack()
#pragma pack(4)//指定对齐方式
struct student
{
char name;
int id;
int age;
double score;
};
struct student s1;
sizeof(s1);//20
#pragma pack()//以#pragma pack()结尾
改变对其方式之后,会在最大字节基本数据类型和n之间取最小值进行对齐
二、联合体
联合体与结构体相似,但是不同之处是,联合体内不同成员变量用的是,相同的空间
union node
{
short x;
char ar[2];
};
int main()
{
union node s1;
s1.x = 0x6162;//十六进制6162
printf("%c %c \n", s1.ar[0], s1.ar[1]);//b a
s1.ar[0] = 1, s1.ar[1] = 2;
printf("%d \n", s1.x);//0000 0010 0000 0001 513
}