枚举
enum 枚举类型名字{ 名字0 , … , 名字n,num枚举类型名 } ;
- 大括号里的名字,就是常量符号, 它们的类型是int , 值依次从0到n。
- 枚举量可以作为值
- 枚举类型可以跟上enum 作为类型
- 但是实际上是以整数来做内部计算和外部输入输出的
- num枚举类型名可用来枚举计数
- 枚举量:声明枚举量的时候可以指定值
enum COLOR { RED=1, YELLOW, GREEN = 5};
结构运算:对于整个结构, 可以做赋值、取地址, 也可以传递给函数参数
p1= (struct point){5, 10} ;
- 结构指针:和数组不同, 结构变量的名字并不是
结构变量的地址, 必须使用& 运算符struct date *pDate = &today;
- 结构作为函数参数:这时候是在函数内新建一个结构变量, 并复制调用者的结构的值
已知今天的日期,计算明天的日期
#include<stdio.h>
#include<stdbool.h>//bool头文件
struct date{
int day;
int month;
int year;
};
bool isLeap(struct date d);
int numberOfDays(struct date d);
int main()
{
struct date today,tomorrow;
printf("Enter today's date(dd mm yyyy):");
scanf("%d %d %d",&today.day,&today.month,&today.year);
if(today.day!=numberOfDays(today)){
tomorrow.day=today.day+1;
tomorrow.month=today.month;
tomorrow.year=today.year;
}else if(today.month==12){
tomorrow.day=1;
tomorrow.month=1;
tomorrow.year=today.year+1;
}else{
tomorrow.day=1;
tomorrow.month=today.month+1;
tomorrow.year=today.year;
}
printf("%d %d %d",tomorrow.day,tomorrow.month,tomorrow.year);
return 0;
}
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;
}
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)){
days=29;
}else days=daysPerMonth[d.month-1];
return days;
}
函数中调用结构体
在函数中, 创建一个临时的结构变量,然后把这个结构返回给调用者。
- 指向结构的指针:
(*p).month=12;等于p->month=12;
用-> 表示指针所指的结构变量中的成员
例:
#include<stdio.h>
struct point{
int x;
int y;
};
struct point* getStruct(struct point*);
void output(struct point);
void print(const struct point *p);
int main()
{
struct point y={0,0};
getStruct(&y);
output(y);
output(*getStruct(&y));
print(getStruct(&y));
*getStruct(&y)=(struct point){1,2};
return 0;
}
struct point* getStruct(struct point*p){
scanf("%d",&p->x);
scanf("%d",&p->y);
printf("%d %d",p->x,p->y);
return 0;
}
void output(struct point p){
printf("%d %d",p.x,p.y);
}
void print(const struct point *p){
printf("%d %d",p->x,p->y);
}
如果有变量定义.
struct rectangle r,*rp;
rp=&r;
那么下面的四种形式是等价的.
r.pt1.x
rp->pt1.x
(r.pt1).x
(rp->pt1).x
但是没有rp-> pt1- > × ( 因为pt1不是指针)
自定义数据类型(typedef)
- 来声明一个已有的数据类型的新名字。比如.
- typedef int Length;
使得Length 成为int 类型的别名。 - Length a,b, len;
- Length numbers [10];
- typedef int Length;
假设int类型变量占用4个字节,定义数组
int x[10] = {0,2,4};
则x在内存中占据40个字节
转换数额与面额英文
#include<stdio.h>
struct{
int amount;
char *name;
}coins[]={
{1,"penny"},//用逗号隔开
{5,"nickel"},
{10,"dime"},
{25,"quarter" },
{50,"half-dollar" }
};
int main()
{
int k;
scanf("%d",&k);
for(int i=0;i<sizeof(coins)/sizeof(coins[0]);i++){
if(k==coins[i].amount){
printf("%s\n",coins[i].name);
break;
}
}
return 0;
}
结构的sizeof是指结构整体所占空间的大小,由于结构中成员的排列顺序,数据是否对齐,造成与各个成员的sizeof之和并不相同。
结构内的成员之间不一定连续,相邻的成员的地址的差不一定等于对应的成员的sizeof,取决于成员所占空间大小与成员如何排列。
联合
联合union
- 存储
所有的成员共享一个空间
同一时间只有一个成员是有效的
union 的大小是其最大的成员
修改一个成员会影响其余所有成员 - 初始化
对第一个成员做初始化
union 共用体名{
成员列表
};
struct{
char name[20];
int num;
char sex;
char profession;
union{
float score;
char course[20];
} sc;
} bodys[TOTAL];