3、结构体变量的存储原理
结构体占用的内存空间是每个成员占用的字节数之和。(考虑对齐的问题)
内存对齐:计算机系统对基本数据类型在内存中存放的位置有限制,要求这些数据的起始地址的值是某个数k的倍数,这就是内存对齐。这个k被称为该数据类型的对期模数。
结构体变量的长度:
1)先找对齐模数
对齐模数是结构体中的基本数据类型中占用自己数最大的那个
2)在计算机结构体变量中的各个成员占用的字节和
例1:
//定义一个结构体
struct A{
int a; //int占4个字节
char b; //char占1个字节
float c; //float占4个字节
}; //故模数是4
//定义结构体变量
struct A A1;
printf("%ld\n",sizeof(A1)); //总字节数是12
例2:
//定义一个结构体
struct A{
short a; //short占2个字节
float b; //float占4个字节
char c; //char占1个字节
double d; //double占8个字节
}; //故模数是8
//定义结构体变量
struct A A2;
printf("%ld\n",sizeof(A2)); //总字节数是24 (内部有转化)
例3:
//定义一个结构体
struct A{
char ch[13]; //char占1个字节,分配了4个int字节,即16个字节,ch1补了3个字节
char ch1[13]; //char占1个字节,补给ch3个字节,还剩10个字节,则给它分配3个int字节的空间,即12个字节
int a; //int占4个字节
}; //故模数是4
//定义结构体变量
struct A A3;
printf("%ld\n",sizeof(A3)); //总字节数是32
结构体作用域
全局结构体和局部结构体,同全局变量和局部变量一样。
结构体数组
指的是结构数组的每一个元素都是具有相同结构类型的下标的结构变量,即用来存放大量的结构体相同的结构变量。
定义格式:
第一种格式: 定义结构体的同时,定义数组
struct 结构体名{
成员表列
}数组名[数组长度];
例:struct Stu{
int age;
char *name;
int num;
float score;
}stu[5];
第二种格式:先定义结构体,后定义数组
struct 结构体名 结构体数组;
结构体数组初始化
1)定义结构体数组的时候进行初始化
struct Stu{
char name[20];
int age;
}boys[3]={{"love",25},{"ying",24},{"jun",23}};
2)定义的同时初始化
struct Stu girl[3]={{"hui",21},{"hu",22},{"jia",23}};
3)先定义结构体数组,后初始化,整体赋值
struct Stu s[2];
s[0]=(struct Stu){"junjun",21};
s[1]=(struct Stu){"ying",22};
4)先定义结构体数组,后初始化
struct Stu stu[2];
strcpy(stu[0].name,"junjun");
或者scanf("%s",stu[0].name);
stu[0].age=19;
stu[0].name="ying";(这样写是不对的,对字符串不能这么初始化)
结构体数组的遍历
用for语句遍历
例:for(i=0;i<3;i++)
{
printf("name:%s,age:%d\n",boys[i].name,boy[i].age);
}
指向结构体变量的指针
定义格式: struct 结构体名 *结构体变量名
结构体指针变量中的值是所指向的结构体变量的首地址
例:struct stu *pstu; //定义指针pstu只能指向stu结构体类型的结构体变量
结构体指针赋值:是把结构体变量的首地址赋予该指针变量,不能把结构名赋予指针变量。
例:
struct stu{
int num;
char name[10];
char sex;
float score;
}boy;//定义结构体变量boy
struct stu *ps;//定义指向结构体变量的指针
ps=&boy; //将结构体变量boy的首地址赋予该指针变量
结构体指针间接访问成员值
一般形式:(*结构体指针变量).成员名 //*两边的括号不能少,因为成员符“.”的优先级高于"*"
或者:结构体指针变量->成员名
例如:(*ps).num;或者ps->num;
结构体嵌套
定义:在结构体定义中,结构体的成员又是另一个结构体变量。
例:
struct Time{
int hour;
int min;
int sec;
};
struct Date{
int year;
int month;
int day;
//嵌套Time的结构体
struct Time time;
};
struct Stu{
char *name;
int age;
char sex;
float score;
struct Date birthday; //嵌套其他结构体类型的变量,但不可嵌套自己这个类型的变量
};
在stu中嵌套存储Date结构体内容:month、day、year。
注意:结构体定义中可以嵌套其他结构体类型的变量,但不可嵌套自己这个类型的变量;可以嵌套自己类型的指针。
嵌套的结构体如何进行初始化
struct Stu st1={"jun",25,'M',89.99f,{1989,6,1}};
嵌套的结构体如何进行访问
printf("姓名:%s, 年龄:%d(生日:%d-%02d-%02d), 性别:%c, 成绩:%5.2f\n",st1.name,st1.age,st1.birthday.year,st1.birthday.month,st1.birthday.day,st1.sex,st1.score);
两层嵌套的结构体如何进行初始化
struct Stu st1={"jun",25,'M',89.99f,{1989,6,1,{12,13,14}}};
两层嵌套的结构体如何进行访问
printf("姓名:%s, 年龄:%d(生日:%d-%02d-%02d %02d:%02d:%02d), 性别:%c, 成绩:%5.2f\n",st1.name,st1.age,st1.birthday.year,st1.birthday.month,st1.birthday.day,
st1.birthday.time.hour,st1.birthday.time.min,st1.birthday.time.sec,st1.sex,st1.score);
结构体嵌套的另一个形式:
struct Per{
char *name;
int age;
struct Per *child;//嵌套自己类型的指针
};
//结构体嵌套自身指针的,初始化
struct Per kimi={"kimi",8,NULL};
//struct Per *child=&kimi;
struct Per p1={"林志颖",38,&kimi};
//结构体嵌套自身指针的,访问
printf("%s的儿子是:%s,儿子的年龄:%d\n",p1.name,(*p1.child).name,p1.child->age);
结构体成员名做函数的参数(值传递)
例:struct Car{
int Wheel;
int speed;
};
void mend(int n)
{
n=2;
}
struct Car car={4,200};//定义结构体变量并进行初始化
mend(car.Wheel);//结构体成员名car.Wheel作函数参数
结构体成员变量名做函数的参数(值传递)
void mend0(struct CarC c2)
{
c2.Wheel=2;
}
mend0(car);//结构体变量名car作函数参数
结构体指针变量作函数的参数
void mend1(struct CarC *c3)
{
c3->Wheel=2;
}
struct Car *c1;
mend1(&car);//结构体指针变量作函数参数(地址传递)
|
|