什么是结构体
结构体和数组一样属于构造类型
数组是用于保存一组相同类型数据的, 而结构体是用于保存一组不同类型数组的
例如:在学生登记表中,姓名应为字符型;学号可为整型或字符型;年龄应为整型;性别应为字符型;成绩可为整型或实型。
显然这组数据不能用数组来存放, 为了解决这个问题,C语言中给出了另一种构造数据类型——“结构(structure)”或叫“结构体”。
定义结构体类型
在使用结构体之前必须先定义结构体类型, 因为C语言不知道你的结构体中需要存储哪些类型数据, 我们必须通过定义结构体类型来告诉C语言, 我们的结构体中需要存储哪些类型的数据
struct 结构体名{
类型名1 成员名1;
类型名2 成员名2;
……
类型名n 成员名n;
};
例如
struct Student {
char *name; // 姓名
int age; // 年龄
float height; // 身高
};
定义结构体变量
定好结构体类型之后, 我们就可以利用我们定义的结构体类型来定义结构体变量
定义结构体变量的三种方法
1.先定义结构体类型,再定义变量
struct Student {
char *name;
int age;
};
struct Student stu;
2.定义结构体类型的同时定义结构体变量
struct Student {
char *name;
int age;
} stu;
3.匿名结构体定义结构体变量
struct {
char *name;
int age;
} stu;
第三种方法与第二种方法的区别在于,第三种方法中省去了结构体类型名称,而直接给出结构变量,这种结构体最大的问题是结构体类型不能复用。
结构体变量的初始化
1.定义的同时按顺序初始化
struct Student {
char *name;
int age;
};
struct Student stu = {“lnj", 27};
2.定义的同时不按顺序初始化
struct Student {
char *name;
int age;
};
struct Student stu = {.age = 35, .name = “lnj"};
.3.先定义后一次性初始化
struct Student {
char *name;
int age;
};
struct Student stu;
stu2 = (struct Student){"lnj", 35};
结构体数组
结构体数组和普通数组并无太大差异, 只不过是数组中的元素都是结构体而已
struct Student {
char *name;
int age;
};
struct Student stu[2];
结构体数组初始化和普通数组也一样, 分为先定义后初始化和定义同时初始化
定义的同时初始化
struct Student {
char *name;
int age;
};
struct Student stu[2] = {{"lnj", 35},{"zs", 18}};
先定义后初始化
struct Student {
char *name;
int age;
};
struct Student stu[2];
stu[0] = {"lnj", 35};
stu[1] = {"zs", 18};
结构体指针
一个指针变量当用来指向一个结构体变量时,称之为结构体指针变量
// 定义一个结构体类型
struct Student {
char *name;
int age;
};
// 定义一个结构体变量
struct Student stu = {“lnj", 18};
// 定义一个指向结构体的指针变量
struct Student *p;
// 指向结构体变量stu
p = &stu;
/*
这时候可以用3种方式访问结构体的成员
*/
// 方式1:结构体变量名.成员名
printf("name=%s, age = %d \n", stu.name, stu.age);
// 方式2:(*指针变量名).成员名
printf("name=%s, age = %d \n", (*p).name, (*p).age);
// 方式3:指针变量名->成员名
printf("name=%s, age = %d \n", p->name, p->age);
return 0;
}
通过结构体指针访问结构体成员, 可以通过以下两种方式
1.(*结构指针变量).成员名
2.结构指针变量->成员名
#include<stdio.h>
#include<string.h>
typedef struct stu
{
int id;
char name[20];
int age;
float score;
}STU;
int main()
{
STU stu = {1001,"lilei",24,98.5};//定义一个结构体变量
STU *pstu;//定义一个结构体指针
pstu = &stu;
pstu->id = 1002;
strcpy(pstu->name , "hanmeimei");
pstu->age = 25;
pstu->score = 92.3;
printf("%d %s %d %.1f\n",pstu->id,pstu->name,pstu->age,pstu->score);
return 0;
}
结构体嵌套的定义
成员也可以又是一个结构,即构成了嵌套的结构
#include<stdio.h>
#include<string.h>
typedef struct birthday
{
int year;
int month;
int day;
}BIR;
struct person
{
int id;
char name[20];
int age;
BIR birth;
};
int main()
{
struct person per1 = {
.id = 1001,
.name = "lelei",
.age = 23,
.birth.year = 1999,
.birth.month = 10,
.birth.day = 12
};
printf("%d %s %d %d %d\n",per1.id,per1.name,per1.age,per1.birth.year,per1.birth.month,per1.birth.day);
return 0;
}
对嵌套结构体成员的访问
如果某个成员也是结构体变量,可以连续使用成员运算符"."访问最低一级成员
struct Date {
int year;
int month;
int day;
};
struct Student {
char *name;
struct Date birthday;
};
struct Student stu;
stu.birthday.year = 1986;
stu.birthday.month = 9;
stu.birthday.day = 10;
结构体和函数
结构体虽然是构造类型, 但是结构体之间赋值是值拷贝, 而不是地址传递
#include<stdio.h>
#include<string.h>
typedef struct stu
{
int id;
char name[20];
float score;
}STU;
//结构体中的成员作为函数的参数传递
float compare_score(float a,float b);
STU compare(STU stu1,STU stu2);
int main()
{
STU stu1 = {1001,"lilei",98.5},stu2 = {1002,"lucy",99.3};
float ret = compare_score(stu1.score,stu2.score);
printf("%.1f\n",ret);
STU ret1 = compare(stu1,stu2);
printf("%d,%s,%.1f\n",ret1.id,ret1.name,ret1.score);
return 0;
}
float compare_score(float a,float b)
{
if(a>b)
{
return a;
}
else
{
return b;
}
}
STU compare(STU stu1,STU stu2)
{
if(stu1.score>stu2.score)
{
return stu1;
}
else
{
return stu2;
}
}
结构体类型作用域
结构类型定义在函数内部的作用域与局部变量的作用域是相同的从定义的那一行开始, 直到遇到return或者大括号结束为止。
结构类型定义在函数外部的作用域与全局变量的作用域是相同的从定义的那一行开始,直到本文件结束为止。
关于结构体今天就学习了这么多,那也就分享这么多吧,明日继续。