文章目录
提示:以下是本篇文章正文内容,下面案例可供参考
一、结构体类型的声明
1.1结构的基础知识
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量
我们现在已经学了char、int、short、float等等类型,但是这些类型都是孤立的。
如果你想描述一个复杂对象,比如你描述一本书,书有价格、书名、作者、出版号…
为了能够描述复杂对象,就有了结构体。
而因为复杂对象有着不同的属性,所以就有了不同的成员变量,不同的成员变量可能有不同类型
1.2结构的声明
struct tag
{
member-list;//成员列表
}variable-list;//变量列表,可以有,可以没有
例如描述一本书
struct Book
{
char name[20];
char author[15];
float price;
};//这里是有一个分号的,别忘记了
1.3结构成员的类型
结构的成员可以是标量、数组、指针,甚至是其他结构体。
二、结构体变量的定义及初始化
2.1结构体的变量的定义
#include<stdio.h>
struct Book
{
char name[20];
char author[15];
float price;
}b1,b2;//可以直接在结构体后面创建(一个或多个)变量
//这里的b1,b2是全局变量,在静态区
int main()
{
//struct Book 看做一个类型
struct Book b3;//也可以在main函数里创建变量
//这里的b3是局部变量,在栈区
return 0;
}
如果你嫌每次都写 “struct 结构体名” 来创建变量麻烦,可以使用typedef来对类型重命名
typedef struct Student
{
char name[20];
int age;
char id[20];
}Stu;//把类型struct Student重命名为Stu
//Stu后面不可以再跟变量了(重命名之后就不允许有变量列表了)
int main()
{
struct Student s1;
Stu s2;//s1和s2是一个类型
return 0;
}
2.2结构体的变量的初始化
struct Student
{
char name[20];
int age;
char id[20];
};
int main()
{
struct Student s1 = {"张三",20,"2016486001"};
struct Student s2 = {"李四",19,"2016486002"};
return 0;
}
可能会遇到嵌套定义的情况,那我们初始化也需要嵌套一下
struct M
{
int a;
char b;
};
struct N
{
struct M m;
float c;
};
int main()
{
struct N t = { {1,'x'},3.14 };
return 0;
}
声明是不会占空间的,定义则会占空间。
声明就相当于造房子的图纸,而定义则是把按图纸把房子建出来。
三、结构体成员的访问
结构体变量访问成员 结构变量的成员是通过点操作符(.)访问的。
点操作符接受两个操作数。例如:
struct M
{
int a;
char b;
};
struct N
{
struct M m;
float c;
};
int main()
{
struct N t = { {1,'x'},3.14 };
printf("%d\n", t.m.a);//可以再用一次点号“.”来对里层结构体成员访问
printf("%c\n", t.m.b);
printf("%f\n", t.c);
return 0;
}
但有时,我们拿到的不是结构体本身,而是结构体的地址。
这时,如果我们想访问结构体成员怎么办?
struct M
{
int a;
char b;
};
struct N
{
struct M m;
float c;
};
int main()
{
struct N t = { {1,'x'},3.14 };
//printf("%d\n", t.m.a);//也可以再用一次点号“.”来对里层结构体成员访问
//printf("%c\n", t.m.b);
//printf("%f\n", t.c);
struct N* pt = &t;//获取结构体t的地址
//法一
printf("%d %c %f\n",(*pt).m.a, (*pt).m.b, (*pt).c);
//*pt,对pt进行解引用,就得到了t,(*pt).m就相当于t.m
//法二
printf("%d %c %f\n", (pt->m).a, (pt->m).b,pt->c);
//pt是指向结构体t的指针,m是结构体t的成员变量
//我们规定一种写法pt->m就相当于t.m
return 0;
}
四、结构体传参
请看下面代码:
struct S
{
int data[1000];
int num;
};
struct S s = { {1,2,3,4}, 1000 };
//结构体传参
void print1(struct S s)
{
printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
printf("%d\n", ps->num);
}
int main()
{
print1(s); //传结构体
print2(&s); //传地址
return 0;
}
上面的 print1 和 print2 函数哪个好些?
答案是:首选print2函数。 原因:
函数传参的时候,参数是需要压栈的。 如果传递一个结构体对象的时候,结构体过大,参数压栈
的的系统开销比较大,所以会导致性能的下降。
但是如果你传的参数仅仅是个地址,也就是4个字节(64位下8字节)啊,这个对性能来说友好很多