课堂笔记:
// 结构体声明
//结构体是一种自定义的数据类型//用struct关键字声明一个结构体
//struct 结构体名
//{
//
// 类型说明符 成员名;
// ... ...
//
// 类型说明符 成员名;
//};
struct point {
//结构体成员;
int x;
int y;
};
struct size {
int width;
int height;
};
// 定义一个结构体的范例
struct soldier {
char name[40];
// 军衔
char rank [20];
char bloodType[3];
};
// 把 struct soldier类型重新定义成Soldier.
//第一种 (建议使用第一种)
typedef struct soldier Soldier;
第二种
// typedef struct soldier {
// char name[40];
// // 军衔
// char rank [20];
// char bloodType[3];
//}Soldier;
//函数1 打印一个结构体变量
//参数如何写 类型 形参
//从规范上讲不能省略函数声明.
void printStruct(Soldier s );
void printStruct(Soldier s) {
//函数1 打印一个结构体变量
//参数如何写 类型 形参
//从规范上讲不能省略函数声明.
//函数内可以直接访问形参的成员
printf("%s %s %s",s.name,s.rank,s.bloodType);
}
//打印结构体数组的函数
void printArray(Soldier array[],int count);
void printArray(Soldier array[],int count)
{
for (int i = 0; i < count; i++) {
printStruct (array[i]);
}
}
int main(int argc, const char * argv[]) {
// // 结构体是⼀一种自定义的数据类型
//
// //定义一个结构体变量
// //类型 变量名 初始值
// //需要注意struct+结构体的名字是变量类型.
// // 初始值的顺序与声明结构体的成员顺序一致
// struct point p1 = {3, 5};
// struct size s1 = {6, 8};
// //结构体如何访问成员
// // 引入一个新的操作符 .
// //先找到结构体变量p1,在通过.操作符访问y的成员
// p1.x = 6;
// printf("%d\n",p1.x);
struct soldier s1 = {"天下刘","小卒","AB"};
struct soldier s2 = {"关羽","上将","o"};
struct soldier s3 = {"张苞","上校","B"};
struct soldier s4 = {"弹头", "火头兵","A"};
//结构体变量可以直接赋值.
// Soldier s5 =s4;
//结构体数组内放的都是结构体变量
struct soldier array[4] ={s1,s2,s3,s4};
//先找到结构体变量 array[3]
// 通过结构体变量找到血型的成员 array[3].name
//array[3].name是什么?---->name字符串的首地址
printf("%s\n",array[3].name);
//修改name这个字符串---->洪志成.
//**** array[3].name = "洪志成";错误的,字符串的修改需要使用字符串函数.
strcpy(array[3].name, "洪志成");
//类型重定义
typedef int Integer;
// 相当于给int 起了个别名,原来的类型名还可用.
// 为现有类型创建⼀一个类型别名
// 语法: typedef 原类型名 新类型名
//
// 例如:
// 
// typedef int Integer;
// Integer a = 10; //等同于 int a = 10;
****************************************
*********main.m
//创建一个MYRect的结构体变量
MYRect rect = { {0,0},{320,480}};
// 结构体成员的访问
rect.size.width = 20;
// rect.size相当于MYSize类型的结构体变量
// 如果想访问宽度.则需要再用一次.语法来访问
// printf("%lu\n",sizeof( struct student));
//
// 结构体嵌套 结构体的成员依然可以是结构体。例如:!
// 
// typedef struct date{
// int year;
//
// int month;
//
// int day; } MyDate;
// struct student{
//
// char name[20];
//
// MyDate birthday;//访问:stu1.birthday.year;
// };
// 对上述5名学⽣生数组,按成绩从⾼高到低排序, 并输出
//
stu stus[5] = {
{01, "zhangfei" , 89.4,'m'},
{01, "zhaopyun" ,98.8,'m' },
{02, "xiongba" , 63.7,'m'},
{04, "niefeng" , 45.9,'m'},
{03, "bujingyun" , 67.3,'m'}
};
//调用排序
bubblesort(stus, 5);
//打印
printArray(stus, 5);
printf("\n");
PLUS**********MYFUNCTION.m
结构体排序
//void bubblesort (stu array[],int count)
//{//按照成绩从高到底
// for (int i = 0; i < count -1; i++) {
// for (int j = 0; j < count - i - 1; j++) {
// if (array[j].score < array[j + 1].score) {
// //交换位置 需要交换整个结构体
// stu temp = array[j];
// array[j] = array[j + 1];
// array[j + 1] = temp;
// }
// }
// }
//}
//void printArray(stu array[],int count)
//{ for (int i = 0; i < count; i++)
// printf("%d %s %.2f %c\n",array[i].num, array[i].name, array[i].score, array[i].sex);
//}
PLUS**********MYFUNCTION.h
//product + clean 清除
//重新编译
//结构体内存所占空间
struct student{
int num;//4个字节,
char name[30];//12字节
float score;//4个字节
char sex;//一个字节
};
typedef struct student stu;
//结构体数组的冒泡排序函数
void bubblesort (stu array[],int count);
// 打印结构体数组的函数
void printArray(stu array[],int count);
// 创建一个描述点的结构体
struct point{
int x;
int y;
};
typedef struct point MYpoint;
// 创建一个描述尺寸的结构体
struct size{
int width;
int height;
};
typedef struct size MYSize;
//创建一个描述矩形区域的结构体
struct rect {
// 包含点的结构体
MYpoint origin;
//包含尺寸的结构体
MYSize size;
};
typedef struct rect MYRect;
**************************************************************
结构体可以直接赋值
例如:stu1 = stu2;
注意:数组不可以直接赋值
**小技巧:可以通过把数组放在结构体内实现数组的直接赋值
*****************************
结构体内存占用:
以最大成员变量类型所占空间为分配单位, 按结构体成员声明顺序自上而下分配。
注:分配空间不足以存储成员变量时,分配新的空间单位
课后题:
1. (**)定义一个结构体变量(包括年、月、日),计算该日在本年中为第
几天?(注意考虑闰年问题),要求写一个函数 days,实现上面的计算。由主函数将年月日传递给 days 函数,计算后将日子传递回主函数输出。
2. (***)某班有 5 个学生,三门课。分别编写 3 个函数实现以下要求:(1) 求各门课的平均分;
(2) 找出有两门以上不及格的学生,并输出其学号和不及格课程的成绩;(3) 找出三门课平均成绩在 85-90 分的学生,并输出其学号和姓名
3. (***)模拟n个人参加选举的过程,并输出选举结果:假设候选人有四
人,分别用 A、B、C、D 表示,当选某候选人时直接输入其编号(编号由计算机
随机产生),若输入的不是 A、B、C、D 则视为无效票,选举结束后按得票数从高到低输出候选人编号和所得票数。
4.(***)创建一个 Point 结构体,包含 x,y 两个变量。并写以下函数:
函数 1,判断两个点是否在一条水平线上。
函数 2,判断两个点是否在一条垂直线上。函数 3,判断两个点是否相等。
5.(***)创建一个 Size 结构体,包含 width,height 两个变量。并写以下函数:
函数 1,判断两个 size 是否等宽。
函数 2,判断两个 size 是否在等高。函数 3,判断两个 size 是否相等。
*******************
.m文件中
//第一题
void days(Year year)
{
printf("请输入年月日,以空格隔开:");
scanf("%d %d %d", &year.year, &year.mouth, &year.date);
int sumday = 0;
int mouth[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
if (!(year.mouth % 400) || !((year.mouth%4) && year.mouth%100)) {
mouth[1] = 29; //判断闰年
}
for (int i = 0; i < year.mouth - 1; i++) {
sumday +=mouth[i]; //计算前几个月的天数
}
sumday += year.date; //总天数,即前几个月的天数加上本月天数
printf("%d年%d月%d日是%d年的第%d天", year.year, year.mouth,year.date,year.year,sumday);
}
//第二题
//求平均分
void averageScore(Student stu[], int count)
{
for (int i = 0; i < count; i++) {
stu[i].average = (stu[i].math+stu[i].chinese+stu[i].English)/3;
printf("%s的平均分是:%.2f\n", stu[i].name, stu[i].average);
}
}
//找出两门不及格学生并输出他的学号和不及格科目成绩
void printfFailStudent(Student stu[], int count)
{
for (int i = 0; i < count; i++) {
int flag = 0; //定义变量计数用来计不及格科数
stu[i].math < 60 ? flag++ : flag; //如果成绩小于60,flag自增,即不及格科数加一
stu[i].chinese < 60 ? flag++ : flag;
stu[i].English < 60 ? flag++ : flag;
if (flag >= 2) { //判断满足不及格科数条件的学生并打印出
printf("\n%s有%d门不及格分别是: ", stu[i].name, flag);
if (stu[i].math < 60) {
printf("math = %d ", stu[i].math);
}
if (stu[i].chinese < 60) {
printf("chinese = %d ", stu[i].chinese);
}
if (stu[i].English < 60) {
printf("English = %d ", stu[i].English);
}
}
}
}
//实现找出平均分在[85,90]中的学生并输出其姓名及学号
void printfWellStudent(Student stu[], int count)
{
for (int i = 0; i < 3; i++) {
if (stu[i].average >= 85 && stu[i].average <= 90) {
printf("\n%s的平均分为%.2f,他的学号是:%d", stu[i].name, stu[i].average, stu[i].number);
}
}
}
//第三题
void election(Candidate c[], int count)
{
printf("请输入参选人的个数,以回车结束:");
int n = 0;
scanf("%d", &n);
for (int i = 0; i < n; i++) { //n个人投票,循环n次
printf("候选人为A,B,C,D,请输入您的选择:");
char choice = 0;
getchar();
scanf("%c", &choice);//四个人参选4种情况,switch...case
switch (choice) {
case 'A':
c[0].poll++;
break;
case 'B':
c[1].poll++;
break;
case 'C':
c[2].poll++;
break;
case 'D':
c[3].poll++;
break;
default:
break;
}
}
for (int i = 0; i < count - 1; i++) { //从高到底排序,冒泡排序
for (int j = 0; j < count - i -1; j++) {
if (c[j].poll < c[j+1].poll) {
Candidate temp = c[j];
c[j] = c[j+1];
c[j+1] = temp;
}
}
}
for (int i = 0; i < count; i++) {
printf("%c的得票为: %d\n", c[i].name, c[i].poll);
}
}
//第四题
//实现判断是否在同一水平线上功能的函数
void isInLevel(myPoint point[])
{
if (point[0].y == point[1].y) {//在同一水平线上条件是 纵坐标相等 即y相等
printf("点(%d, %d)和点(%d, %d)在同一水平线\n", point[0].x, point[0].y, point[1].x, point[1].y);
}
else
printf("点(%d, %d)和点(%d, %d)不在同一水平线\n", point[0].x, point[0].y, point[1].x, point[1].y);
}
//实现判断是否在同一垂直线上功能的函数
void isVertically(myPoint point[])
{
if (point[0].x == point[1].x) {//在同一垂直线上条件是 横坐标相等 即x相等
printf("点(%d, %d)和点(%d, %d)在同一垂直线\n", point[0].x, point[0].y, point[1].x, point[1].y);
}
else
printf("点(%d, %d)和点(%d, %d)不在同一垂直线\n", point[0].x, point[0].y, point[1].x, point[1].y);
}
//实现判断两点是否相等功能的函数
void isEqual(myPoint point[])
{ //两点相等条件是 横,纵坐标都相等 即 x相等且y相等
if (point[0].x == point[1].x && point[0].y == point[1].y) {
printf("点(%d, %d)和点(%d, %d)相等\n", point[0].x, point[0].y, point[1].x, point[1].y);
}
else
printf("点(%d, %d)和点(%d, %d)不相等\n", point[0].x, point[0].y, point[1].x, point[1].y);
}
//第五题
//实现判断宽度是否相等功能的函数
void isWidthEqual(mySize size[])
{
if (size[0].width == size[1].width) {
printf("Size(%d, %d)和Size(%d, %d)的宽度相等\n", size[0].width, size[0].height, size[1].width, size[1].height);
}
else
printf("Size(%d, %d)和Size(%d, %d)的宽度不相等\n", size[0].width, size[0].height, size[1].width, size[1].height);
}
//实现判断高度是否相等功能的函数
void isHeightEqual(mySize size[])
{
if (size[0].height == size[1].height) {
printf("Size(%d, %d)和Size(%d, %d)的高度相等\n", size[0].width, size[0].height, size[1].width, size[1].height);
}
else
printf("Size(%d, %d)和Size(%d, %d)的高度不相等\n", size[0].width, size[0].height, size[1].width, size[1].height);
}
//实现判断大小是否相等功能的函数
void isSizeEqual(mySize size[])
{
if (size[0].width * size[0].height == size[1].width * size[1].height) {
printf("Size(%d, %d)和Size(%d, %d)相等\n", size[0].width, size[0].height, size[1].width, size[1].height);
}
else
printf("Size(%d, %d)和Size(%d, %d)不相等\n", size[0].width, size[0].height, size[1].width, size[1].height);
}
//方法一:
void isRectIntersectant(myRect rect[])
{
int minx = rect[0].point.x < rect[1].point.x ? rect[0].point.x : rect[1].point.x;
int maxx = rect[0].point.x > rect[1].point.x ? rect[0].point.x : rect[1].point.x;
int miny = rect[0].point.y < rect[1].point.y ? rect[0].point.y : rect[1].point.y;
int maxy = rect[0].point.y > rect[1].point.y ? rect[0].point.y : rect[1].point.y;
int minw = rect[0].point.x < rect[1].point.x ? rect[0].size.width : rect[1].size.width;
int minh = rect[0].point.y < rect[1].point.y ? rect[0].size.height : rect[1].size.height;
if (minx+minw>=maxx && miny+minh>=maxy) {
printf("相交\n");
}
else
printf("不相交\n");
}
//方法二:
//void isRectIntersectant(myRect rect[])
//{
// int x1 = rect[0].point.x;
// int y1 = rect[0].point.y;
// int w1 = rect[0].size.width;
// int h1 = rect[0].size.height;
// int x2 = rect[1].point.x;
// int y2 = rect[1].point.y;
// int w2 = rect[1].size.width;
// int h2 = rect[1].size.height;
// if (x1 <= x2)
// {
// if (y1 <= y2) {
// if (x1+w1>=x2 && y1+h1>=y2) {
// printf("相交\n");
// }else
// printf("不相交\n");
// }
// else{
// if (x1+w1>=x2 && y2+h2>=y1) {
// printf("相交\n");
// }else
// printf("不相交\n");
// }
// }
// else
// {
// if (y1 <= y2) {
// if (x2+w2>=x1 && y1+h1>=y2) {
// printf("相交\n");
// }else
// printf("不相交\n");
// }
// else{
// if (x2+w2<=x1 && y2+h2>=y1) {
// printf("相交\n");
// }else
// printf("不相交\n");
// }
//
// }
//}
void isRectContainPoint(myRect rect[])
{
myRect minx = rect[0].point.x < rect[1].point.x ? rect[0] : rect[1];
myRect maxx = rect[0].point.x > rect[1].point.x ? rect[0] : rect[1];
if (minx.point.y < maxx.point.y && minx.point.x+minx.size.width > maxx.point.x && minx.point.y+minx.size.height > maxx.point.y) {
printf("包含\n");
}
else
printf("不包含\n");
}
void isRectContainRect(myRect rect[])
{
myRect minx = rect[0].point.x < rect[1].point.x ? rect[0] : rect[1];
myRect maxx = rect[0].point.x > rect[1].point.x ? rect[0] : rect[1];
if (minx.point.y <= maxx.point.y && minx.point.x+minx.size.width >= maxx.point.x+maxx.size.width && minx.point.y+minx.size.height >= maxx.point.y+maxx.size.height) {
printf("在\n");
}
else
printf("不在\n");
}
*******************************************
.h文件中
//定义结构体变量包括:年 月 日
typedef struct year
{
int year;
int mouth;
int date;
}Year;
//定义结构体变量包括:名字,学号,数学成绩,语文成绩,英语成绩,平均成绩
typedef struct student{
char name[30];
int number;
int math;
int chinese;
int English;
float average;
}Student;
//定义结构体变量包括:姓名,票数
typedef struct candidate
{
char name;
int poll;
}Candidate;
//定义结构体变量包括:横坐标,纵坐标
typedef struct point
{
int x;
int y;
}myPoint;
//定义结构体变量包括:宽度,高度
typedef struct size
{
int width;
int height;
}mySize;
typedef struct rect
{
myPoint point;
mySize size;
}myRect;
//1题
void days(Year year);
//2题
void averageScore(Student s[], int);
void printfFailStudent(Student s[], int);
void printfWellStudent(Student s[], int);
//3题
void election(Candidate c[], int);
//4题
void isInLevel(myPoint point[]);
void isVertically(myPoint point[]);
void isEqual(myPoint point[]);
//5题
void isWidthEqual(mySize size[]);
void isHeightEqual(mySize size[]);
void isSizeEqual(mySize size[]);
//6题
void isRectIntersectant(myRect rect[]);
void isRectContainPoint(myRect rect[]);
void isRectContainRect(myRect rect[]);
****************************
main.m文件中;
/*第一题(**)定义一个结构体变量(包括年、月、日),计算该日在本年中为第
几天?(注意考虑闰年问题),要求写一个函数 days,实现上面的计算。 由主函数将年月日传递给 days 函数,
计算后将日子传递回主函数输出。*/
// Year myYear = {0};
// days(myYear); //直接调用函数
/*第二题(***)某班有 5 个学生,三门课。分别编写 3 个函数实现以下要求:
(1) 求各门课的平均分;
(2) 找出有两门以上不及格的学生,并输出其学号和不及格课程的成绩;
(3) 找出三门课平均成绩在 85-90 分的学生,并输出其学号和姓名*/
// Student stu[] = { //定义包含5个学生信息的结构体
// {"zhangsan", 111, 50, 56, 80, 0},
// {"lisi", 112, 89, 88, 84, 0},
// {"wangwu", 113, 56,43, 99, 0},
// {"zhaoliu", 114,77,88,99,0},
// {"haoyun", 115,66,88,99,0}
// };
// int count = sizeof(stu)/sizeof(stu[0]);
// averageScore(stu, count);
// printfFailStudent(stu, count); //直接调用函数
// printfWellStudent(stu, count);
/*第三题(***)模拟n个人参加选举的过程,并输出选举结果:假设候选人有四
人,分别用 A、B、C、D 表示,当选某候选人时直接输入其编号(编号由计算机
随机产生),若输入的不是 A、B、C、D 则视为无效票,选举结束后按得票数从
高到低输出候选人编号和所得票数*/
// Candidate candidate[] = {{'A',0},{'B',0},{'C',0},{'D',0}};
// election(candidate, 4);
/*第四题(***)创建一个 Point 结构体,包含 x,y 两个变量。 并写以下函数:
函数 1,判断两个点是否在一条水平线上。
函数 2,判断两个点是否在一条垂直线上。
函数 3,判断两个点是否相等。*/
// myPoint point[2] = {{10, 8}, {9, 8}};
// isInLevel(point);
// isVertically(point);
// isEqual(point);
/*第五题(***)创建一个 Size 结构体,包含 width,height 两个变量。 并写以下函数:
函数 1,判断两个 size 是否等宽。
函数 2,判断两个 size 是否在等高。
函数 3,判断两个 size 是否相等。*/
// mySize size[2] = {{8,8},{6,7}};
// isWidthEqual(size);
// isHeightEqual(size);
// isSizeEqual(size);
/*第六题(***)创建一个 Rect 结构体,包含 origin,size 两个变量。其中 origin 是
Point 类型的,size 是 Size 类型的。 并写以下函数:
函数 1,判断两个 Rect 是否相交。
函数 2,判断两个 Rect 是否包含某个 Point。
函数 3,判断一个 Rect 是否在另外一个 Rect 中。*/
myRect rect[2] = {{{3,3}, {8,12}}, {{8,8}, {4,2}}};
isRectIntersectant(rect);
isRectContainPoint(rect);
isRectContainRect(rect);
return 0;
}