结构体定义及赋值
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;
}