目录
正文:
1.结构体类型的声明
1.1 结构的基础知识
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
1.2 结构的声明
struct tag //struct是结构体关键字 tag是结构体标签
{
member-list; //成员变量或成员列表
}varible-list; //变量列表(可省略)
1.3 结构成员的类型
结构的成员可以是数组、指针甚至是其他结构体;
1.4 结构体变量的定义和初始化
示例一:
#include<stdio.h>
//结构体类型的声明
struct Stu
{
char name[20];
int age;
char sex[8];
float score;
}s1,s2,s3; //s1,s2,s3是通过struct Stu类型创建的变量,是全局变量;
typedef struct Stu Stu;
//struct Stu 才是结构体类型,不能随便省略,但可以通过typedef进行重定义或重命名。
int main()
{
struct Stu s4;
struct Stu s5; //s4,s5也是结构体变量,是局部变量;
Stu s6;
return 0;
}
利用typedef进行重定义或重命名时,也可以更改为以下形式:
typedef struct Stu
{
char name[20];
int age;
char sex[8];
float score;
}Stu;
示例二:
struct Point
{
int x;
int y;
}p1 = {10,15};
struct S
{
char c;
struct Point p3;
double d;
char arr[20];
};
int main()
{
struct Point p2 = { 100,200 };
struct S ss = { 'w',{100,20 },5.5,"hello"};
return 0;
}
2.结构体成员的访问
结构体成员访问操作符:
(1). 结构体变量.结构体成员
(2)-> 结构体指针
具体操作示例如下:
#include<stdio.h>
#include<string.h>
struct Point
{
int x;
int y;
}p1 = {10,15};
struct S
{
char c;
struct Point sp;
double d;
char arr[20];
};
void print1(struct S s)
{
printf("%c\n", s.c); //打印w
printf("%d %d\n", s.sp.x, s.sp.y);
printf("%.1lf\n", s.d);
printf("%s\n", s.arr);
}
void print2(struct S* ps) //ps的内容即是ss的地址
{
printf("%c\n", ps->c);
printf("%d %d\n", ps->sp.x, ps->sp.y);
printf("%.1lf\n", ps->d);
printf("%s\n", ps->arr);
}
int main()
{
struct Point p = { 100,200 };
struct S ss = { 'w',{100,20},5.5,"hello" };
printf("%c\n", ss.c); //打印w
printf("%d %d\n", ss.sp.x,ss.sp.y);
printf("%.1lf\n", ss.d);
printf("%s\n", ss.arr);
//也可以进行赋值操作
ss.c=d;
ss.sp.x=1000;
ss.sp.y=2000;
ss.d=3.14;
strcpy(ss.arr,"world");
//strcpy可以进行字符串拷贝;
print1(ss); //打印struct S类型的变量
print2(&ss);
return 0;
}
3.结构体传参
如上述代码中print1与print2函数的实现中分别进行了结构体变量传参与结构体变量地址传参;
摘取函数调用部分如下:
//print1
void print1(struct S s)
{
printf("%c\n", s.c); //打印w
printf("%d %d\n", s.sp.x, s.sp.y);
printf("%.1lf\n", s.d);
printf("%s\n", s.arr);
}
//print2
void print2(struct S* ps)
{
printf("%c\n", ps->c);
printf("%d %d\n", ps->sp.x, ps->sp.y);
printf("%.1lf\n", ps->d);
printf("%s\n", ps->arr);
}
我们知道函数形参是对实参的一份临时拷贝,而在print1的设计中,s与ss的内容完全相同,会占用很大的一部分空间,在print2的设计中,ps只存放一个地址,占据的空间是4个或8个字节,故而print2更节省空间。
同时,函数传参时,参数是需要压栈的,如果传递的一个结构体对象的时候结构体过大,参数压栈的系统开销也就较大,会导致性能的下降。
故而首选print2函数。
所以在需要进行结构体传参的时候,优先考虑传结构体的地址。