Day11.复合类型
一、结构体的定义和赋值
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*
struct 结构体名称
{
结构体成员列表
};
*/
struct students
{
//成员列表
char name[30];
unsigned int age;
char tel[16];
float scores[3];
char sex;
}stu_1 = { "曹儿子",16,"18305939266",98.8,68.6,88.8,'M' };
int main(void)
{
//1、按照结构体顺序赋值
//struct students stu_1 = { "曹儿子",16,"18305939266",98.8,68.6,88.8,'M' };
//2、不按顺序赋值
//struct students stu_1 = { .sex = 'M',.name = "段儿子",.age = 15,.scores[1] = 98,.scores[0] = 65.5,.scores[2] = 86.6,.tel = "10068686666" };;
//3、第三种赋值方式
//struct students stu_1;
//stu_1.name = "邓儿子";//字符串类型应该用strcpy 函数来赋值
//strcpy(stu_1.name, "邓儿子");
//stu_1.age = 13;
//strcpy(stu_1.tel, "13666665555");
//stu_1.scores[0] = 96.5;
//stu_1.scores[1] = 63.5;
//stu_1.scores[2] = 83.5;
//stu_1.sex = 'M';
//第四种赋值方式:定义的同时直接复制
printf("stu_1的姓名:%s\n", stu_1.name);
printf("stu_1的年龄:%d\n", stu_1.age);
printf("stu_1的电话:%s\n", stu_1.tel);
printf("stu_1的分数:%.1f %.1f %.1f\n", stu_1.scores[0], stu_1.scores[1], stu_1.scores[2]);
printf("stu_1的性别:%s\n", stu_1.sex=='M'?"男":"女");
return 0;
}
二、结构体大小和内存结构
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct stus
{
//结构体会根据数据类型进行内存对齐(可优化)
//不影响阅读的话,顺序一般是大的数据类型放在上面
//char name[30];//30
//unsigned int age;//4
//char tel[16];//16
//float scores[3];//12
//char sex;//1
unsigned int age;//4
float scores[3];//12
char name[30];//30
char tel[16];//16
char sex;//1
}stu;
int main(void)
{
printf("结构体大小%d\n", sizeof(stu));//68-->64
return 0;
}
三、结构体数组
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct stu
{
char name[30];
unsigned int age;
char tel[16];
float scores[3];
char sex;
};
int main(void)
{
//结构体数组
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[%d]的姓名:%s\n", i, s[i].name);
printf("s[%d]的年龄:%d\n", i, s[i].age);
printf("s[%d]的电话:%s\n", i, s[i].tel);
printf("s[%d]的分数:%.1f %.1f %.1f\n", i, s[i].scores[0], s[i].scores[1], s[i].scores[2]);
printf("s[%d]的性别:%s\n", i, s[i].sex == 'M' ? "男" : "女");
}
return 0;
}
四、案例:学生成绩
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct stu_scores
{
char name[20];
float scores[3];
};
int main(void)
{
struct stu_scores s[3];
for (int i = 0; i < 3; i++)
{
printf("请宁输入第%d名学生的姓名和三门成绩:\n",i+1);
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 - 1 - i; 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)
{
struct stu_scores temp = s[j];
s[j] = s[j + 1];
s[j + 1] = temp;
}
}
}
for (int i = 0; i < 3; i++)
{
printf("%s 的成绩成绩:%.1f %.1f %.1f \n",s[i].name, s[i].scores[0], s[i].scores[1], s[i].scores[2]);
}
return 0;
}
五、结构体和指针
1、结构体成员为指针
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct stuinfo
{
char* name;
unsigned int age;
};
int main(void)
{
struct stuinfo s;
s.name = (char*)malloc(sizeof(char) * 21);
strcpy(s.name, "张三");
s.age = 18;
printf("%s %d\n", s.name, s.age);
if (s.name)
free(s.name);
return 0;
}
2、结构体指针
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct stu_info
{
char* name;
unsigned int age;
}stu;
int main(void)
{
struct stu_info* s = &stu;
s->name = (char*)malloc(sizeof(char) * 21);
strcpy(s->name, "张三");
s->age = 18;
printf("%s %d\n", s->name, s->age);
if (s->name)
free(s->name);
return 0;
}
3、堆空间开辟结构体
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct tec
{
char* name;
unsigned int age;
}t;
int main(void)
{
struct tec* p=(struct tec*)malloc(sizeof(t) * 5);
p->name = (char*)malloc(sizeof(char) * 21);
strcpy(p->name, "张三");
p->age = 18;
printf("%s %d\n", p->name, p->age);
if (p->name)
free(p->name);
if (p)
free(p);
return 0;
}
4、案例:学生成绩(重点*)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct stu_scores_1
{
char* name;
float* scores;
};
int main(void)
{
struct stu_scores_1* s=(struct stu_scores_1*)malloc(sizeof(struct stu_scores_1)*3);
for (int i = 0; i < 3; i++)
{
//开辟堆空间
(s+i)->name = (char*)malloc(sizeof(char) * 21);
(s+i)->scores = (float*)malloc(sizeof(float) * 3);
printf("请宁输入第%d名学生的姓名和三门成绩:\n", i + 1);
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 - 1 - i; j++)
{
float sum1 = (s+j)->scores[0] + (s+j)->scores[1] + (s+j)->scores[2];
float sum2 = s[j + 1].scores[0] + s[j + 1].scores[1] + s[j + 1].scores[2];
if (sum1 > sum2)
{
struct stu_scores_1 temp = s[j];
s[j] = s[j + 1];
s[j + 1] = temp;
}
}
}
for (int i = 0; i < 3; i++)
{
printf("%s 的成绩成绩:%.1f %.1f %.1f \n", (s+i)->name, (s+i)->scores[0], (s+i)->scores[1], (s+i)->scores[2]);
}
for (int i = 0; i < 3; i++)
{
free((s+i)->name);
free((s+i)->scores);
}
free(s);
return 0;
}
六、结构体和函数
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct info
{
char name[21];
int age;
};
void fun01(struct info s)
{
strcpy(s.name, "李四");
s.age = 20;
}
void fun02(struct info* s)
{
strcpy(s->name, "李四");
s->age = 20;
}
struct info fun03()
{
struct info s;
strcpy(s.name, "李四");
s.age = 20;
return s;
}
int main0901(void)
{
struct info s = { "张三",18 };
fun01(s);
fun02(&s);
printf("%s %d\n", s.name, s.age);
return 0;
}
int main(void)
{
struct info s = fun03();
printf("%s %d\n", s.name, s.age);
return 0;
}
七、结构体嵌套
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct str_a
{
int a;
float b;
char c;
};
struct str_b
{
double d;
char* e;
short f;
struct str_a abc;
};
int main(void)
{
struct str_b strb;
strb.d = 10.0f;
strb.abc.a = 100;
printf("%d\n", strb.abc.a);
return 0;
}
八、共用体
格式:
union 共用体名称
{
变量类型 变量名;
};
//优点:节省内存
//缺点:公用一个地址,不方便
九、枚举
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
enum colors
{
red,blue,yellow,black,white,green
}clo;
int main(void)
{
int val;
scanf("%d", &val);
switch (val)
{
case red:
printf("红色\n");
break;
case blue:
printf("蓝色\n");
break;
case yellow:
printf("黄色\n");
break;
case black:
printf("黑色\n");
break;
case white:
printf("白色\n");
break;
case green:
printf("绿色\n");
break;
default:
break;
}
return 0;
}
十、typedef应用
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//简化已有的数据类型
typedef unsigned long long ull;
//简化结构体
struct students_info_list
{
char name[20];
char sex;
};
typedef struct students_info_list sinfo;
int main(void)
{
sinfo sinfo_1;
strcpy(sinfo_1.name, "xujie");
sinfo_1.sex = 'M';
ull a = 10;
printf("%d\n", a);
return 0;
}
十一、打字游戏
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#include<conio.h>
void tips()
{
printf("======================打字游戏======================\n");
printf("====================按任意键继续====================\n");
printf("===================按ESC 退出游戏===================\n");
//_getch 接收字符但不显示
char ch = _getch();
//ESC在ASCII表中对应27
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';
}
printf("%s\n", arr);
}
void printf_ch(char* arr)
{
//定义变量: 变量 开始时间 结束时间 正确率
char ch;
unsigned int start_time;
unsigned int end_time;
float val = 0;
for (int i = 0; i < 50; i++)
{
if (i == 0)
{
start_time = time(NULL);
}
ch = _getch();
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 / 50 * 100);
}
int main(void)
{
while (1)
{
char arr[51];
memset(arr, 0, 51);
//提示
tips();
//生成随机字符
rand_ch(arr);
//打字计时并且算出出正确率
printf_ch(arr);
}
return 0;
}