- 1.结构体的定义
- 2.所占内存大小
- 3.用typedef来重命名
- 4.进行成员的访问
- 5.结构体的使用
- 6.练习题:对学生数组进行排序
基本数据类型 (内置类型) 原来就有 如:int double char 等等
而结构体类型 —> 自定义类型
设计一个结构体类型
struct 类型名字
{
成员列表(属性)
};
设计一个学生类型:
struct Student
{
char name[10];//名字 成员列表:可以为各种类型,如int 、double 等
int age;//年龄
int score;//分数
} ;// 注意要以分号结尾
定义结构体变量:
类型(struct Student) + 变量名称 (stu)
2.所占内存大小struct Student stu ;
类型设计时,不占内存 。
//此时不占用内存
struct Student
{
} ;
// 注意要以分号结尾
但当使用数据类型来定义变量时就占用内存
结构体大小
内存划分按照字节划分
地址访问:cpu 内存读写不是按照一个字节一个字节读取,而是按照2的整数倍来一块一块读取
内存对齐规则:
-
结构体变量的首地址,必须为结构体变量中最大数据的成员所占字节数的整数倍
-
结构体变量中每个成员的地址相对于首地址的偏移量,必须为该成员数据类型所占大小的整数倍
-
结构体变量的总大小必须为该结构体变量中最大基本数据类型所占字节的整数倍
如:结构体
struct A
{
char a;
int b;
} ;// 注意要以分号结尾
结构体所占字节为5,但根据规则 cpu会进行内存对齐,经过对齐之后结构体大小就为8字节
例子:
struct Student {
char name[10];//名字 成员列表:可以为各种类型,如int double 结构体
int age;//年龄
int score;//分数
} ;// 注意要以分号结尾
根据内存对齐规则得结构体占内存大小:
char name[10] //占10个字节 int age //占4个字节 因name最后一个存放在地址为09,不为4的倍数,则进行内存对齐,在09后加上2个字节,age的首地址存放在地址为12的位置 int score //占4个字节,score首地址存放在16 共20个字节
对于name 还可以这样设计
struct Student {
const char* name;//存放张三所在的地址(位于数据区)
int age;//年龄
int score;//分数
};
在内存上所占大小:
const char* name 占4字节 name放的为一个地址,为存放张三所在的地址(位于数据区) 共占12个字节
在使用和设计时,应优先选择所占字节更小的结构体。
3.用typedef来重命名可以用typedef来重命名,这样在之后使用时可以直接用重命名。
可以用 Student 代替 struct Student 来定义结构体变量,更加方便。
//方式一
typedef struct Student Student;
//方式二
typedef struct Student
{
const char* name;
int age;//年龄
int score;//分数
}Student;//重用名
使用:
Student str ;//代替struct Student str;
指针类型结构体进行重命名
//方式一
typedef struct Student* PStu;
//方式二
typedef struct Student
{
const char* name;
int age;//年龄
int score;//分数
}Student,*PStu;//重用名
使用:
PStu pstr = &str;//struct Student* pstr = &str;4.进行成员的访问
-
通过 . (成员访问符) 访问
stu.name;
stu.age;
stu.score; -
结构体与指针结合
Student* ptr = &s;//结构体变量指针 使之指向结构体变量s
printf(“%sn”,(*ptr).name);//1 通过解引用+ . 访问
printf(“%sn”,ptr->name);//2 通过指针的指向符来访问
定义结构体
struct Student {
const char* name;
int age;//年龄
int score;//分数
};
1.普通结构体
int main()//定义一个结构体变量 赋值 ,通过.访问 ,打印结构体的值
{
struct Student stu = {"张三",10,100};//对结构体变量stu进行初始化(赋值)
//可以通过结构体变量来进行成员的访问
printf("%sn",stu.name);
return 0;
}
运行结果:
2.数组类型结构体
int main()
{
//定义一个结构体数组,赋值 ,通过.访问 ,打印结构体的值
struct Student arr[] = {{"zs",10,100},{"ls",9,99},{"ww",11,90}};
int len = sizeof(arr)/sizeof(arr[0]);
for(int i = 0;i
printf("第%d个学生 名字:%s 年龄:%d 分数:%dn",i,arr[i].name,arr[i].age,arr[i].score);
}
return 0;
}
其中arr+1就加一个结构体的大小
运行结果:
- 要求:
按照学生成绩对学生数组进行冒泡排序(升序)
若成绩相同,按姓名(降序排序)
- 定义结构体,并重命名为Student
typedef struct Student {
const char* name;
int age;//年龄
int score;//分数
}Student;
- 通过冒泡排序来对成绩比大小,按照升序排序。排序完后再对其成绩相同的学生按照名字进行降序排序。
void BubbleSort(Student *s,int len)
{
Student ss;
for (int i = 0; i < len; i++)//对成绩进行升序排序
{
for (int j = 0; j < len - i -1; j++)
{
if (s[j].score > s[j+1].score)
{
ss = s[j];
s[j] = s[j + 1];
s[j + 1] = ss;
}
}
}
for (int j = 0; j < len-1 ; j++)//对成绩相同者进行降序排序
{
if (s[j].score == s[j + 1].score)
{
if (strcmp(s[j].name, s[j + 1].name) >= 0) { break; }
else
{
ss = s[j + 1];
s[j + 1] = s[j];
s[j] = ss;
}
}
}
}
- 测试看是否正确
int main()
{
struct Student s[] = {{"zs",10,100},{"awls",9,99},{"wa",11,99}};
int len = sizeof(s) / sizeof(s[0]);
BubbleSort(s, len);
for (int i = 0; i < len; i++)
{
printf("第%d个学生 名字:%s 年龄:%d 分数:%dn", i,s[i].name, s[i].age, s[i].score);
}
return 0;
}
运行结果:



