c语言.ppt
4
结构说明与结构变量定义
结构说明由struct引导,基本形式
struct [类型名] { 成员列表};
结构变量定义:
2)定义结构类型的同时定义结构变量 3)直接定义结构变量 1)先定义结构类型,再定义结构变量
例 struct student 例 struct student { int num; { int num; char name[20]; char name[20]; char sex; char sex; int age; int age; double score; douБайду номын сангаасle score; char addr[30]; char addr[30]; }; }stu1,stu2; }stu1, stu2; struct student stu1, stu2;
10
示例:居民身份证
居民身份证信息的结构类型定义
typedef struct { //注:二代身份证可能不止这些信息 char name[20]; // 名字字符串用多长? int sex; //性别 char nationality[10]; //民族 int born_in[3]; //出生地 char address[50]; //地址 int date_of_issue[3]; //发放日期 int valid_years; //有效期 char issued_by[30]; //发证机关 char id_number[18]; //身份证号 char photo[100][64]; //照片 } IDCARD;
8
用结构标志定义结构变量
利用结构标志定义结构变量
struct point pt1, pt2; struct circle circ1, circ2; double distance(stuct point p1, struct point p2);
与结构有关的函数的原型说明:
结构标志可用于定义指向结构的指针,做类型转 换,计算大小,建立存放结构的存储块:
11
无效结构定义
结构成员不能是被描述的结构本身。 非法结构描述的例子
struct invalid { int n; struct invalid iv; };
这种描述定义的结构里包含自身,引起了 无穷嵌套,不合理,也不可能在计算机里 实现。
12
二、回顾结构的实现问题
2013-12-13
14
19
例
结构体指针间接访问分量
例
POINT *pPoint, point1, point2; pPoint = &point1; pPoint->x = 10; pPoint->y = 15;
20
四、结构体与函数
2013-12-13
21
1. 结构与函数
结构可作为函数参数和函数返回值。将结 构数据传给函数有三种方式(返回值情况 类似):
void prtIDCard(IDCARD *icp) { printf("%s\n%s\n\n", icp->id_number, icp->name); }
只复制一个指针,更合理。设idc是IDCARD变量:
prtIDCard(&idc);
例,打印一个身份证结构数组中的各身份证的信息
IDCARD idcs[10000], *p; ... /* 假设idcs的元素都有了值 */ for(p = idcs; p < idcs+10000; p++) prtIDCard(p);
例:打印身份证中身份证号和姓名的函数: void prtIDCard0(IDCARD ic) { printf("%s\n", ic.id_number); printf("%s\n\n", ); } 复制整个结构,大部分复制工作没有价值
25
3. 传递结构体指针
可考虑传递结构指针,下面函数完成同样工作:
7
定义结构体标志
struct point { //点结构体 double x; //横坐标 double y; //纵坐标 }; struct circle { //圆结构体 struct point center; //圆心 double radius; //半径 }; struct rectangle { //矩形 struct point lu; //左上角点 struct point rd; //右下角点 };
同类型结构变量可整体赋值,效果是各成员分别赋值 pt2 = pt1;
结构体不能做相等、不等比较 成员访问
访问结构体成员用圆点运算符(.),具有最高优先级, 自左向右结合。 pt2.y = pt1.y + 2.4; circ1.center.x = 2.07; circ1.center.y = pt1.y;
例:由参数值构造POINT类型的结构值,函数定义 POINT mkpoint1(double x, double y) { POINT temp; temp.x = x; temp.y = y; return temp; } 返回值可赋给同类型变量。这种函数从成员值构造结构 值,可称为结构值构造函数。使用:
circ1 = mkcircle(pt1, 5.254); circ2 = mkcircle(circ1.center, 11.7); circ3 = mkcircle(mkpoint1(2.05, 3.7), 3.245);
第三个例子:mkpoint返回POINT值,传给mkcircle的 POINT类型参数
画图软件中需要描述点、圆、矩形等形状。 分析
平面上的点可形式表达为(x, y) 在平面上,圆心(x, y)和圆半径可唯一地表示一个圆 在平面上,给定矩形的左上角的点和右下角的点即可 唯一地确定一个矩形。
因此,定义圆或矩形都需要定义一个点。 拓展学习
对于规则形状的描述方法 图形学
16
struct exam 的可能布局
4 个字节 aa nn
xx
• 结构成员可能不连续,存放位置之间可能出现空位( 结构中的空洞) • 结构大小未必等于成员大小之和。应该用sizeof计算 结构大小(例如动态存储分配时)
17
三、回顾结构体变量的使用
2013-12-13
18
结构变量的使用
同类型体可以整体赋值
struct exam { char aa; int nn; double xx; };
为了效率,硬件通常规定各种基本类型数据的摆放 方式。例如,通常要求两字节表示的整数从偶数地 址的单元开始存放;需要8个字节表示的双精度数, 可能要求从8(或4)的倍数地址的单元开始存放。 系统对整个结构对象的存放也可能有起始位置要求
struct circle *p; p = (stuct circle *)malloc(sizeof(struct circle)); ... ...
9
定义结构体类型
程序里反复使用的结构最好是定义为类型 typedef struct { double x; double y; } POINT; //定义POINT类型 typedef struct { POINT center; double radius; } CIRCLE; //定义CIRCLE类型 typedef struct { POINT lu; //左上点 POINT rd; //右下点 } RECTANGLE; //定义RECTANGLE类型
结构的实现
一个结构占一块连续存储,各成员顺序存放。 CIRCLE对象的存储方式。 typedef struct { POINT center; double radius; } CIRCLE;
CIRCLE 结构
x POINT 结构
y
radius
15
对齐问题
结构成员类型可不同,可能出现对齐问题:
传结构成员的值,只要该成员能赋值。 传递整个结构的值。结构参数。
实参结构变量的值整个赋给形参,函数内对形参 的操作不会影响实参 传结构指针允许函数对实参结构做任何操作,包 括修改。可以避免结构复制,若结构很大,复制 费时间,也可考虑用指针方式传递
传结构的地址(指针)。结构指针参数。
22
2. 处理结构的函数
5
说明
一个结构里可以有任意多个成员 成员可为任何类型,如基本类型、指针或 数组成员 成员也可以是结构 成员名用标识符表示 一个结构里各个成员的名字不能相互冲突 不同结构完全可以包含名字相同的成员, 相互无关 结构的成员名与结构外的其他名字无关, 不会冲突
6
结构定义方法示例
pt1 = mkpoint1(3.825, 20.7); pt2 = mkpoint1(pt1.x, 0.0);
temp随函数结束而撤消,值返回,与局部变量的撤消无 关。返回大的结构值时需要复制大批数据
23
由参数值构造CIRCLE类型的结构值,函数定义: CIRCLE mkcircle(POINT c, double r) { CIRCLE temp; temp.center = c; temp.radius = r; return temp; } 函数有一个结构参数。用例:
24
typedef struct { char name[20]; 定义计算两个点之间距离的函数,采用结构参数: int sex; double distance(POINT p1,char nationality[10]; POINT p2) int born_in[3]; { char address[50]; int date_of_issue[3]; double x = p1.x-p2.x, y = p1.y-p2.y; int valid_years; char issued_by[30]; return sqrt(x*x + y*y); char id_number[18]; } char photo[100][64]; } IDCARD; 复制整个结构,语义清楚。缺点是整体复制开销较大