定义
将不同的类型结合成一个整体 比如一个学生的学号,姓名,年龄,地址
有一点像python的class,如果有python基础的话会比较好理解
系统不会为结构体开辟空间 只会为结构体定义的变量开辟空间!!!
用法
struct student
{
int num;// 结构体成员 定义时不要给初始化
char name[32];
};
// 结构体中的成员拥有独立的空间
// 访问的方法是 结构体变量.成员名
void test01()
{
// student lucy; // lucy为结构体变量名
// cout << lucy.num << endl;// 不初始化结果为0
student lucy={100,"xiaoming"};
cout << lucy.num << " "<< lucy.name << endl;
}
如果在不知道初始值的情况下,用memset直接初始化0
#include <string.h>
void test02()
{
student lucy;
// void * __cdecl memset(void *_Dst,int _Val,size_t _Size);
memset(&lucy,0,sizeof(lucy));
cout << lucy.num << " "<< lucy.name << endl;
}
相同类型结构体变量之间的赋值有两种方法,一个是逐个成员赋值,第二种是相同类型的结构体赋值
// 相同类型结构体变量之间的赋值
void test03()
{
student lucy = {100,"lcuy"};
student bob;
bob.num = lucy.num;
// bob.name = lucy.name;//这样写是错误的,因为name是字符串常量,放置在文字常量区,只能可读,不能赋值
strcpy(bob.name,lucy.name);
// 第二种方法:相同类型的结构体变量可以直接赋值 (推荐)
bob = lucy;
}
结构体数组
本质是数组,只是数组的每个元素是结构体变量
void test04()
{
student arr[5] = {{100,"lucy"},{101,"bob"},{102,"tom"},{103,"jerry"},{104,"john"}};
int n = sizeof(arr)/sizeof(arr[0]);
int i;
for(i = 0;i<n;i++)
{
cout<<arr[i].num<<" "<< arr[i].name<<endl;
}
}
结构体指针变量
结构体指针变量本质是指针变量,只是该变量保存的是结构体变量的地址
有两种方式 一个是用*p.访问,另一个使用->访问
void test05()
{
student lucy = {100,"lucy"};
student *p = &lucy;
cout << lucy.name << " "<< lucy.num<<endl;
cout << (*p).name << " "<< (*p).num <<endl;
// 通过指针变量,使用-> 访问变量
cout << p ->name << " " << p->num<< endl;
// 如果是地址可以直接使用 ->访问成员 如果是结构体变量,需要用.访问成员
cout << (&lucy) ->name << " " << (&lucy)->num<< endl;
}
结构体的指针成员,即结构体中的成员是指针
#include<string.h>
struct stu
{
int num;
char *name; // 这个地方要注意,如果直接使用是放在文字常量区的
};
void test06()
{
stu lucy;
lucy.num = 100;
lucy.name = new char[32]; //这样定义lucy是放在堆区的 new申请堆区空间
strcpy(lucy.name,"lucy");
cout << lucy.num <<" "<< lucy.name << endl;
stu bob = {100,"bob"};
cout << bob.name << " "<<bob.num<<endl;
}
深拷贝与浅拷贝
相同类型的结构体变量可以整体赋值,叫浅拷贝,注意浅拷贝时结构体不能存在指针成员,没有指针成员浅拷贝肯定没什么问题
深拷贝可以先开辟独立的空间,然后再赋值
浅拷贝代码示例
void test07()
{
stu lucy;
lucy.num = 100;
lucy.name = new char[32]; //这样定义lucy是放在堆区的 new申请堆区空间
strcpy(lucy.name,"lucy");
cout << lucy.num <<" "<< lucy.name << endl;
stu bob;
bob = lucy;
delete [] lucy.name;
cout << bob.name << endl;// 输出乱码
// 浅拷贝的意思是lucy和bob指向同一地址,当释放lucy的name内容时,bob的name也被释放的
}
深拷贝代码示例
void test08()
{
stu lucy;
lucy.num = 100;
lucy.name = new char[32]; //这样定义lucy是放在堆区的 new申请堆区空间
strcpy(lucy.name,"lucy");
cout << lucy.num <<" "<< lucy.name << endl;
stu bob;
bob.num = lucy.num;
bob.name = new char[32];// 深拷贝,先开辟空间
strcpy(bob.name,lucy.name);
delete [] lucy.name;
cout << bob.name << endl;//这样输出就是lucy了
// 深拷贝的时候是开辟新空间,如果lucy空间被删除并不会影响bob的name
}
结构体的对齐规则
目的 用空间换时间 比如一个 char int类型结构体构成是这样的 char int int int int, char占1位,int占4位,如果想读int数据
需要先读四个字节,char int int int 再读四个字节 int x x x ,然后合在一起
如果使用了对其规则就是 char x x x int int int int,这样想读 int 就直接读后面4个就可以,减少了时间
关于位域就不具体写了,再单片机中用于节省空间用,按位与按位或会比较复杂