1、结构体与数组的区别
结构体和数组一样都属于构造类型,但是二者的区别在于:
数组只能由多个相同类型的数据构成,而结构体可以由多个不同类型的数据类型构成。
2、结构体的构成
格式: struct 结构体名{
数据类型变量1;
数据类型变量2;
……
}
eg:struct person { 变量; // 称为结构体变量或属性 } //根据结构体类型person,定义结构体变量,变量名为p(此阶段分配存储空间) struct person p={ }; // 赋值的时候只能在定义结构体的时候同时赋值
3、结构体变量的定义
1、先定义结构体,再定义变量struct Student{ int age; char *name; }; struct Student stu;
2、定义结构体的同时定义变量
struct Student{ int age; char *name; } stu;
3、直接定义结构体变量
struct { int age; char *name; } stu; //缺点:不能重复使用
4、结构体的初始化
1、声明变量的同时初始化struct Student{ int age; char *name; }; struct Student stu = {22, "hello"};
注意错误写法:
struct Student stu; stu={22,"hello"};//如果是一次性赋值的话,只能在初始化的时候赋值
2、先声明变量,再逐一初始化
struct Student stu; stu.age =22; stu.name ="hello";
3、定义结构体的同时进行变量定义和初始化
struct Student{ int age; char *name; } stu = {22,"hello"};
4、非顺序初始化
struct Student stu = {.name = "hello", .age = 22};
5、注意:
1)如果没有初始化结构体,所有变量会自动的有默认值。
2)定义类型的时候并没有分配存储空间,只有在定义结构体变量的时候才真正的分配存储空间。
5、内存分析
默认情况下一个结构体的存储空间的大小等于它所有成员存储空间的和,当结构体成员的类型不一致时,遵循补齐算法,即结构体所占用内存空间的大小,一定是结构体中最大成员所占用存储空间的倍数。eg:struct student { int age; char *name; }stu;
sizeof(stu)的值为16(8的倍数),因为最大的成员字节数是结构体所占的8个字节。
内存分配:定义结构体类型时不会分配内存空间,只有当赋值的时候才能分配存储空间。6、访问结构体
1、结构体变量是基本数据类型int age =stu.age; char *name= stu.name;
3、相同结构体类型变量间可以整体赋值
struct Student stu1 = {23, "hello"}; struct Student stu2 = stu1; // 把结构体变量stu1的值对应的赋值给stu2,所以stu2 = {23, "hello"}
7、作用域
定义在函数内部:从定义那一行开始,到函数或代码块结束。(跟局部变量一样)
定义在函数外部:从定义那一行开始,到程序结尾。(跟全局变量一样)8、结构体数组
eg:
struct Record{ int no; char *name; int score; }; struct Record rank[3]= { {1,"jake",500}, {2,"rose",300}, {3,"jim",100} };
结构体数组的初始化和数组的初始化一样,如果想改变数组里的内容不能直接用:
//错误写法; rank[0] = {4,"whb",900}; //正确写法 rank[0] .no=4; rank[0] .name="whb"; rank[0] .sroce=900;
9、指向结构体的指针
struct student *p; p=&stu;
有三种方法访问结构体属性:
方法1:stu.age;
方法2:(*p).age;//代表指针访问结构体中的age属性
方法3: p->age;//代表指针访问结构体中的age属性 (最常用)
eg:struct Student{ int age; char *name; }; struct Student stu = {23, "hello"}; struct Student *p = &stu; printf("%d,%s\n", stu.age, stu.name); printf("%d,%s\n", (*p).age, (*p).name); printf("%d,%s\n", p->age, p->name);
10、结构体与函数
1、结构体作为函数参数
结构体实参会把成员变量值对应的赋值给函数结构体参数对应的变量值,改变函数结构体参数不会影响到实参。struct Student{ int age; char *name; }; void test(struct Student s) { // 对结构体s的操作不会影响到stu s.age = 10; s.name = "world"; } int main() { struct Student stu = {23,"hello"}; test(stu); printf("%d, %s\n", stu.age,stu.name); return 0; }
输出:
23, hello
2、结构体指针作为函数参数struct Student{ int age; char *name; }; void test(struct Student * s) { // 对结构体s的操作会影响到stu s->age = 10; s->name = "world"; } int main() { struct Student stu = {23,"hello"}; test(&stu); printf("%d, %s\n", stu.age,stu.name); return 0; }
输出:
10, world11、结构体的嵌套
概念:在结构体中调用结构体.eg:#include<stdio.h> int main() { struct Date { int year; int month; int day; }; struct Student { int no; struct Date birthday; }; struct Student stu={1,{2008,9,20}}; printf("出生日期:%d-%d-%d",stu.birthday.year,stu.birthday.month,stu.birthday.day); return 0; }
注意:结构体的嵌套不能自己包含自己。12.枚举关键词:enum 其余定义方法和结构体一样
作用:固定变量的取值范围。enum season s = spring;//s只能四个季节中的一个,(枚举值都是整型变量,从0开始,此时spring为0,winter为4,也可以进行手工指定)enum season { spring, summer, autumn, winter,};
注:枚举类型中定义的变量只能取枚举中的属性。