C语言—结构体
结构体的声明
结构的基础知识
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
结构体的定义:
struct 结构体类型的名称
{结构体的相关属性(结构的成员变量)
};struct Stu
{//成员变量char name[20];//名字int age;//年龄char id[20]; //学号
};
结构的声明
语法:
struct tag
{member-list;
}variable-list;
实例:描述一个学生
struct Stu
{//成员变量char name[20];//名字int age;//年龄char id[20];
} s1,s2;//s1和s2也是结构体变量
//s1,s2是全局变量int main()
{//s是局部变量struct Stu s ;//struct Stu类型创建的对象return 0;
}
结构成员的类型
结构的成员可以是标量、数组、指针,甚至是其他结构体。
实例:
struct B
{char c;short s;double d;
};struct Stu
{//成员变量struct B sb;char name[20];//名字int age;//年龄char id[20];
} s1,s2;//s1和s2也是结构体变量
//s1,s2是全局变量int main()
{//s是局部变量struct Stu s;//对象return 0;
}
结构体变量的定义和初始化
实例:
struct Point
{int x;int y;
}p1; //声明类型的同时定义变量p1struct Point p2; //定义结构体变量p2//初始化:定义变量的同时赋初值。
struct Point p3 = {x, y};struct Stu //类型声明
{char name[15];//名字int age; //年龄
};struct Stu s = {"zhangsan", 20};//初始化struct Node
{int data;struct Point p;struct Node* next;
}n1 = {10, {4,5}, NULL}; //结构体嵌套初始化struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化
结构体成员的访问
- 结构体变量访问成员 结构变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数。 例如:
访问s的成员:
struct S s;
strcpy(s.name, "zhangsan");//使用.访问name成员
s.age = 20;//使用.访问age成员
- 结构体指针访问指向变量的成员 有时候得到的不是一个结构体变量,而是指向一个结构体的指针。例如:
struct Stu
{char name[20];int age;
};void print(struct Stu* ps)
{printf("name = %s age = %d\\n", (*ps).name, (*ps).age);//使用结构体指针访问指向对象的成员printf("name = %s age = %d\\n", ps->name, ps->age);
}int main()
{struct Stu s = {"zhangsan", 20};print(&s);//结构体地址传参return 0;
}
实例:
struct B
{char c;short s;double d;
};struct Stu
{//成员变量struct B sb;char name[20];//名字int age;//年龄char id[20];
} s1,s2;//s1和s2也是结构体变量
//s1,s2是全局变量int main()
{//s是局部变量struct Stu s = { {'w', 20, 3.14}, "张三", 30, "202005034"};//对象//. ->printf("%c\\n", s.sb.c);printf("%s\\n", s.id);struct Stu* ps = &s;printf("%c\\n", (*ps).sb.c);printf("%c\\n", ps->sb.c);return 0;
}
结构体传参
实例:
struct B
{char c;short s;double d;
};
struct Stu
{//成员变量struct B sb;char name[20];//名字int age;//年龄char id[20];
};void print1(struct Stu t)
{printf("%c %d %lf %s %d %s\\n", t.sb.c, t.sb.s, t.sb.d, t.name, t.age, t.id);
}void print2(struct Stu* ps)
{printf("%c %d %lf %s %d %s\\n", ps->sb.c, ps->sb.s, ps->sb.d, ps->name, ps->age, ps->id);
}int main()
{//s是局部变量struct Stu s = { {'w', 20, 3.14}, "张三", 30, "202005034" };//对象//写一个函数打印s的内容print1(s);print2(&s);return 0;
}
注:print1和print2函数的功能一样,首选print2函数。 因为函数传参的时候,参数是需要压栈的。 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。
总结: 结构体传参的时候,要传结构体的地址。
补充:
- 栈是一种数据结构。栈的特点是先进后出、后进先出
- 给栈中放数据的操作—压栈 ;从栈中拿数据的操作—出栈
- 每个函数调用都会在内存的栈区上开辟一块空间
- 函数传参通常(大部分情况下、绝大部分编译器(编译器设计))情况下传参顺序是参数是从右向左传参的
- 函数传参也是压栈操作
- 函数调用参数压栈: