结构体
结构体
结构的模型:
1 2 3 4 5 6 7
struct 结构体名 { //[成员列表(member list)/域表(field list)] 类型名1 成员名1; 类型名2 成员名3; }
- 成员可以是其他结构体
定义结构体
先声明结构体类型,在定义该类型的变量
1 2 3 4 5 6 7 8 9 10 11
//声明结构体类型 struct Student { int num; char name[20]; char sex; int age; //struct Date birthday; chat addr[30]; } struct Student student1,student2;
- Tips:
- 许多计算机以4个字节为一个“字”,所以,如果在一个“字”中只存放了一个字节,但是该“字”剩下的3个字节不会被占用,而是跳过他们,去到下一个“字”开始存放。
- 所以这里sizeof(student1)的结果是64,而不是63
- 这种定义方式的好处:将
声明类型
和定义变量
分离开来,可以随时修改
2.在声明类型的同时定义变量
1 2 3 4 5 6 7
struct Student { int num; char name[20]; char sex; int age; }student1,student2;
3.不指定类型名而直接定义结构体类型变量
1 2 3 4 5 6 7 8
struct { int num; int num; char sex; int age; /* data */ }student1,student2;
- Tips:
- 结构体类型与结构体变量:
- 类型:定义结构体时用的,不会分配内存;
- 变量:实例化后的结构体,对其分配对应的空间大小;
- 结构体的成员名可以和程序中的变量名相同
- 结构体类型与结构体变量:
结构体变量的初始化和引用
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
#include <stdio.h>
int main(int argc, char const *argv[])
{
//初始化(赋值)
struct Student
{
/* data */
long int num;
char name[20];
char sex;
char addr[20];
}a{ 10101,"li min",'m',"123 beijing"};
//赋值方式一
struct Student b{ .name = "zhang fang"};
//赋值方式2
//.name === b.name
//其他未指定初始化0
//数值 -> 0
//字符型 -> '\0`
//指针型 -> 'NULL`
//引用
//结构体变量名.成员名
// . 是成员运算符 (运算符中最高的优先级) ==> 可以把student1.num看作是一个整体
return 0;
}
使用结构体数组
- 定义
1 2 3 4 5 6 7 8 9
// 方式1. struct 结构体名 { 成员列表} 数组名[数组长度]; //方式2 struct Person{ ... }; struct Person leader[3];
- 赋值
1 2 3
struct Person leader[3] = { "li",0,"zhang",0,"sun",0}; struct Person leader[3] = { {"li",0},{"zhang",0},{"sun",0}};
结构体指针
就是指向结构体变量的指针
- 一个结构体变量的起始地址 === 结构体变量的指针
指向结构体变量的指针
3种等价方法:
1 2 3 4 5 6 7 8 9 10 11 12
struct Student { long num; }; struct Student stu; //方法1 stu.num; //方法2 (*p).num; //方法3 p->num;
指向结构体数组的指针
可以用指针变量指向结构体数组的元素
p应该指向结构体类型,而不是结构体数组元素中的成员
如果非要,先将成员的地址转换成p的类型
1
p = (struct Student*)stu[0].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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdio.h>
struct
{
int num;
char name[10];
char sex;
char job;
union
{
int class;
char position[10];
}category;
}person[2];
//定义结构体数组person,有两个元素
int main(int argc, char const *argv[])
{
int i;
for(i=0;i<2;i++)
{
printf("please enter the date of person: \n");
scanf("%d %s %c %c",&person[i].num,
&person[i].name,
&person[i].sex,
&person[i].job);
if(person[i].job=='s') scanf("%d",&person[i].category.class);
else if(person[i].job == 't') scanf("%s",person[i].category.position);
else printf("input error!!!");
}
printf("\n");
printf(" NO.\tname\tsex\tjob\tclass/position\n");
for(i=0;i<2;i++){
if(person[i].job=='s') printf("%-6d%-10s%-4c%-4c%-10d\n",person[i].num,person[i].name,person[i].sex,person[i].job,person[i].category.class);
//%-6d 表示以十进制输出,占6列,数据向左对齐
else printf("%-6d%-10s%-4c%-4c%-10s\n",person[i].num,person[i].name,person[i].sex,person[i].job,person[i].category.position);
}
return 0;
}
1
2
3
4
5
6
7
8
9
//输出
please enter the date of person:
101 li f s 501
please enter the date of person:
102 wang m t prof
NO. name sex job class/position
101 li f s 501
102 wang m t prof
枚举类型
- 类型声明
- 方式1:
- 同时声明和定义[不带枚举类型名]
- enum {sum,mon,tue,wed,thu,fri,sat} workday,weekend;
- 方式2:
- 先声明枚举类型名,再定义枚举变量
- enum Weekday{sum,mon,tue,wed,thu,fri,sat};
- enum Weekday workday,weekend;
- 方式1:
- 枚举类型的枚举元素是常量,不能对其赋值
- 每个枚举元素都代表一个整数,一般默认顺序为:0,1,2,3,4….
- 枚举元素可以用来判断比较,因为每个枚举类型变量的值是整数。
typedef声明新类型名
1
2
typedef int Integer; //指定Interger为类型名,作用与 int相同
typedef int Count; //define int into Count,make reader easy to understand its function.
typedef与#define的区别
- 相似:作用都是用来将一个名字替换成另一个
- 不同:
typedef
is duringcompile
#define
is duringprecomppile
This post is licensed under CC BY 4.0 by the author.