【看课必备】MOOC C语言进阶——翁恺 结构类型笔记
目录
MOOC原视频地址:C语言程序设计进阶_浙江大学_中国大学MOOC(慕课)
结构(structure)
代码引入:明天是哪一天?
首先,我们拿一个程序来慢慢理解。
typedef struct date {
int years;
int month;
int day;
} DATE;
DATE today, tomorrow;
//下一天是哪天?
#include <stdio.h>
#include <stdbool.h>
int number0fDays(struct date *p);
bool isLeap(struct date *p1);
int main() {
printf("请输入今天的日期:(years mm dd)");
scanf_s("%d %d %d", &today.years, &today.month, &today.day);
if (today.day != number0fDays(&today)) { //今天不是月末
tomorrow.day = today.day + 1;
tomorrow.month = today.month;
tomorrow.years = today.years;
}
else if (today.month == 12) { //今天是月末,还是12月。
tomorrow.day = 1;
tomorrow.month = 1;
tomorrow.years = today.years + 1;
}
else { //今天是月末。
tomorrow.day = 1;
tomorrow.month = today.month + 1;
tomorrow.years = today.years;
}
printf("明天是:%d-%d-%d", tomorrow.years, tomorrow.month, tomorrow.day);
return 0;
}
int number0fDays(struct date *p) {
int days;
const int daysPerMonth[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
if (p->month == 2 && isLeap(p)) {
days = 29;
}
else days = daysPerMonth[p->month - 1];
return days;
}
bool isLeap(struct date *p1) {
bool leap = false;
if ((p1->years % 4 == 0 && p1->years % 100 != 0) || p1->years % 400 == 0) {
leap == true;
}
return leap;
}
是不是看的有一点懵?别慌,我们一点一点来看。
代码解析
1.首先来看如何写出结构
struct date { //声明结构类型
int day; //结构成员1
int month; //结构成员2
int years; //结构成员3
}; //因为是语句,最后加;结尾
struct date today, tomorrow; //定义结构变量
细心的小伙伴会发现,结构类型通常用在函数外,这样对所有函数都起作用。
结构的成员也与数组的单元类似,但是数组的单元只能有统一的单元类型,而结构可以有多种类型。
2.结构初始化与访问结构成员
struct date today={2021,12,12}; //结构初始化
struct date today={.year=2021,.month=12,.day=12}; //另一种结构初始化的方式
tomorrow.day = today.day + 1; //.+名字可以访问结构中的成员
3.几种结构变量的运算
today=(struct date){2021,12,5};
today=tomorrow; //结构中所有的值都传过去了。
代码拓展延伸
4.结构指针
struct date *p=&today;
p->month=12; //p指向了结构变量today里的成员。
由于结构的名字并不是结构的地址,所以必须用&。所以当结构变量传入函数时,其实是结构变量的值传给了函数,(因为C语言在函数调用的时候是传值的),程序在函数内又复制了一遍结构,进行操作。最后返回的并不是原本的结构变量的值,或者说原本的结构变量的值没有改变。(这就说明了结构与数组的很大不同)。
那么,有什么解决方案吗?你可能会想到,可以创建一个临时的结构变量,最后返回临时的结构变量的值。呃......这可能不是最好的方法。更好的方法是传入结构指针作为参数,最后返回指针。
5.结构数组
struct date today[3] = { {2021,10,12},{2021,12,12},{2021,11,13} };
today[i].month //取出结构变量today,第i个数组的成员month
6.结构里的结构
#include <stdio.h>
int main() {
struct point {
int x;
int y;
};
struct rectangle {
struct point pt1;
struct point pt2;
};
struct rectangle r;
struct rectangle* p;
p = &r; //记得给指针赋值。
r.pt1.x = 1; //.的左边必须是一个结构。
r.pt2.y = 2;
p->pt2.x = 3;
p->pt1.y = 4;
printf("%d %d %d %d", r.pt1.x,r.pt2.y,p->pt2.x,p->pt1.y);
}
这里就不作过多解释了,其实就是嵌套的结构。
枚举(enumeration)
enum color {red yellow green Number};//red=0,yellow=1,green=2,Number=3.
color称为枚举类型名称,该类型只能是int,分别从0到n。(也可以指定值)
枚举的意义与主要作用:比用const int更为方便,并且可以自动计数。例如上段代码 Number 就是数据的数量。主要作用就是定义符号量。
类型定义(typedef)
typedef int LENTH; //LENTH成为了int的别名。
LENTH a, b, len;
typedef struct Adate { //DATE就是struct这个结构。
int x;
int y;
}DATE;
DATE d = { 1,2 };
其实就是给变量类型换个名字,方便阅读者理解。
联合(union)
union AnElt {
int i;
char c[4];
}elt1,elt2;
union常用于得到一个int double ......内部的各个字节。(以16进制的形式得到)
union的用法类似于struct,但是 i与c使用的是同一空间。讲到文件时会拓展。
如果这篇文章对你有帮助的话,请给作者一个点赞或者关注一下,谢谢大家了!
(作者也是一边学习一边分享,如有错误欢迎指出!持续更新中......)