复合类型

结构体定义及赋值

1、复合类型在内存中存放的模型:

2、定义结构体格式:
struct 结构体名称 { 结构体成员列表 } ; 分号结尾
在这里插入图片描述

3、在主函数中结构体表述格式:
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>


//定义结构体格式
/*
struct 结构体名称
{
	结构体成员列表

};
//定义结构体变量
 struct 结构体名称 结构体变量名 
 结构体变量名.结构体成员列表 = 值
 如果是字符串类型  需要使用strcpy
*/

struct students
{
	//成员列表
	char name[21];
	unsigned int age;
	char tel[16];
	float scores[3];
	char sex;
}stu = { "尼古拉斯",500,"13888888888",100.0f,200,300,'M' };

int main02()
{
	//按照结构体顺序 赋值
	//struct  students   stu = { "尼古拉斯",500,"13888888888",100.0f,200,300,'M' };

	//struct  students   stu = { .sex = 'M',.name = "刘能",.tel = "13777777777",.scores[0] = 100,.scores[1] = 99,.scores[2] = 88,.age = 48 };

	//struct students stu;
	stu.name = "谢广坤";
	//strcpy(stu.name, "谢广坤");
	//stu.age = 50;
	//strcpy(stu.tel, "13777777778");
	//stu.scores[0] = 90;
	//stu.scores[1] = 80;
	//stu.scores[2] = 70;
	//stu.sex = 'F';

	//strcpy(stu.name, "谢广坤");
	//stu.age = 50;
	//strcpy(stu.tel, "13777777778");
	//stu.scores[0] = 90;
	//stu.scores[1] = 80;
	//stu.scores[2] = 70;
	//stu.sex = 'F';


	printf("姓名:%s\n", stu.name);
	printf("年龄:%d\n", stu.age);
	printf("电话: %s\n", stu.tel);
	printf("成绩: %.1f   %.1f   %.1f\n", stu.scores[0], stu.scores[1], stu.scores[2]);
	printf("性别: %s\n", stu.sex == 'M' ? "男" : "女");
	system("pause");
	return EXIT_SUCCESS;
}

定义结构体变量:
①struct 结构体名称 结构体变量名
②结构体变量名.机构体成员列表 = 值
注:如果是字符串类型 需要使用strcpy;
在这里插入图片描述
4、赋值方式
①按照结构顺序赋值
在这里插入图片描述
②打印结构体成员方式:
在这里插入图片描述
打印结果
在这里插入图片描述

②赋值方式2

在这里插入图片描述

③赋值方式3
在这里插入图片描述

注意:如果是是字符串格式需要使用strcpy来进行赋值

④赋值方式4
在这里插入图片描述

结构体大小和内存结构;

1、结构体大小:
注意:结构体需要根据数据类型进行内存对齐;
在这里插入图片描述
打印结果
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

//结构体需要根据数据类型进行内存对齐
//struct stus
//{
//	char name[20];//20
//	unsigned int age;//4
//	char tel[15];//15
//	char sex;//1  52
//	float scores[3];//12
//}stu;

struct stus
{
	//char * p;   //4
	//char arr[2];//2  8
	//short d; //2   16
	//int c;  //4 
	//long g;//4    
	//double f;//8  24
	//float h[2];//8   40


	double f;//8  24
	float h[2];//8   40
	long g;//4    
	int c;  //4 
	char * p;   //4
	short d; //2   16
	char arr[2];//2  8


	/*
	姓名:  char name[200];
	等级: int 
	当前经验:int 
	攻击: int 
	防御:int 
	技能冷却:foat 

	*/


}stu;


int main03()
{
	
	printf("结构体大小%d\n", sizeof(stu));

	system("pause");
	return EXIT_SUCCESS;
}

2、内存结构模型图:
注意:所有数据类型的大小在内存中存储的资质一定是他的类型的倍数
在这里插入图片描述

①写结构体位置根据数据类型从大到小的方式书写;
在这里插入图片描述
②有利于节省空间,不利于输出格式的阅读;利于输出格式的阅读,不利于节省空间;需要根据当时权重进行排列;
在这里插入图片描述
结构体数组
1、结构体数组格式
在这里插入图片描述
2、学生成绩案例

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct stu1
{
	//成员列表
	//char name[21];
	char * name;
	float scores[3];
};
int main05()
{
	struct stu1 s[3];
	//struct stu1 *s = malloc(sizeof(struct stu1) * 3);
	for (int i = 0; i < 3; i++)
	{
		//开辟堆空间
		s[i].name = (char *)malloc(sizeof(char) * 21);
		printf("请您输入学生 姓名   成绩 :\n");
		scanf("%s%f%f%f", s[i].name, &s[i].scores[0], &s[i].scores[1], &s[i].scores[2]);
	}
	//冒泡排序
	for (int i = 0; i < 3 - 1; i++)
	{
		for (int j = 0; j < 3 - i - 1; j++)
		{

			int sum1 = s[j].scores[0] + s[j].scores[1] + s[j].scores[2];
			int sum2 = s[j + 1].scores[0] + s[j + 1].scores[1] + s[j + 1].scores[2];
			if (sum1 > sum2)
			{
				//结构体交换   交换所有成员列表中的数据
				交换姓名
				//char temp[21] = { 0 };
				//strcpy(temp, s[j].name);
				//strcpy(s[j].name, s[j + 1].name);
				//strcpy(s[j + 1].name, temp);

				交换成绩

				//for (int k = 0; k < 3; k++)
				//{
				//	float temp=s[j].scores[k];
				//	s[j].scores[k] = s[j + 1].scores[k];
				//	s[j + 1].scores[k] = temp;
				//}

				//结构体变量交换
				struct stu1 temp = s[j];
				s[j] = s[j + 1];
				s[j + 1] = temp;

			}
		}
	}




	for (int i = 0; i < 3; i++)
	{
		printf("姓名:%s\n", s[i].name);
		printf("成绩: %.1f   %.1f   %.1f\n", s[i].scores[0], s[i].scores[1], s[i].scores[2]);
	}


	for (int i = 0; i < 3; i++)
	{
		free(s[i].name);
	}

	system("pause");
	return EXIT_SUCCESS;
}

冒泡排序:
交换方式1
在这里插入图片描述在这里插入图片描述

交换方式2 结构体变量交换;
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct stu
{
	//成员列表
	char name[21];
	unsigned int age;
	char tel[16];
	float scores[3];//scores[0]
	char sex;
};
int main04()
{

	//结构体数组
	struct stu  s[2];
	for (int i = 0; i < 2; i++)
	{
		printf("请您输入 姓名  年龄  电话  成绩  性别:\n");
		scanf("%s%d%s%f%f%f,%c", s[i].name, &s[i].age, s[i].tel, &s[i].scores[0], &s[i].scores[1], &s[i].scores[2], &s[i].sex);
	}


	for (int i = 0; i < 2; i++)
	{
		printf("姓名:%s\n", s[i].name);
		printf("年龄:%d\n", s[i].age);
		printf("电话: %s\n", s[i].tel);
		printf("成绩: %.1f   %.1f   %.1f\n", s[i].scores[0], s[i].scores[1], s[i].scores[2]);
		printf("性别: %s\n", s[i].sex == 'M' ? "男" : "女");
	}


	system("pause");
	return EXIT_SUCCESS;
}

/*
学员姓名:

三门功课成绩  总成绩排序

排序



if()
{
char * temp = s[i].name;


}

*/
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct stu2
{
	//成员列表
	//char name[21];
	char * name;
	float * scores;
};

int main09()
{
	struct stu2 *p = (struct stu2 *)malloc(sizeof(struct stu2) * 3);
	for (int i = 0; i < 3; i++)
	{
		p[i].name = (char *)malloc(sizeof(char) * 21);
		p[i].scores = (float *)malloc(sizeof(float) * 3);
		//(p+i)->name

		printf("请您输入学生 姓名   成绩 :\n");
		scanf("%s%f%f%f", p[i].name, &p[i].scores[0], &p[i].scores[1], &p[i].scores[2]);

	}

	//冒泡排序
	for (int i = 0; i < 3 - 1; i++)
	{
		for (int j = 0; j < 3 - i - 1; j++)
		{
			float sum1 = p[j].scores[0] + p[j].scores[1] + p[j].scores[2];
			float sum2 = p[j + 1].scores[0] + p[j + 1].scores[1] + p[j + 1].scores[2];
			if (sum1 > sum2)
			{
				struct stu2 temp = p[j];
				p[j] = p[j + 1];
				p[j + 1] = temp;
			}
		}
	}


	for (int i = 0; i < 3; i++)
	{

		printf("姓名:%s\n", p[i].name);
		printf("成绩: %.1f   %.1f   %.1f\n", p[i].scores[0], p[i].scores[1], p[i].scores[2]);
	}


	//释放
	for (int i = 0; i < 3; i++)
	{
		free(p[i].name);
		free(p[i].scores);
	}

	free(p);



	system("pause");
	return EXIT_SUCCESS;
}

3、结构体和指针
①结构体成员为指针:
在这里插入图片描述
②结构体指针
在这里插入图片描述

释放
在这里插入图片描述

③堆空间开辟结构体,通过指针来实现:
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct stuinfo
{
	char *name;
	int age;
};

int main06()
{
	struct  stuinfo si;
	si.name = (char *)malloc(sizeof(char)* 21);

	strcpy(si.name, "张三");
	si.age = 18;

	printf("%s   %d\n", si.name, si.age);

	free(si.name);


	system("pause");
	return EXIT_SUCCESS;
}
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct sinfo
{
	char *name;
	int age;
}stu;
int main07()
{
	struct sinfo * s = &stu;
	s->name = (char *)malloc(sizeof(char) * 21);
	strcpy(s->name, "李芮");
	s->age = 50;
	printf("%s   %d\n", s->name, s->age);

	free(s->name);



	system("pause");
	return EXIT_SUCCESS;
}

模型图:
①结构体包含指针对应的空间
在这里插入图片描述
②结构体指针:
在这里插入图片描述
③在堆中开辟结构体:
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct tec
{
	char *name;//4
	int age;//4
}t;

int main08()
{
	struct tec * p = (struct tec *)malloc(sizeof(t) * 3);
	//p[i].name
	//struct tec ** p = (struct tec **)malloc(sizeof(struct tec *) * 3);
	//p[1]->name = 
	p->name = (char *)malloc(sizeof(char) * 21);

	strcpy(p->name, "牛玲");
	p->age = 18;

	printf("%s   %d\n", p->name, p->age);

	if (p->name  != NULL)
	{
		free(p->name);
		p->name = NULL;
	}

	if (p)
	{
		free(p);
		p = NULL;
	}


	printf("%d\n", sizeof(struct tec *));

	system("pause");
	return EXIT_SUCCESS;
}

结构体作为函数参数
1、结构体做为形参,不会改变主函数中实参的值;
在这里插入图片描述
2、结构体指针做为形参
在这里插入图片描述
返回方式
1、结构体作为返回值
在这里插入图片描述

2、结构体指针作为返回值
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct info
{
	char name[21];
	int age;
};

void fun01(struct info s)
{
	strcpy(s.name, "李四");
	s.age = 20;

	printf("%s   %d\n", s.name, s.age);

}
void fun02(struct info *s)
{
	strcpy(s->name, "李四");
	s->age = 20;

}



int main1001()
{
	struct info s = { "张三",18 };

	//fun01(s);
	fun02(&s);

	printf("%s   %d\n", s.name, s.age);

	system("pause");
	return EXIT_SUCCESS;
}
struct info  fun03()
{
	struct info s;
	strcpy(s.name, "李四");
	s.age = 20;

	return s;

}
struct info * fun04()
{
	struct info s;
	strcpy(s.name, "李四");
	s.age = 20;

	return &s;
}

//int fun04()
//{
//	int a = 10;
//	return a;
//}
int main1002()
{
	//struct info s = fun03();
	//printf("%s   %d\n", s.name, s.age);


	//int a = fun04();


	struct info * s = fun04();
	printf("%s   %d\n", s->name, s->age);

	return 0;

}

结构体嵌套结构体
1、定义及赋值
在这里插入图片描述

2、结构体大小

模型图1:
在这里插入图片描述
模型图2
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct stra
{
	int a;  //4   4
	float b;//4   8
	char c;//1   12  9
	char arr[7];   //16
	double h;//24
}abc;

struct  strb
{
	struct stra abc;//12  16
	short f;  //2
	char * e;  //4
	short g;
	//double d; //8
};


/*
	技能cd:
	skill01 10
	skill02 3
	skill03 7

*/
/*

	名称
	等级
	攻击
	技能:


*/
int main12()
{
	struct strb  strbb;
	//strbb.d = 10.0f;
	//strbb.abc.a = 100;


	//printf("%d\n", strbb.abc.a);

	printf("%d\n", sizeof(strbb));


	system("pause");
	return EXIT_SUCCESS;
}

共用体

联合union是一个能在同一个存储空间存储不同类型数据的类型;
格式:union 共用体名称 成员列表 共用体变量名
在这里插入图片描述
注意:共用体所占的内存长度等于其最长成员的长度;
在共用体中最后一次赋值,它的值为准确的。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

//共用体   union 共用体名称  成员列表  共用体变量名
union vars
{
	double a;
	float b;
	int c;
	short d;
	char f;
	//char arr[17];//17
}var;
int main13()
{
	printf("%d\n", sizeof(var));
	var.a = 100;
	var.b = 3.14;
	var.c = 66;
	printf("%f\n", var.a);
	printf("%f\n", var.b);
	printf("%d\n", var.c);

	system("pause");
	return EXIT_SUCCESS;
}

枚举

enum 将变量的值一一列举出来,变量的值只限于列举出来的值的范围内。
在这里插入图片描述
应用方向:流程化操作
枚举与switch联合使用

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

enum colors
{
	red=10,bule,yellow=20,black,white,green
}clo;
/*
	插卡
	输入密码
	锁定
	取款
	查询
	退卡
	锁定解除

*/
/*
10
	移动
	攻击
	技能
	死亡
20
	亮牌子
	跳舞


*/
int main14()
{
	clo = 0;

	int val;
	scanf("%d", &val);
	switch (val)
	{
	case red:
		break;
	case bule:
		break;
	case yellow:
		break;
	case black:
		break;
	case white:
		break;
	case green:
		break;
	default:
		break;
	}
	//switch (val)
	//{
	//case red:
	//	printf("请输入您的密码");
	//	clo = 1;
	//	printf("红色\n");
	//	break;
	//case bule:
	//	printf("");
	//	clo = 2;
	//	clo = 3;
	//	clo = 4;

	//	printf("蓝色\n");

	//	break;
	//case yellow:
	//	printf("黄色\n");

	//	break;
	//case black:
	//	break;
	//case white:
	//	break;
	//case green:
	//	break;
	//default:
	//	break;
	//}

	system("pause");
	return EXIT_SUCCESS;
}

typedef

作用:为一种数据类型(基本类型或自定义数据类型)定义一个新名字,不能创建新类型
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include "studentsInfoList.h"
//
typedef unsigned long long ull;
//
//struct studentsInfoList
//{
//	char name[20];
//	char sex;
//};
//typedef struct studentsInfoList sinfo;

int main115()
{
	sinfo s1;





	ull a = 10;

	printf("%d\n", a);

	system("pause");
	return EXIT_SUCCESS;
}

结构体在.h头文件中定义,在当前它文件中引用其头文件可直接使用
在这里插入图片描述
在文件中使用,引用函数体所在文件的头文件
在这里插入图片描述

练习:打字游戏

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <conio.h>
#include <time.h>


void tips()
{
	printf("==================打字游戏================\n");
	printf("================按任意键继续==============\n");
	printf("===============按Esc 退出游戏=============\n");
	char ch = _getch();
	if (ch == 27)
	{
		exit(0);
	}
}
void rand_ch(char * arr)
{
	srand((unsigned int)time(NULL));
	for (int i = 0; i < 50; i++)
	{
		arr[i] = rand() % 26 + 'a';
	}

}
void print_ch(char * arr)
{

	//变量  计时器  开始 结束   计数器  val
	unsigned int start_time;
	unsigned int end_time;
	int val = 0;
	for (int i = 0; i < 50; i++)
	{
		char ch = _getch();
		if (i == 0)
		{
			start_time = time(NULL);
		}
		if (ch == arr[i])
		{
			printf("%c", ch);
			val++;
		}
		else
		{
			printf("_");
		}
	}
	end_time = time(NULL);


	printf("\n用时:%d(秒)\n", end_time - start_time);
	printf("正确率:%.1f%%\n", val*1.0 / 50 * 100);
	if (val*1.0 / 50 * 100 > 80.0)
	{
		printf("打字小能手!\n");
	}

}
int main()
{
	//字库
	char arr[51];
	memset(arr, 0, 51);
	while (1)
	{
		//1、提示
		tips();
		//2、随机字符
		rand_ch(arr);
		printf("%s\n", arr);
		//3、输入字符
		print_ch(arr);
	}
	return EXIT_SUCCESS;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值