目录
一、从基本数据类型到抽象数据类型
在冯诺依曼结构体系中程序和数据都是以二进制储存,为了表示复杂的数据结构仅使用几种基础类型显然是不够的。然而任何一种程序设计语言都无法将实际应用中涉及的所有复杂数据对象都作为其基本数据类型,所以根本解决方法就是允许用户自定义数据类型于是C语言中出现了构建数据类型也称作复合数据类型。
二、结构体的定义
1.为什么要定义结构体
数组是由相同类型的数据构成的一种数据结构适合于对其具有相同属性的数据进行批量处理。而结构体是将不同类型的数据成员组织到同一名字之下是用于对关系紧
密、逻辑相关具有相同或不同属性的数据进行处理.
2.结构体变量的定义
第一步:结构体模板的声明:
struct 结构体名(用于区别于其他结构体也称结构体标签)
{
数据类型 成员1的名字
数据类型 成员2的名字
数据类型 成员3的名字
……
数据类型 成员n的名字
};
分号是结构体声明的结束标志不能省略。
注意:结构体模板只是声明了数据类型,定义了数据的组织形式,并未声明结构体类型的变量。
第二步:
- 先声明结构体模板,再定义结构体变量。
struct point stu1;
- 在声明结构体模板的同时定义结构体变量。
一种形式是:
Struct {
int x;
int y;
}p1,p2;
此种方法因未指定结构体标签,不能再在程序的其他处定义结构体变量因而并不常用
另一种是:
Struct point{
int x;
int y;
}p1,p2;
三、用typedef定义数据类型
关键字typedef用语位系统固有的或程序员自定义的数据类型定义一个别名数据类型的别名,通常使用大写字母目的是为了与己有的数据类型相区分。
typedef是为一种已存在的类型定义一个新的名词,并未定义一种新的数据类型。
四、结构体变量的初始化
结构体变量的成员可以通过将成员的初值至于花括号之内进行初始化。
-
#include<stdio.h>
-
strust date {
-
int month;
-
int day;
-
int year;
-
};
-
int main(int argc;char const*argv[])
-
{
-
strust date today={07,31,2014};
-
strust date thismonth={,month=7;year=2014};
-
printf(“Today’s date is %i-%i-%i.\n”,today.year,today.month,today.day) ;
-
printf(“This month is %i-%i-%i.\n,thismonth.year,thismonth.month,thismonth,day”);
-
return 0;
-
}
输出:Today’s day is 2014-7-31
This month is 2014-7-0
没有赋值会带入0(类似于数组)
访问结构体变量的成员必须使用成员选择运算符也称圆点运算符格式如下:结构体变量名.成员名
五、嵌套的结构体
嵌套的结构体就是在一个结构体内包含了另一个结构体作为其成员。
-
typedef strust date
-
{
-
Int year;
-
Int month;
-
Int day;
-
}DATE;
-
typedef strust student
-
{
-
Long studentID;
-
char studentname[10];
-
char studentsex;
-
DATE birthday;
-
Int score[4];
-
}STUDENT;
初始化:STUDENT stu1={2021xxxxxx,“范老大”,‘Man’,{2003,“月份(eg:May)”,xx},{100,98,96,93}};
运算:当出现结构体嵌套时必须以联级方式访问结构体成员,即通过成员选择运算符逐级找到最底层的成员时再引用。
stu1.birthday.year=2003;(大概吧)
六、结构数组
strust date dates[100];
strust date dates[]={{4,5,6},{7,8,9}}
七、结构体的运算
1.C语言允许对具有相同结构类型的变量进行整体赋值。但对于字符数组类型的结构体进行赋值时,只能用strcpy()。
2.结构体类型的声明既可以放在所有函数体的外部也可以放在函数体内部。在函数体外部声明的结构体类型可为所有函数使用称为全局声明;在函数体内声明的结构体类型只能在本函数体内使用就离开,该函数声明失效,称为局部声明。
八、结构体所占字节
我们先引一个例子:
-
#include<stdio.h>
-
typedef struct sample
-
{
-
char m1;
-
int m2;
-
char m3;
-
}SAMPLE;
-
int main (void)
-
{
-
SAMPLE s={'a',2,'b'};
-
printf("bytes=%d\n",sizeof(s));
-
return 0;
-
}
输出结果是:bytes=12
显然我们知道:char所占字节为1,int所占字节为4,之所以会输出12个字节,是因为内存对齐。即为了满足处理器的对齐要求,可能会再较小成员会加入补位,从而导致多了一些字节。
九、结构作为函数参数
1.整个结构可以作为参数的值传给函数。
2.这时候在函数奶新建一个结构变量,并复制调用者的结构的值。
3.也可以返回一个结构。
4.这与数组完全不同。
给函数输入参数可能会出现这种情况:
-
#include<stdio.h>
-
strust point(
-
int x;
-
int y;
-
};
-
void getStrust(strust point);
-
void output(strust point);
-
void main()
-
{
-
strust point y={0,0};
-
getStrust(y);
-
output(y);
-
}
-
void getStrust(strust point p)
-
{
-
scanf("%d",&p.x);
-
scanf("%d",&p.y);
-
printf("%d,%d\n");
-
}
-
voidoutput(strust point p)
-
{
-
printf("%d,%d",p.x,p.y);
-
}
输入:12,23
输出:12,23\n0,0
解决办法是:在输入函数中,创建一个临时的结构变量,然后八这个结构返回给调用者。
-
#include<stdio.h>
-
strust point(
-
int x;
-
int y;
-
};
-
strust point getStrust(void);
-
void output(strust point);
-
void main()
-
{
-
strust point y={0,0};
-
y=gesStrust();
-
output(y);
-
}
-
strust point getStrust(void);
-
{
-
strust point p;
-
scanf("%d",&p.x);
-
scanf("%d",&p.y);
-
printf("%d,%d\n");
-
return p;
-
}
-
voidoutput(strust point p)
-
{
-
printf("%d,%d",p.x,p.y);
-
}
十、结构体指针的定义与初始化
1.指向结构体变量的指针
-
strust date{
-
int month;
-
int day;
-
int year;
-
}myday;
-
strust date *p=&myday;
-
(*p).month=12;
-
p->month=12;
指向结构体的指针变量名->成员名(指向运算符/箭头运算符)
-
#include<stdio.h>
-
strust point(
-
int x;
-
int y;
-
};
-
strust point* getStrust(strust point*);
-
void output(strust point);
-
void printf(const struct point*p)
-
void main()
-
{
-
strust point y={0,0};
-
gesStrust(&y);
-
output(y);
-
output(*gesStrust(&y));
-
printf(gestrust(&y));
-
return 0;
-
}
-
strust point* getStrust(strust point*p)
-
{
-
scanf("%d",&p->x);
-
scanf("%d",&p->y);
-
printf("%d,%d\n",p->x,p->y);
-
return p;
-
}
-
void output(strust point p)
-
{
-
printf("%d,%d",p.x,p.y);
-
}
-
void print(const strust point*p)
-
{
-
printf("%d,%d",p->x,p->y);
-
}
2.指向结构体数组的指针
strust date{
int month;
int day;
int year;
};
strust date dates[100];
strust date dates[]={{4,5,6},{7,8,9}}
定义指针变量pt指向结构体数组的方式:
strust point*pt=dates;
等价于strust point*pt=&dates[0];
等价于strust point*pt;pt=dates;
十一、枚举
枚举是一种用户定义的数据类型,它用关键字enum一如下语句声名:
enum枚举类型名字{名字0,...名字n}
枚举类型名字通常不真的使用,要用的是大括号里的名字,因为他们就是常量符号,类型是int,值依次是0到n。
enum colors{red,yellow,green};
red值是0,yellow值是1.green值是2.
-
#include<stdio.h>
-
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);
-
}
计数器
-
#include<stdio.h>
-
enum color {red=1;yellow,green=5,Numcolors};
-
int main (void)
-
{
-
printf("code for green is %d\n",green);
-
return 0;
-
}