结构体
- 结构体可以将松散的数据,不同类型的数据进行整合,规划在一起
一、基础
1、声明和初始化
struct Stu
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
}a; //并创建一个结构体变量a
也可以创建两个并定义
struct Stu
{ int member1;
char member2;
} a = {10, 'a'}, b = {20, 'b'};
等同于再写一横代码
struct Stu c = {20, 'b'}, d = {30, 'c'};// 同时声明并初始化c和d
2、匿名结构体
struct // 结构体类型
{
char name[20];
char sex;
int num;
float score[3]
}person1,person2;
- 这里的
struct
后面没有跟名称,这个结构体类型是匿名的。这意味着它不能被用来定义其他变量,只能用于定义person1
和person2
这两个变量。 - 这种定义方式在某些情况下是有用的,特别是当你只需要定义一个或几个特定结构体变量,而不需要复用这个结构体类型时。
3、成员访问
-
为了访问结构的成员,我们使用成员访问运算符(.)。
-
引用形式:<结构体类型变量名> . <成员名>
int main()
{ stu1 = { "Tom",12,18,'A'};// 给结构体成员赋值
printf("%s的学号是%d,年龄是%d,在%c组\n", stu1.name, stu1.num, stu1.age, stu1.group);
return 0;
}
- 需要注意的是,结构体是一种自定义的数据类型,是创建变量的模板,不占用内存空间;结构体变量才包含了实实在在的数据,需要内存空间来存储。
4、注意
-
结构体变量名和数组名不同,数组名在表达式中会被转换为数组指针,而结构体变量名不会,无论在任何表达式中它表示的都是整个集合本身,要想取得结构体变量的地址,必须在前面加&符号,所以给p赋值只能写成。
-
结构体和结构体变量是两个不同的概念:结构体是一种数据类型,是一种创建变量的模板,编译器不会为它分配内存空间,就像 int、float、char 这些关键字本身不占用内存一样;结构体变量才包含实实在在的数据,才需要内存来存储。
二、结构体数组
- 结构体数组:是指数组中的每一个元素都式结构体。
- 结构体数组常被用来表示一个拥有相同数据结构的群体。eg 一个班级里的三十人
1、声明
struct stu
{
char name[20]; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
}class[5];
//表示一个班有5个人
2、初始化
struct stu
{
char name[20]; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
} class[5] = {
{"Li ping", 5, 18, 'C', 145.0},
{"Zhang ping", 4, 19, 'A', 130.5},
{"He fang", 1, 18, 'A', 148.5},
{"Cheng ling", 2, 17, 'F', 139.0},
{"Wang ming", 3, 17, 'B', 144.5}
};
- 当对数组中全部元素赋值时,也可以不给出数组长度
struct stu
{
char name[20]; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
}class[] = {
{"Li ping", 5, 18, 'C', 145.0},
{"Zhang ping", 4, 19, 'A', 130.5},
{"He fang", 1, 18, 'A', 148.5},
{"Cheng ling", 2, 17, 'F', 139.0},
{"Wang ming", 3, 17, 'B', 144.5}
};
3、运用
- 结构体数组的使用:计算全班学生的总成绩、平均成绩和140分一下的人数
int main()
{
int i, num_140 = 0;
float sum = 0;
for (i = 0; i < 5; i++) {
sum += ban[i].score;
if (ban[i].score < 140) num_140++;
}
printf("sum=%.2f\naverage=%.2f\nnum_140=%d\n", sum, sum / 5, num_140);
return 0;
}
三、结构体和指针
1、定义和声明
-
定义类型:
struct 结构体名 * 结构体指针名
struct stu*p=&stu1//stu 为结构体名 p为结构体指针名 stu1为定义的结构体变量
- 也可以在同时定义结构体指针
struct stu
{ char *name;
int num;
int age;
char group;
} stu1 = { "Tom", 12, 18, 'A'}, *p = &stu1;//结构体指针 ,也可以同时的定义
struct stu *p = &stu1;//完全的等效
2、访问成员
(*p).nane //p为结构体指针名
p->name // 或者
第一种写法中, . 的优先级高于 ***** ,(p)两边的括号不能少
如果去掉括号写成 * p.name
那么就等效于(p.name),这样意义就不对了。第二种写法中,-> 是一个新的运算符,习惯称它为“箭头”
这也是 -> 在C语言中的唯一用途。
3、- >
在C语言中,->
是一个运算符,用于访问结构体指针指向的结构体中的成员。当你有一个指向结构体的指针时,你可以使用 ->
运算符来访问该结构体的成员。
printf("Name: %s\n", p->name);
printf("Sex: %c\n", p->sex);
printf("Age: %d\n", p->age);
- p->name 表示指针 p 指向的结构体的 name成员,p->sex 表示 sex 成员,p->age 表示 age 成员。
4、结构体数组指针
struct Student
{
char cName[20];
int number;
char csex;
}student1; //结构体变量
struct Student stu1[5]; //结构体数组
struct Student*p; // 结构体指针
p=stu1[n];
(++p).number//是指向了结构体数组下一个元素的地址
- p=stu1[n] 其中stu1[n]是一个数组名代表着地址
- p++代表移向下一个数组元素,也就是结构体
5、结构体元素是指针
struct Student
{ char* Name;
int number;
char csex;
}stu;
- stu . Name=(char) malloc (sizeof (char) );*
- 在使用时可以很好地防止内存被浪费,
- 防止Name被分配到任意的地址,有危险
未完待续
四、typedef
- 简化类型定义
1、简化
typedef struct tag {
member1;
member2;
} Tag;
- 同样也可以写成
typedef struct tag Tag;
- 只是相当于让struct tag等价于Tag,其他的一点都没有变
2、使用
- 定义变量
Tag a; // 使用typedef定义的类型创建变量
Tag b, c; // 同时创建b和c两个变量
- 定义指针
Tag*p=&a;