第三周 结构类型
1、枚举
定义可以罗列起来的名字
enum COLOR{RED,YELLOW,GREEN};
·枚举是一种用户定义的数据类型,用关键字enum以如下语法来声明:
enum枚举类型名字{名字0,...,名字n};
·枚举类型名字通常并不真的使用,要用的是在大括号里的名字,因为他们就是常量符号,类型是int,值依次从0到n
当需要一些可以排列起来的常量值时,定义枚举的意义就是给这些常量值名字
#include
enum color{red,yellow,green};
void f(enum color c);
int main(void){
enum color t=red;
scanf("%d",&t);
f(t);
return 0;
}
void f(enum color c)
{
printf("%d\n",c);
}
·枚举量可以作为值
·枚举类型可以跟上enum作为类型
·但是实际上是以整数来做内部计算和外部输入输出的
枚举比宏好
声明结构类型
#include
int main(int argc,char const *argv[])
{
struct date{
int month;
int day;
int year;
};
struct date today;
today.month=07;
...
printf("Today's date is %i-%i-%i.\n",today.year,today.month,today.day)
}
---结构体一般放在函数外面
声明结构类型
-声明结构的形式
struct point{
int x;
int y;
};//声明结构point
struct point p1,p2;//声明两个变量
struct{
int x;
int y;
}p1,p2;
p1,p2都是无名结构,里面含有x和y
struct point{
int x;
int y;
}p1,p2;
p1和p2都是point里面有x和y的值
结构类型 结构变量
结构的初始化
#inlcude
struct date{
int month;
int day;
int year;
}
结构成员:
1、结构和数组类似
2、访问方法:
数组用[]运算符和下标访问其他成员
a[0]=10;
结构用.运算符和名字访问其成员
today.day
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;
结构作为函数参数
int numberofdays(struct date d)
·整个结构可以作为参数的值传入函数
·即在函数内新建一个结构变量,并复制调用者的结构的值
.优先级高于&
输入结构
没有直接的方式可以一次scanf一个结构
·if 写一个函数来读入结构
#include
struct point{
int x;
int y;
}
void getStruct(struct point);
void output(struct point);
void main(){
struct point y={0,0};
getStruct(y);
output(y);
}
void getStruct(struct point p){
scanf("%d",&p.x);
scanf("%d",&p.y);
printf("%d,%d",p.x,p.y);
}
void output(struct point p){
printf("%d,%d",p.x,p.y);
}
---输入函数里面的值并没有传进主函数里面
·C语言的特点是在函数调用的时候是传值的
·故函数中的变量p和main函数中的y是不同的变量
·在函数读入p的数值之后,没有任何东西进去main函数里面,故y输出为(0,0)
如何实现?
定义结构体函数,做结构体赋值
--结构体传递给函数,更有效的方式是传递指针而不是拷贝值
#include
struct point{
int x;
int y;
};
struct point getStruct(void);//定义结构体类型的函数
void output(struct point);
int main(int argc,char const *argv[])
{
struct point y={0,0};
y=getStruct();//进行结构体赋值
printf("\n");
output(y);
}
struct point getStruct(void){
struct point p;
scanf("%d",&p.x);
scanf("%d",&p.y);
printf("%d,%d",p.x,p.y);
return p;//返回一个结构体类型的值
}
void output(struct point p){
printf("%d,%d",p.x,p.y);
}
结构指针作为参数
指向结构的指针
struct date{
int month;
int day;
int year;
}myday;
struct date *p=&myday;//
(*p).month=12;//*p就是myday *p就是指针指的变量
p->month=12;//p所指的那个结构的month
·用->表示指针所指的结构变量中的成员
--花样写代码
#include
struct point{
int x;
int y;
};
struct point* getStruct(struct point*);//结构体指针
void output(struct point);
void print(const struct point *p);
int main(int argc,char const *argv[])
{
struct point y={0,0};
getStruct(&y);//进行结构体赋值
printf("\n");
output(y);
output(*getStruct(&y));//函数返回指针,*取出该指针的变量,作为函数的输入变量
print(getStruct(&y));
}
struct point* getStruct(struct point *p){
//struct point p;
scanf("%d",&p->x);
scanf("%d",&p->y);
printf("%d,%d",p->x,p->y);
return p;//返回一个结构体类型的值
}
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 date dates[100];//结构体数组
struct date dates[]={ {4,5,2005},{2,4,2005}};
1、结构体数组的初始化
struct time{
int hour;
int minutes;
int seconds;
};
struct time timeUpdate(struct time now);
struct time testTimes[5]={
{11,59,59},{12,0,0},{1,29,59},{23,59,59},{19,12,27}
};
2、结构体数组的使用
testTimes[i].hour,
---嵌套的结构
struct point{
int x;
int y;
};
struct rectangle{
struct point pt1;
struct point pt2;
};
如果有变量 struct rectangle r;
可以得到:
r.pt1.x r.pt1.y
r.pt2.x r.pt2.y
r为复合结构体
rp为结构体的指针
变量定义:
struct rectangle r,*rp;
rp=&r;
下面四种形式是等价的:
r.pt1.x
rp->pt1.x
(r.pt1).x
(rp->pt1).x
但是没有rp->pt1->x(因为pt1不是指针)
结构中的结构的数组
#include
struct point{
int x;
int y;
};
struct rectangle{
struct point p1;
struct point p2;
};
void printRect(struct rectangle r){
printf("<%d,%d>to<%d,%d>\n",r.p1.x,r.p2.y,r.p2.x,r.p2.y);
}
int main(int argc,char const *argv[]){
int i;
struct rectangle rects[]={ {
{1,2},{3,4},
{5,6},{7,8}}};//2个矩形
for(i=0;i<2;i++)
printRect(rects[i]);
}
---typedef 自定义数据类型
C语言提供的一个用以声明一个已有的数据类型的新名字
eg:
typedef int Length
使得Legnth 成为int类型的别名
声明新的类型的名字
·新的名字是某种类型的别名
·改善了程序的可读性
typedef long int64_t;
typedef struct ADate{
int month;
int day;
int year;
}Date;
/*
struct ADate{
int month;
int day;
int year;
}*/这一串是原来的类型
Date是typedef后的新的名字
结构体的名字就是Date
不使用typedef,声明结构体变量需要加上 struct point p1;
使用之后,声明结构体为 Date p1;
此外,还可以写成
typedef struct{
int month;
int day;
int year;
}Date;
typedef char* Strings[10];//Strings 10个字符串的数组的类型
typedef struct node{
int date;
struct node*next;
}aNode;
or
typedef struct node aNode;//使用aNode 就可以代替struct node;
----联合
1、联合的定义 声明 初始化
union AnElt{
int i;
char c;
}elt1,elt2;//两个成员变量和结构体不同,这两个成员变量共用一个内存空间
仅有一份内存空间
-存储:1、所有的成员共享一个空间
2、同一时间只有一个成员是有效的
3、union的大小是其最大的成员大小
-初始化:对第一个成员做初始化
elt1.i=4;
elt2.c='a';
elt2.i=0xDEADBEEF;
sizeof(union...)=sizeof(每个成员)的最大值
union 主要的使用场景:
#include
typedef union{
int i;
char ch[sizeof(int)];
}CHI;
int main(){
CHI chi;
int i;
chi.i=1234;
for(i=0;i
}
}
//小端模式
D2 04 00 00