一、结构体设计
1.1结构体-->用户自定义数据类型
结构体的基本语法:
// struct 类型名
// {
// 属性(变量的声明)
// };
struct Student {
char name[10];//成员列表(属性)
int age;
int score;
};
1.2如何定义结构体变量
int main() {
定义一个结构体变量, . 成员访问符
struct Student stu = { "zs",10,100 };
struct Student stu2;
stu2 = { "lisi",9,99 };
通过结构体变量来进行成员的访问:
printf("%s\n", stu.name);
注意: . 为成员访问符
两种定义方式:
第一种:
struct Student stu = { "zs",10,100 };
第二种:
struct Student stu2;
stu2 = { "lisi",9,99 };
二、定义一个结构体类型的数组,赋值,数据并打印(与数组指针的结合)
2.1数组和结构体的结合:
struct Student {
char name[10];//成员列表(属性)
int age;
int score;
};
struct Student arr[] = { {"zs",10,100},{"lisi",9,99},{"ww",8,88}};
struct Student arr[] = { stu,stu2,{"ww",8,88} };
int len = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < len; i++) {
printf("第%d个学生:姓名:%s 年龄:%d\n", i + 1, arr[i].name, arr[i].age);
}
2.2指针和结构体的结合:
typedef struct Student {
const char* name;
int age;
int score;
}Student, * PStu;
int main() {
Student s = {"zs",10,100};
// s.name;
//结构体和指针结合
//struct Student* ptr = &s;
PStu ptr = &s;
printf("%s\n",(*ptr).name); //1
printf("%s\n",ptr -> name); //2 1 2 效果相同 -> 指向符具有解引用功能
}
注意:
-> 指向符自带解引用功能
例题:按照学生的成绩对学生数组进行冒泡排序(升序) 若成绩相同,按照姓名(降序排序)
typedef struct Student {
const char* name;
int score;
int age;
}Student;
typedef Student ElemType;
void Swap(ElemType* a, ElemType* b) {
ElemType temp = *a;
*a = *b;
*b = temp;
}
void BubbleSort(ElemType* arr, int len) {
int flag = 0;
for (int i = 0; i < len; i++) { //趟数
flag = 0;
for (int j = 0; j < len - 1 - i; j++) {
if (arr[j].score > arr[j + 1].score) {
Swap(&arr[j], &arr[j + 1]);
flag = 1;
} //成绩相同,按照姓名 降序排序
else if (arr[j].score == arr[j + 1].score) {
if (strcmp(arr[j].name, arr[j + 1].name) < 0) {
Swap(&arr[j], &arr[j + 1]);
}
}
}
if (!flag)
break;
}
}
int main() { // ww zs lisi
Student arr[] = {
{"lisi",100,9},{"zs",100,10},{"ww",88,9}
}; // 1 2 3 4
int len = sizeof(arr) / sizeof(arr[0]);
BubbleSort(arr, len);
for (int i = 0; i < len; i++) {
printf("%s %d\n",arr[i].name,arr[i].score);
}
}
三、结构体大小
内存大小的基本单位:字节
cpu在内存中读取过程:
1、cpu在地址访问时不是一个字节一个字节进行读取的,而是成块读取,以2,4,8,的倍数字节读取内存(具体如何读取可以自己做设定)
2、平台读取地址,从偶数位置进行读取
3、不同平台内存对齐方式不一样,要统一内存对齐方式
结构体大小的计算:
1)变量首地址,必须是MIN{结构体最大基本数据类型,指定对齐方式}所占字节数的整数倍。
2)每个成员变量相对于结构体首地址的偏移量,都是MIN{该成员基本数据类型整数倍,指定对齐方式}
3)结构体总大小为结构体最大基本数据类型整数倍,指定对齐方式的整数倍
指定对齐方式:
#pragma pack(字节)对齐方式开始标记 预处理指令
##pragma pack()对齐方式结束标记 预处理指令
#pragma pack(8) 按照8字节进行内存对齐
结构体的嵌套
不属于基本数据类型,而属于自定义的数据类型
例:
当两个结构体嵌套时 char ca;为了使得自己是下一个数据类型的整数倍所以需要添加7个字节的空余位置来满足自己是下一个数据类型的整数倍
但将struct B中的元素替换至Student内,它的运算结果变为了16
7