枚举、struct结构、typedef和union
一、枚举
1、基本概念
2、枚举的简单应用
二、结构
1、struct结构
2、struct与函数
简单应用(下一天)
3、结构里的结构
简单应用(下一秒)
三、typedef和union
1、typedef
2、联合(union)
一、枚举
1、基本概念
枚举是一种用户定义的数据类型,它用关键字enum以如下语法来声明
enum 枚举类型名字{名字0,…,名字n};
枚举类型的名字通常并不真的使用,要用的是在大括号里的名字,因为它们就是常量符号,他们的类型是int,
值则依次从0到n。如:
enum peoples{ Leo,Tim,Tom,Ann};
创建了三个常量,Leo的值是0,Tim是1,而Ann是2.
需要一些可以排列起来的常量值时,定义枚举的意义就是给这些常量值名字。
枚举量可以做值
枚举类型可以跟上enum作为类型
但是实际是以整数来做内部计算和外部输入输出的
声明枚举量的时候可以指定值
2、枚举的简单应用
#include <stdio.h>
enum COLOR {RED, YELLOW, GREEN, NumCOLORS}; //枚举三种颜色
int main(int argc, char const *argv[])
{
int color = -1; //定义判断值
char *colorName = NULL;
printf("请输入你喜欢的颜色的代码:");
scanf("%d", &color); //读入颜色代码
switch( color ) {
case RED: colorName = "red";
break;
case YELLOW: colorName = "yellow";
break;
case GREEN: colorName = "green";
break;
default: colorName = "unknown";
break;
} //根据输入的不同输出
printf("你喜欢的颜色是%s\n", colorName); //输出最喜欢的颜色
return 0;
}
二、结构
1、struct结构
声明结构类型
和本地变量一样,在函数内部说明的结构类型只能在函数内部使用。
所以通常在函数内外说明结构类型,这样就可以被多个函数所使用了。
struct point{
int x;
int y;
};
srtuct point p1, p2;
p1和p2都是point里面x和y的值
struct{
int x;
int y;
} p1, p2;
p1和p2都是一种无名结构,里面有x和y
struct point{
int x;
int y;
}p1, p2;
p1和p2都是point里面有x和y的值t。
对于第一和第三种形式都声明了结构point但是第二种结构没有声明point,只定义的两种两个变量。
结构成员
结构和数组相似
数组用[]运算符和下标访问其成员
a[0] = 10;
结构用.运算符和名字访问其成员
today.day
student.firstName
p1.x
p1,y
结构运算
要访问整个结构,直接用变量的名字
对于整个结构可以做赋值,取地址,也可以传递给函数参数
p1 = (struct point){5, 10}; //相当于p1.x = 5; p1.y = 10;
p1 = p2; //相当于p1.x = p2.x; p1.y = p2.y;
结构指针
和数组不同,结构类型的名字必须是结构变量的地址,必须用&运算符
struct date *pDate = &today;
读入日期
#include <stdio.h>
struct date { //定义结构
int month;
int day;
int year;
};
int main(int argc, char const *argv[])
{
struct date today;
today.month = 11;
today.day = 4;
today.year = 2022;
printf("Today`s date is %i-%i-%i.\n",today.year, today.month, today.day);
return 0;
}
2、struct与函数
结构作为函数参数,也可以作为参数的值传入函数
这时候是在函数内新建一个结构变量,并复制调用者的结构的值
也可以返回一个结构
这与数组不同
指向结构的指针
用->表示指针所指的结构变量中的成员
结构数组
struct date dates[];
struct date dates[] = {
{4, 5, 2005}, {2, 4, 2004} };
简单应用(下一天)
#include <stdio.h>
#include <stdbool.h>
struct date { //定义结构
int month;
int day;
int year;
};
bool isLeap(struct date d);
int numberOfDays(struct date d);
int main(int argc, char const *argv[])
{
struct date today, tomorrow;
printf("Enter today's date (mm dd yyyy):");
scanf("%i %i %i", &today.month, &today.day, &today.year); //读入date
if( today.day != numberOfDays(today) ) { //判断一般情况
tomorrow.day = today.day+1;
tomorrow.month = today.month;
tomorrow.year = today.year;
} else if (today.month == 12 ) { //date为每年最后一天
tomorrow.day = 1;
tomorrow.month = 1;
tomorrow.year = today.year + 1;
} else { //date为每月最后一天(不包括12月)
tomorrow.day = 1;
tomorrow.month = today.month+1;
tomorrow.year = today.year;
}
printf("Tomorrow's date is %i-%i-%i.\n", tomorrow.year, tomorrow.month, tomorrow.day);
return 0;
}
int numberOfDays(struct date d)
{
int days;
//列出每月的天数
const int daysPerMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if ( d.month ==2 && isLeap(d) ) //闰年则为29天
{
days = 29;
}else
{
days = daysPerMonth[d.month-1];
}
return days;
}
bool isLeap(struct date d) //判断平年和闰年
{
bool leap = false;
if( (d.year %4 == 0 && d.year %100 !=0 ) || d.year%400 == 0 )
leap = true;
return leap;
}
3、结构里的结构
嵌套的结构
struct point {
int x;
int y;
};
如果有变量
struct rectangle r;
就可以有
r.pt1.x 、r.pt1.y,
r.pt2.x和r.pt2.y
如果有变量定义
struct rectangle r, *rp;
rp = &r;
那么下面的四种形式是等价的:
r.pt1.x
rp->pt1.x
(r.pt1).x
(rp->pt1).x
但是没有rp->pt1->x (因为pt1不是指针)
简单应用(下一秒)
#include <stdio.h>
struct time{ //定义结构
int hour;
int minutes;
int seconds;
};
struct time timeUpdate(struct time now);
int main(void)
{
struct time testTimes[5] = {
{11, 59, 59}, {12, 0, 0}, {1, 29, 59}, {23, 59, 59} , {19, 12, 27}
}; //读入代表时间的结构数组
int i;
for ( i=0; i<5; ++i ) {
printf("Time is %.2i:%.2i:%.2i\n", testTimes[i].hour, testTimes[i].minutes, testTimes[i].seconds );
testTimes[i] = timeUpdate(testTimes[i]);
printf("...one second later it's %.2i:%.2i:%.2i\n", testTimes[i].hour, testTimes[i].minutes, testTimes[i].seconds);
}
return 0;
}
struct time timeUpdate(struct time now)
{
++now.seconds;
if ( now.seconds == 60 ) {
now.seconds = 0;
++now.minutes;
if ( now.minutes == 60 ) {
now.minutes = 0;
++now.hour;
if ( now.hour == 24 ) {
now.hour = 0;
}
}
} //嵌套if,判断时间的特殊情况
return now;
}
三、typedef和union
1、typedef
自定义数据类型(typedef)
typedef 功能,声明一个已有的数据类型的新名字。例如:
typedef int Length;
Typedef
声明新类型的名字,是某种类型的别名,提高了程序的可读性
typedef long int64_t;
typedef struct Adate {
int month;
int day;
int year;
} Date;
int64_t i = 10000000;
Date d = { 6, 11, 2022};
2、联合(union)
union AnElt {
int i;
char c;
} elt1, elt2;
elt1, elt2;
联合
存储
所有的成员共用一个空间
同一个时间只有一个成员是有效的
union 的大小是最大的成员