【摘要】为了解决将不同的数据存储在一起并且方便操作的问题,出现了结构体,它就可以实现存储不同类型的数据,结构体中的数据称作成员,通过成员的名字,你就可以操作这个结构体
结构体的出现,是为了解决要将不同的数据存放在一个结构里面的问题,数组中只能放单一类型的数组,而且数组有时候操作起来也不是那么方便,因此结构体应运而生。
这篇文章将会提及一下方面
1. 结构体的定义以及变量的声明
2.结构体的内存对齐问题
3.结构体的大小
4.如何访问结构体里面的成员
5.结构体嵌套
6.结构体数组(最常用)
7.结构体与位段
一.结构体的定义以及变量声明
struct CLA //定义了一个结构体,但是还不能进行操作,因为没有进行声明结构体变量
{
char ch; //结构体内部的三个成员 ch,i,d
int i;
double d;
};
由于不能使用结构体,于是再给后面加上一个变量名进行实例化
struct CLA
{
char ch;
int i;
double d;
}stu; //声明一个结构体变量,此时就可以对结构体中的成员进行操作
二.结构体的内存对齐问题
结构体中由于是不同类型的数据的集合,因此在进行存储的时候会出现内存对齐的问题,这样做也是为了便于数据在内存中的存储,如果是windows环境下64位操作系统的话,默认对齐数是8个比特位,因此结构体的大小应该是8的整数倍,具体对齐方式如下
1.如果不满8个比特位的数据,就按占8个比特位进行存储,
2.如果,超过了8个比特位,就在下一个8个比特位中存储,
3.利弊 结构体的存储可能会造成内存浪费的问题,但是这样做的好处就是便于数据的操作,在内存足够的情况下,可以忽略它的缺点。
三.结构体的大小(基于内存对齐)
1.一个结构体的大小就是结构体内部数据占用的内存大小的总和,而结构体数组的大小就是数组内部存在的几个结构体大小之和
2.结构体内存占用和数据的存储先后也有关系,尽量把数据可以放在一个对齐位数大小的存储空间中可以节约内存空间
3.如果需要创建几百上千个结构体时,内存的占用显得尤为重要,但是也需要注意代码的可读性。
#include<stdio.h>
#include<stdlib.h>
struct CLA
{
char ch;
int i;
double d;
}stu,*p;
struct CLA mystru,mystru_arr[3];
int main()
{
printf("sizeof(char)=%d\n",sizeof(char));
printf("sizeof(int)=%d\n",sizeof(int));
printf("sizeof(double)=%d\n",sizeof(double));
printf("sizeof(CLA)=%d\n",sizeof(CLA));
printf("sizeof(CLA_F)=%d\n",sizeof(mystru));
printf("sizeof(mystru_arr)=%d\n",sizeof(mystru_arr));
printf("sizeof(p)=%d\n",sizeof(p));
system("pause");
return 0;
}
四.如何访问结构体里面的成员
结构体成员的访问有专门的操作符 (.)操作符,这个操作符的用法是 :变量名.成员名
如果定义了一个结构体指针指向了这个结构体,那么成员的访问就要使用另一个操作符(->)操作符
指针访问结构体的一个优点就是它不用再将冗杂的结构体再写一遍,可以增加程序的可维护性,也可以使代码更精简
struct CLA
{
char ch;
int i;
double d;
}stu,*p;
p->ch //这里就可以通过指针访问结构体得成员
五.结构体的嵌套
结构体的嵌套是可以实现的,但是需要注意一个问题:在一个结构体里面嵌套另一个结构体时,必须在这之前声明被嵌套的结构体,否则计算机并不清楚你要嵌套的结构体到底在哪里,就会出现错误
struct Data //事先声明结构体Data
{
int year;
int mouth;
int day;
}y;
struct Stu
{
char name[8];
int id;
Data birth; //嵌套结构体时顺便加入一个变量
}x;
用图片来表示结构体变量y中存储的数据
结构体嵌套的使用,通常是为了解决一个结构体太过庞大而进行分开声明的,这样做使得代码的调试没有那么麻烦,不过也有缺点,这样做有可能会导致成员的错误访问,得到你不想要的结果
六.结构体数组的使用
结构体数组的使用,可以方便我们进行大量不同类型数据的存储和操作。
结构体数组本质上也是一个数组,不过它的下标访问的不是一个数据而是一个结构体。因此,结构体数组在使用的过程中也是遵循数组的一些规则。
与数组的区别:结构体数组在进行数据操作的时候不会将数组退化为指针,因此,操作时必须用取地址符号(&)
注意问题:同样的,结构体数组也不能下标越界,因此在使用之前应该先进行有效性检查,除此之外,结构体数组加1,就是加的结构体的大小,这点和数组时相似的
struct CLA
{
char ch;
int i;
double d;
}stu,*p;
struct CLA mystru,mystru_arr[3];//定义一个结构体数组,里面有三个结构体
七.结构体与位段
位段的成员后面有一个冒号和一个整数,这个整数指定该位所占用的位的数目
struct Char {
unsigned ch : 7; //指定占用7个位
unsigned font :6; //指定占用6个位
unsigned size :19;//指定占用19个位
};
struct Char ch1;
1. 位段的出现,是为了解决结构体内存浪费的问题
2. 位段和结构体的声明很类似,但是位段的使用有一些要求,位段里面存储的数据必须是整型.有符号整型或者无符 号整型
3.使用位段会导致程序可移植性减弱
4.使用位段需要避免内存位置的边界上形成重叠
注:我也是个初学者,有任何纰漏之处欢迎大家指正,一定虚心接受。