结构体

结构体

一、什么是结构体

结构体指的是有一个结构,在这个结构中,可以存不同类型的变量,而且相互不影响,是一种自定义类型

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;
}



posted @ 2020-12-10 00:15  kisfly  阅读(501)  评论(0编辑  收藏  举报