结构体: 结构体是一种自定义的数据类型
不同于enum, struct各成员名是用分号’;’ 分隔, 而不是逗号’,’.
结构体需要先声明和定义, 然后再声明和定义其结构体变量, 才可进行访问.
结构体本身不能被直接赋值定义.
定义结构体变量方法:
struct 结构体名 变量名 = {初值};
例如: 先声明并实现结构体的内容
struct
student{ // 这是结构体, 叫student
char
name[
20
];
//
注意
中间用分号分离
char sex;
int age;
double studentID;
char sex;
int age;
double studentID;
float score;
// void printName(); 注意, 在结构体中不可以声明一个函数. 函数不能作为结构体的成员
};
结构体本身不能在声明成员变量时赋值, 只能通过它的变量给它赋值, 不同的变量会开辟不同的空间, 各变量的值不会冲突
然后在main函数中声明结构体变量并赋初值
struct
student
stu = {
"xiaoming"
,
'm'
,
21
,
20151016,
88
};
// 注意, 初值的赋值时得注意数据类型一致 不同成员之间用逗号’,’而不是’;'隔开
// stu 叫结构体student 的结构体变量
结构体变量的取值
通过 变量名. 成员名 的方式进行取值
比如我现在要获得并打印结构体变量 stu 的名字
printf
(
"%s\n"
, stu.
name
);// 即可
如果要修改结构体变量名的某个值, 如将stu的age改成23,stu的name改成
"longjiang"
stu.
age
=
23
;
对于基本类型, 可通过直接访问的方法改变结构体变量对应成员的值.
但要注意的是, 如成员变量是数组的时候, 不能够直接进行赋值, 得通过访问数组的具体地址进行赋值
而是得通过strcpy(stu.name,"longjiang”); 方法进行修改
如何通过一个函数打印整个stu的值呢?
刚才提过, 结构体是自定义的数据类型 函数的形式参数写法是 (数据类型 变量名) 同理 可将结构体的变量当成参数传给函数
不同的是结构体的数据类型是自定义的 写法是 struct 结构体名 结构体变量名
void
printStudent(
struct
student
stu) { // 形参的数据类型是 struct student
printf("%s\n", stu.name);
printf("%c\n", stu.sex);
printf("%d\n", stu.age);
printf("%.2lf\n", stu.studentID);
printf("%.2f\n", stu.score);
printf("%c\n", stu.sex);
printf("%d\n", stu.age);
printf("%.2lf\n", stu.studentID);
printf("%.2f\n", stu.score);
}
printStudent(stu);
// 将stu的所有信息打印出来
匿名结构体
通过上面的信息 我们可以知道 :
1. 结构体内不能定义函数
2. 结构体不能给自己赋值
3. 结构体只能通过定义结构体变量, 来对结构体内的数据进行操作
如果结构体是匿名的 也就是没有名字的, 那我们要怎么定义这个匿名结构体的结构体变量呢?
struct
{
char name[ 20 ];
char sex;
int age;
}
student1 = { "123" , 'a' , 22 }
char name[ 20 ];
char sex;
int age;
}
student1 = { "123" , 'a' , 22 }
;
可以在声明结构体的同时, 声明结构体变量
也可以这么声明:
struct
{
char name[ 20 ];
char sex;
int age;
char name[ 20 ];
char sex;
int age;
} student1, student2;
然后通过student1.sex = ‘m’ 的方法, 对其进行赋值
别名:
关键字 typedef
用法: typedef existing new;
即 typedef oldName newName;
比如给int起别名
typedefint XiaoMing;
int a = 10;
XiaoMing b =10;
int a = 10;
XiaoMing b =10;
printf("%d", a == b);
结果为1, 即表示 a == b
特殊的
给数组起名
typedef
int
MyArray[
5
];
表示 MyArray 是一个int型 容量为5的数组类型名
MyArray array = {1,2,3,4,5};
for (int i =0; i <5; i++) {
printf("%d ",array[i]);
for (int i =0; i <5; i++) {
printf("%d ",array[i]);
}
当然这种写法想来是没人会选择去用的 看不懂可无视
但是下面这种用法是很常用的:
使用typedef定义结构体
第一种方法是常规方法, 值得注意的是可以把别名取成结构体名
第二种方法则比较简洁, 但是得注意的是, 用这种方法的时候 就不能在结构体声明定义的同时声明结构体变量, 写原来结构体变量的地方被替换成了结构体的别名, 此时可以同时定义多个别名, 每个别名用逗号隔开即可
使用别名的好处
Student
st = {
"xiaoming"
,
'm'
,
21
,
20151016
,
88.0
};
书写上: 不需要再写成 struct student st = {
"xiaoming"
,
'm'
,
21
,
20151016
,
88.0
};
相比之下用别名定义简洁了许多
结构体数组
将多个结构体变量放到数组中, 构成结构体数组
形式如下:
struct student students[10] = {0};
students[0].name; // 访问第一个学生的姓名
代码如下:
Student stu1 = {"xiaoming",99,25}, stu2 = {"xiaohong",80,22}, stu3 = {"xiaogang",70,23};
Student studentArray[3] = {stu1, stu2, stu3};
// studentArray[0] == stu1 ...
// studentArray[1].age == stu2.age...
结构体数组通过将多个同一个结构体声明的结构体变量放在一个数组里, 就可以通过数组遍历的方法, 查询每个结构体变量的值
结构体数组的优点在于可以批量处理多个相同结构体的结构体变量 的某个成员
根据对比5个学生的成绩, 将成绩最高的学生的所有信息打印
Student
stu1 = {
"xiaoming"
,
99
,
25
}, stu2 = {
"xiaohong"
,
80
,
22
}, stu3 = {
"xiaogang"
,
70
,
23
}, stu4 = {
"zhaoc"
,
60
,
23
}, stu5 = {
"jinggang"
,
70
,
22
};
Student studentArray[ 5 ] = {stu1, stu2, stu3, stu4, stu5};
int score = studentArray[ 0 ]. score ;
for ( int i = 0 ; i < 5 ; i++) {
if (score < studentArray[i]. score ) {
score = studentArray[i]. score ;
}
}
for ( int i = 0 ; i < 5 ; i++) {
if (score == studentArray[i]. score ) {
printStudent (studentArray[i]); // 打印出结构体的所有成员信息
}
Student studentArray[ 5 ] = {stu1, stu2, stu3, stu4, stu5};
int score = studentArray[ 0 ]. score ;
for ( int i = 0 ; i < 5 ; i++) {
if (score < studentArray[i]. score ) {
score = studentArray[i]. score ;
}
}
for ( int i = 0 ; i < 5 ; i++) {
if (score == studentArray[i]. score ) {
printStudent (studentArray[i]); // 打印出结构体的所有成员信息
}
}
按照5个学生的成绩, 对五个学生进行排序:
for
(
int
i =
0
; i <
5
-
1
; i++) {
for ( int j = 0 ; j < 5 - 1 - i; j++) {
if (studentArray[j]. score > studentArray[j + 1 ]. score ) {
Student temp = studentArray[j];
studentArray[j] = studentArray[j + 1 ];
studentArray[j + 1 ] = temp;
}
}
}
for ( int j = 0 ; j < 5 - 1 - i; j++) {
if (studentArray[j]. score > studentArray[j + 1 ]. score ) {
Student temp = studentArray[j];
studentArray[j] = studentArray[j + 1 ];
studentArray[j + 1 ] = temp;
}
}
}
for (int i =0; i <5; i++) {
printStudent(studentArray[i]); //打印出结构体的所有成员信息
}
打印结构体成员信息的函数代码:
void printStudent(Student stu) {
printf("%s\n", stu.name);
printf("%d\n", stu.age);
printf("%d\n", stu.score);
}
printf("%s\n", stu.name);
printf("%d\n", stu.age);
printf("%d\n", stu.score);
}
结构体的字节对齐
以最大成员变量类型所占空间为分配单位,
按结构体成员声明顺序自上而下分配.
计算顺序 由上至下依次计算 一个成员变量一个成员变量的计算
并且自动补齐为 该结构体中所占最大字节的变量的字节数来进行补齐
例: 如果结构体中 最大的是float 就按 4的倍数补齐 最大的是double 就按8的倍数补齐
注: 分配空间不足以储存成员变量时, 分配新的空间单位
在结构体声明的文件添加#pragma pack(1) 取消自动字节补齐功能
结构体的嵌套使用
描述一个人与出生年月日和家庭成员
typedef
struct
dateDes {
int year;
int month;
int day;
int year;
int month;
int day;
}DateDes;
typedefstruct HomePerson {
char mother[20];
char father[20];
char mother[20];
char father[20];
}HomePerson;
typedef
struct
Person{
char
name[
20
];
DateDes date;
HomePerson home;
}
Person;
在结构中 可以有其他结构体当作成员变量 结构体中可以嵌套结构体
不过值得注意的是, 结构体中出现的其他结构体必须得是本结构体出现之前就已经声明定义过的结构体
创建这个嵌套结构体的结构体变量 代码如下:
DateDes
date = {
2015
,
10
,
18
};
HomePerson home = { "mama" , "baba" };
HomePerson home = { "mama" , "baba" };
Person person = {"xiaoming", date, home};
获得其本身名字, 获得其家人名字
printf
(
"%s\n"
, person.
name
);
printf("%s\n", person.home.father);