结构体
结构体
一、什么是结构体
结构体指的是有一个结构,在这个结构中,可以存不同类型的变量,而且相互不影响,是一种自定义类型
C语言的结构体中,不能写函数
二、结构体的定义
struct //结构体名
{
//成员==>成员就是定义的变量
};//以分号结尾
//C语言中的结构体,结构体必须要有至少一个成员
//定义结构体 由不同变量组合在一起的结构
struct Student
{
char name[20];
int id;
char sex[3];
char classnum[100];
};
1.结构体变量,访问里面的成员,通过 . 访问
初始化赋值及访问
#include <stdio.h>
#include<string.h>
struct Student
{
char name[20];
int id;
char sex[3];
char classnum[100];
};
int main()
{
//定义结构体变量
//struct Student stu1;
//通过变量名.成员名
//stu1.id = 1;
//从键盘输入
scanf("%d",&(stu1.id));
//strcpy(stu1.name, "苏宇");
struct Student stu1 = {
"苏宇",1,"男","2011期"
};
printf("%s\t%d\t%s\t%s\n", stu1.name, stu1.id, stu1.sex, stu1.classnum);
getchar();
getchar();
return 0;
}
三、结构体数组
数组:类型 数组名[大小]
1.结构体数组:
struct student stu[5];
#include <stdio.h>
#include<string.h>
struct Student
{
char name[20];
int id;
char sex[3];
char classnum[100];
};
int main()
{
struct Student stu1[5] = {
{"苏宇",1,"男","2011"},
{"小宇",2,"男","2012"},
{"大宇",3,"男","2013"},
{"老宇",4,"男","2014"},
{"英语",5,"女","2015"}
};
//同等类型的结构体变量之间可以相互赋值
stu1[1]=stu1[2];
for (int i = 0; i < 5; i++)
{
printf("%s\t%d\t%s\t%s\n",
stu1[i].name, stu1[i].id, stu1[i].sex, stu1[i].classnum);
}
getchar();
getchar();
return 0;
}
2.计算结构体的内存
struct node
{
int a;
double b;
};
int main()
{
printf("%d", sizeof(struct node));
//内存占16个字节
//这是自动补齐内存
struct node n={1.23,99};
printf("%lf\t%d\n",n.b,n.a);
//用指针操作
double* p=(double*)&n;//必须要强转成相同类型
printf("%d\n",*p);//只能打印1.23000002
printf("%d\n",*(int*)(p+1));//只能打印99
}
/*
如果是char[10]这样的数组,计算内存时
struct node
{
int a;
char b[5];
char c[6];
}
计算这个结构体的大小是:先找最大的int占4个字节,再去补后面的char
0000==>int 完整的 0000
0000 0000
0==>char[5] 0000
0000 0000
00==>char[6]
所以一共是16个字节
四、结构体指针
1.如果直接用结构体指针指向成员,那么就是结构体指针->成员名
2.如果还是用.成员的方式,那么就先解引用结构体指针得到结构体变量,然后.成员
值传递,址传递
struct stu
{
int id;
char name[20];
};
void func1(struct stu n)//值传递
{
n.id;
n.name;
}
void func2(struct stu* p)//用指针进行地址传递
{
p->id;
p->name;
}
int main()
{
struct stu n = { 1,"苏宇" };
struct stu* p = &n;
//访问可以使用 (*p).id
printf("%d\t%s\n", p->id, p->name);
printf("%d\t%s\n", (*p).id, (*p).name);
}
3.动态申请内存(堆区)
要包含头文件 #include<stdlib.h>
#include<stdio.h>
#include<stdlib.h>
struct stu
{
int id;
char name[20];
};
int main()
{
//节省内存
struct stu* pn=(struct stu*)malloc(sizeof(struct stu));
pn->id=123;
//相当于是
//(*pn).id=123;
printf("%d\n",pn->id);
free(pn);
pn=NULL;
//使用完之后,释放内存,再置空
}
五、公用体 联合
union node
{
int num;
float hight;
};
int main()
{
union node n;
n.num=123;
printf("%d\n",n.num);//输出123
n.hight=175;
printf("%d\n",n.num);//输出的是一个乱码
//因为公用体同一时间只能存放同一类型的值
}
都是用来优化程序的
六、枚举
穷举:把所有的东西一一列举出来
enum week//枚举是从0开始的,后面的值等于前面的值加一
{
one,two,three,four,
five,six,seven
};
enum dir
{
hero=2;
wall=1;
box=3;
}
int main()
{
enum week w;
w=4;
//one==0,two==1 .....
switch (w)//输入w,双击后,按enter键
{
case one:
break;
case two:
break;
case three:
break;
case four:
break;
case five:
printf("666\n");
break;
case six:
break;
case seven:
break;
default:
break;
}
}
七、typedef
//typedef 真名 别名
struct node
{
int id;
struct
{
int asd;
int a;
}n1,n2,n3;//n1,n2,n3是这个结构体定义的变量
};
typedef struct node N;
int main()
{
//访问
N n;
n.n1.a;
n.id=123;
printf("%d\n",n.id);
}
//N就代替了struct node
//也可以
typedef struct node1
{
int id;
}A;//A是别名
struct Student stu[20] = {
{"王飞",1,"女","2011期C语言"},
{"李飞",2,"男","2012期C++"},
{"张飞",3,"男","2013期数据结构"},
{"不飞",4,"女","2014期"} , {
"老飞",5,"男","不知道是那一期"},
}; 要实现的效果,将3删除掉
#include <stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#define SIZE 10
#define size strcmp(a1,a2)
//可以运用到推箱子这样的程序,循环比较多的,方便改动
/*
struct Student stu[20] = {
{"王飞",1,"女","2011期C语言"},
{"李飞",2,"男","2012期C++"},
{"张飞",3,"男","2013期数据结构"},
{"不飞",4,"女","2014期"} ,
{"老飞",5,"男","不知道是那一期"},
};
要实现的效果,将3删除掉
*/
typedef struct Student
{
char name[20];
int id;
char sex[3];
char classnum[100];
}stu;
stu* pStu = NULL;//动态数组 结构体指针
int len = 0;//表示元素个数 //全局普通变量
int maxSize = 10;//动态数组当前最大容量
void init()//初始化数组,用来初始化数组
{
pStu = (stu*)malloc(sizeof(stu)*maxSize);
//申请到的内存空间,系统默认是void类型的字节,
//需要void*去接收,不过这里是stu*类型的指针
//sizeof不用pStu是因为他是指针类型只有四个字节
}
void initsert(stu* s)//把一个元素放入动态数组末尾
//stu* s=struct Student* s 一个叫s的结构体指针
{
if (len >= maxSize)
//如果动态数组元素>动态数组最大容量,就需要扩容了
{
//申请一块新内存
stu* temp = (stu*)malloc(sizeof(stu)*(maxSize * 2));
memcpy(temp, pStu, sizeof(stu)*len);
if (pStu != NULL)
{
free(pStu);
}
pStu = temp;
}
//pStu[len++] = *s;
*(pStu + len) = *s;//赋值,一次只赋一个值
len++;
}
void Print()//输出结构体
{
for (int i = 0; i < len; i++)
{
printf("%s\t%d\t%s\t%s\n",
pStu[i].name, pStu[i].id, pStu[i].sex, pStu[i].classnum
);
}
}
void delete_id(int id)//删除操作
{
for (int i = 0; i < len; i++)
{
if (pStu[i].id == id)
{
for (int j = i; j < len; j++)
{
pStu[j] = pStu[j + 1];
}
len--;
}
}
}
int main()
{
struct Student sten[20] = {
{"王飞",1,"女","2011期C语言"},
{"李飞",2,"男","2012期C++"},
{"张飞",3,"男","2013期数据结构"},
{"不飞",4,"女","2014期"} ,
{"老飞",5,"男","不知道是那一期"},
{"王飞",1,"女","2011期C语言"},
{"李飞",2,"男","2012期C++"},
{"张飞",3,"男","2013期数据结构"},
{"不飞",4,"女","2014期"} ,
{"老飞",5,"男","不知道是那一期"},
{"王飞",1,"女","2011期C语言"},
{"李飞",2,"男","2012期C++"},
{"张飞",3,"男","2013期数据结构"},
{"不飞",4,"女","2014期"} ,
{"老飞",5,"男","不知道是那一期"},
{"王飞",1,"女","2011期C语言"},
{"李飞",2,"男","2012期C++"},
{"张飞",3,"男","2013期数据结构"},
{"不飞",4,"女","2014期"} ,
{"老飞",5,"男","不知道是那一期"},
};
init();//初始化数组
for (int i = 0; i < 20; i ++ )
{
//initsert(sten + i);//stu=s
//struct Student* s=struct Student* (stu+i)
initsert(&sten[i]);
//因为initsert(形参),里面的形参是struct Student* s是指针类型
//所以要取内容,才能得到值
//相当于initsert(*sten)
//将sten中的内容取出来
}
delete_id(3);
delete_id(4);
Print();
free(pStu);
pStu = NULL;
getchar();
getchar();
return 0;
}