C语言中的结构体

结构体(struct)


将一组不同类型的元素定义在一起,且以struct声明,就是结构体。

1
2
3
4
5
struct Person {
char name[20]; //char *name;
int age;
float weight;
};

定义


  • 不允许对结构体本身递归定义

    如下定义是错误的,

    1
    2
    3
    4
    truct Student {
    int age;
    struct Student stu; //error
    };

  • 结构体内可以包含别的结构体

  • 结构体变量占用的内存空间是其成员所占内存之和,而且各成员在内存中按定义的顺序依次排列

三种结构体变量定义形式

  • 先定义结构体类型,再定义变量
1
2
3
4
5
6
struct Person {
char name[20];
int age;
float weight;
};
struct Person person;
  • 结构体类型与变量同时定义
1
2
3
4
struct Student {
char *name;
int age;
} stu;
  • 省略类型,结构体变量名为stu
1
2
3
4
struct {
char *name;
int age;
} stu;

在定义变量的位置,是可以定义多个变量的:

1
2
3
4
struct {
char *name;
int age;
} stu1, stu2, stu3;

初始化


  • 先定义,后初始化

    1
    2
    3
    4
    5
    6
    7
    8
    struct Person {
    char name[20];
    int age;
    float weight;
    };
    int main() {
    struct Person person = {"a", 28, 55.5f};
    }

  • 定义时,并初始化

    1
    2
    3
    4
    5
    struct Person {
    char name[20];
    int age;
    float weight;
    } person = {"a", 28, 55.5f};

初始化的时候,可以按顺序赋值一些变量,而不全部赋值,与数组类似

1
2
3
4
5
6
7
> > struct Person {
> > char name[20];
> > int age;
> > float weight;
> > } person = {"a", 28};
> >
>
  • 不能在初始时,先声明变量,再初始化

    如下,是错误的

    1
    2
    struct Person person;
    person = {"a", 28, 55.5f}; //error

使用


以 “变量名.属性”来使用

1
person.age = 18;

结构体中, 若以 char name[20]; 字符数组形式声明: 不能直接用 person.name = "name";来赋值。

要以 strcpy(person.name, "name"); 这样的形式来赋值。

若声明成 char *name; 则不会有这样的问题

结构体数组


跟结构体变量一样,结构体数组也有3种定义方式

初始化与数组类似 struct Person person = { {}, {}, {} }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//第一种
struct Student1 {
int grade;
};
struct Student1 stu1[3];//先定义结构体类型,再定义变量
//第二种
struct Student2 {//直接在变量后声明数组
int grade;
}stu2[3];
//第三种
struct {//省略结构体名字,并声明为数组
int grade;
}stu3[3];

结构体作为函数参数


值传递: 将结构体变量作为函数参数进行传递时,其实传递的是全部成员的值,也就是将实参中成员的值一一赋值给对应的形参成员。因此,形参的改变不会影响到实参。

指向结构体的指针


结构体指针变量的定义形式:struct 结构体名称 *指针变量名,如:

1
2
struct Person p = {..};
struct *xp = &p;

有了指向结构体的指针,那么就有3种访问结构体成员的方式:

1
2
3
4
printf("%s\n", p.name);
//下面两种是用 指针变量来访问结构体成员
printf("%s\n", (*xp).name);//因为 .优先级高,所以要括起来(*xp)
printf("%s\n", xp->name);

结构体链表


静态链表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdlib.h>
void static_link_test(void) {
struct Person {
int age;
struct Person *next;
} a, b, c, *p;
a.age = 10;
b.age = 20;
c.age = 30;
p = &a;
a.next = &b;
b.next = &c;
c.next = NULL;
struct Person *t = p;
while (t != NULL) {
printf("cur age = %d \n", t->age);
t = t -> next;
}
}

动态链表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdlib.h>
struct dynamic_link_person {
int age;
struct dynamic_link_person *next;
};
void dynamic_link_create(int n) {
if (n < 0) {
exit(1);
}
//声明结构体 指针类型的 数组
struct dynamic_link_person *ary[n];
for (int i = 0; i < n; ++i) {
//动态分配内存
ary[i] = (struct dynamic_link_person*) malloc(sizeof(struct dynamic_link_person));
ary[i] -> age = 10 + i;
printf("%d ", (*ary[i]).age);
}
printf("\n");
//声明指针 指向 数组末尾
struct dynamic_link_person *p = ary[n - 1];
for (int i = n - 1; i > 0; --i) {
ary[i] -> next = ary[i - 1]; //next 指向 数组中前一个元素
}
ary[0] -> next = NULL;
/*
遍历 链表
*/
struct dynamic_link_person *temp = p;
while (temp != NULL) {
printf("%d ", (*temp).age);
temp = (*temp).next;
}
printf("\n");
/*
释放动态申请的内存
*/
for (int i = 0; i < n; ++i) {
free(ary[i]);
}
}
------ 本文结束 ------

版权声明
协议:No Fuck License

stone 创作并维护
本文首发于 stone世界 博客( http://stone86.top
版权所有,侵权必究。如要转载,请声明出处

Fork me on GitHub