1.结构体定义
我们已经学过数组的定义,数组是相同类型元素的集合,那么,结构体就是不同类型元素的集合。比如,我们要将现实生活中的一个人的信息放到程序里,信息包括姓名,身高,体重,性别等等,这些都是不同类型元素,我们可以通过结构体有机的将他们结合起来。
/*编写一个结构体,存储人的基本信息*/ struct Stu { char name[5]; float height; float weight; char sex[]; }; int main() { struct Stu h = { "lvzi",160,55.3,"girl"}; printf("name=%s\n", h.name); printf("height=%.2f\n", h.height); printf("weight=%.2f\n", h.weight); printf("sex=%s\n", h.sex); return 0; }
补充:
数组和结构体都是处理多个对象集合的问题,他们都是聚合类型(aggregate type)。
数组和结构体的区别:
1.数组处理的是多个相同类型的元素,而结构体处理的是多个不同类型的元素(当然,结构体成员的类型也可以相同);
2.数组无法整个赋值,只能对数组元素一一赋值,而结构体可以整体赋值,或者说是将一个成员赋值给另一个成员;
3.数组不可以作为函数的返回值,而结构体可以(返回结构体的函数)
/*数组无法整体赋值,结构体可以 */ int a[5], int b[5]; a = b;//错误赋值 struct stu a, b; a = b;//可以,将b成员全部赋给a成员
/* 返回结构体的函数 */ /*结构体xyz*/ struct xyz { int x; long y; double z; }; /*返回结构体函数xyz_of*/ struct xyz xyz_of(int x, long y, double z)//函数的返回值应是结构体,所以用struct xyz;不能单独一个struct { //struct xyz 才能叫做一个结构体类型 struct xyz temp; temp.x = x * x; temp.y = y * y; temp.z = z * z; return temp; } int main() { struct xyz s = {0,0,0}; s = xyz_of(2, 3, 4); /*打印输出*/ printf("%d\n", s.x); printf("%ld\n", s.y); printf("%.2f\n", s.z); return 0; }
2.结构体的定义
结构体的定义有三种,作者建议尽量使用直接定义法,同时尽量 不要使用typedef定义的结构体,减少在阅读时产生的歧义;
#include <stdio.h> 结构体变量的定义(3种) 直接定义 struct stu { char name[20]; int age; int height; }; struct stu stu1; 直接初始化定义 struct stu { char name[20]; int age; int height; }; struct stu stu1 = {"Tom",18,180}; 使用typedefine定义(注意格式) typedef struct { char name[20]; int age; int height; } person;//一般把这个名字放到最后面 person person2;//此时person2就是一个结构体变量
3.结构体成员的访问
两种调用指针变量的方式 #include <stdio.h> struct Stu//定义结构体变量(未初始化) { char name[20]; int age; float score; }; void print1(struct Stu t) { printf("%s %d %f", t.name, t.age, t.score); } void print2(struct Stu* t) { printf("%s %d %f", (*t).name, (*t).age, (*t).score); } void print3(struct Stu* t) { printf("%s %d %f", t->name, t->age, t->score); } int main() { struct Stu t = { "mike",20,59.9}; print1(t);//第一种调用方式 结构体变量.成员名称 printf("\n"); print2(&t); printf("\n"); print3(&t); return 0; }
4.结构体数组
结构体类型作为一组数据类型,自然可以通过数组存放。数组元素是结构体,可以用于存储多位相同结构体成员的对象(比如存储多位人员的信息);
下面以一段代码为例,讲解结构体数组
/*结构体数组*/ /* 定义三个学生,并按身高进行排序 */ #define NAME_LEN 5 #define NUMBER 3 //定义学生人数 /*学生信息结构体*/ typedef struct{ char name[NAME_LEN]; float height; float weight; }Student; /*交换信息函数*/ void swap_stu(Student * x, Student * y) //定义两个结构体型指针变量,用来存储结构体的地址 { Student temp; temp = *x; *x = *y; *y = temp; } /*排身高函数*/ void sorted_by_height(Student a[], int num)//第一个形参应是结构体数组 { int i, j; for (i = 0; i < num; i++) { for (j = 0; j < num - i-1; j++) { if (a[j + 1].height < a[j].height)//只比较身高 { swap_stu(&a[j + 1], &a[j]); } } } } int main() { Student std[] = //std 结构体数组元素的数组名 { {"Bob",177.5,140.7}, {"Tom", 167.5, 120.7}, {"LVZI", 187.5, 110.7} }; int i;//依次打印每个人的信息 for (i = 0; i < NUMBER; i++) { printf("%-8s %6.2f %6.2f\n", std[i].name, std[i].height, std[i].weight); } sorted_by_height(std, NUMBER); printf("\n按身高排序后\n"); for (i = 0; i < NUMBER; i++) { printf("%-8s %6.2f %6.2f\n", std[i].name, std[i].height, std[i].weight); } return 0; }
5.作为成员的结构体
结构体的成员可以是数字,字符,字符串,也可以是结构体,即嵌套使用结构体
比如要研究一辆汽车行驶位置与其所剩燃料的关系;
对于汽车来说,有两个成员,位置和所剩燃料,而对于位置这个成员来说,又具有两个成员即x和y;如果想显示当前汽车的x位置,可以连用两个操作符 car.point.x;
补充:求两点之间的距离
/*计算两点之间的距离*/ //点结构体的声明 typedef struct { double x; double y; }Point; //求距离函数 double distance_of (Point pa, Point pb) { return (sqrt(pow(pa.x - pb.x, 2) + pow(pa.y - pb.y, 2))); } int main() { //定义起点和终点 Point ori, des; //设置坐标 printf("请输入起点的X坐标:"); scanf("%lf", &ori.x); printf(" Y坐标:"); scanf("%lf", &ori.y); printf("请输入终点的X坐标:"); scanf("%lf", &des.x); printf(" Y坐标:"); scanf("%lf", &des.y); //计算距离函数 double c =distance_of(ori, des); printf("两点间的距离为:%.2lf", c); return 0; }
结构体规范:1.结构体的声明放在外部,且放在靠前位置
2.尽量少用typedef ,可能会造成曲解
3.引用结构体成员时尽量使用->操作符,方便快捷
4.结构体类型也是一种数据类型,可以定义结构体数组,指向结构体的指针变量