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.结构体类型也是一种数据类型,可以定义结构体数组,指向结构体的指针变量