C语言-结构体(一)
1、结构体的声明
结构体的基础只是
- 结构体是一些值的集合,这些值成为成员变量,结构的每一个成员可以是不同类型的变量。
结构的声明
struct tag{
member-list;
}variable-list;
数组:一组相同类型的元素的集合。
结构体:也是一些值的集合,但是值的类型可以不同
struct B{
char c;
short s;
double d;
};
struct Stu{ //类型 java 类
//结构体的成员变量
char name[20];//名字
int age;//年龄
char id[20];
}s1,s2;//s1和s2也是结构体变量,这是第二种new的方式,且是全局的
//s1,s2是全局变量
int main(){
struct B sb;
//s是局部变量
struct Stu s;//对象 --java实体类
return 0;
}
结构体成员的类型
结构体的成员可以是标量,数组,指针,甚至是其他结构体
结构体变量的定义和初始化
有了结构体类型,那如何定义变量,起始很简单
//结构体的定义或者初始化就是赋值
struct B{
char c;
short s;
double d;
};
struct Stu{ //类型 java 类
//结构体的成员变量
struct B sb;
char name[20];//名字
int age;//年龄
char id[20];
}s1,s2;//s1和s2也是结构体变量,这是第二种new的方式,且是全局的
//s1,s2是全局变量
int main(){
//s是局部变量
struct Stu s = {{'w',20,3.14},"张三",30,"20202222"};//对象 --java实体类
return 0;
}
struct Node{
int data;
struct Point p;
struct Node* next;
}n1 = {10,{4,5},NULL}; //及沟通嵌套初始化
struct Node n2 = {20,{5,6},NULL};//结构体嵌套初始化
结构体成员的访问
- 结构体变量访问成员 结构体变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数。例如:
struct Stu
{
char name[20];
int age;
};
struct Stu s;
int main(){
//s是局部变量
struct Stu s = {{w,20,3.14},"张三",30,"2122121"};//对象
//. ->
printf("%d\n", s.sb.c);
printf("%d\n",s.id);
struct Stu* ps = &s;
printf("%c\n",(*ps).sb.c);
printf("%c\n",ps->sb.c);//要用箭头必须是指针,这里sb不是指针
return 0;
}
结构体传参
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 print(struct Stu* ps){
printf("%c %d %lf %s %d %s\n",sp->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,"2122121"};//对象
//写一个函数打印s的内容
print1(s); //传值调用,传变量本身
print(&s); //传址调用,传递的是指针
return 0;
}
上面的print1和print函数那个更好些
答案是:首选print函数。原因
函数传参的时候,参数是需要压栈的,如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销较大,所以导致性能的下降。
结论:结构体传参的时候,要传结构体的地址。
函数调用的参数压栈
栈:是一种数据结构,遵循后进先出的原则
压栈:
int Add(int x,inty){
int z = 0;
z = x + y;
return z;
}
int main(){
int a = 3;
int b = 5;
int c = 0;
c = Add(a,b);
return 0;
}
/**
每一个函数调用
都会在内存的栈区上
开辟一块空间!
栈区划出一块空间给mian函数,
main函数在这块空间中规划空间的使用。
将变量等压栈完成后按照顺序,调用函数,
栈区为调用函数Add创建一块内存空间,通常情况下编译器是由右向左传参的。
此时将要传递的数据赋值一份压栈进新的空间,再开辟空间给Add函数
调用完成销毁空间
*/
上
开辟一块空间!
栈区划出一块空间给mian函数,
main函数在这块空间中规划空间的使用。
将变量等压栈完成后按照顺序,调用函数,
栈区为调用函数Add创建一块内存空间,通常情况下编译器是由右向左传参的。
此时将要传递的数据赋值一份压栈进新的空间,再开辟空间给Add函数
调用完成销毁空间
*/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wiEc7EvP-1679641275681)(C语言-结构体(一)].assets/image-20230324145741173.png)