目录
结构体的声明
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
struct tag //struct是结构体关键字 tag是结构体的类型名/标签
{
member-list;//成员列表
}variable-list;//变量列表
写法1:
struct Book
{
char name[20];
int price;
};
int main()
{
struct Book b1;
struct Book b2;
return 0;
}
等同于,不一样的地方在于上面的b1和b2是局部变量,下面的b1和b2是全局变量。
写法2
struct Book
{
char name[20];
int price;
}b1,b2;
int main()
{
return 0;
}
写法3
typedef struct Book
{
char name[20];
int price;
}Book;//起别名,这种情况不能再定义全局变量了
int main()
{
Book b1;
Book b2;
return 0;
}
这样写也可以
struct Book
{
char name[20];
int price;
};
typedef Book Book;
int main()
{
Book b1;
Book b2;
return 0;
}
结构成员的类型
结构的成员可以是标量(整形变量、浮字符型变量等)、数组、指针,甚至是其他结构体。
结构体的初始化
结构体成员的访问
#include <stdio.h>
struct S
{
char c;
char arr[3];
int* p;
};
struct F
{
int a;
struct S s;
double d;
};
void print(struct S* p)
{
printf("%c %s %p\n",p->c,p->arr,p->p);
}
int main()
{
struct S s4 = {'c',"ac",NULL};
struct S s5 = {.c = 'c',.arr="ac",.p=NULL};
printf("%c %s %p\n",s4.c,s4.arr,s4.p);
printf("%c %s %p\n",s5.c,s5.arr,s5.p);
//结构体变量.结构体成员
//结构体指针->结构体成员
//struct Book* p1 = &b1;
print(&s4);
return 0;
}
结构体传参
实现1
#include <stdio.h>
struct S
{
int arr[100];
int n;
};
void print(struct S s)
{
int i = 0;
for (i = 0;i < 10;i++)
{
printf("%d ",s.arr[i]);
}
printf("\n%d\n",s.n);
}
int main()
{
struct S s = {{1,2,3,4,5},100};
print(s);//这里可以看见没取地址所以要用.取地址,就要像上面在形式参数用结构体指针
return 0;
}
但这样进行传参,实参传给形参,形参会是实参的一份临时拷贝,至少101个整形,这个结构体大小至少是400个字节以上。所以这里采用值传递的话,空间浪费就会非常严重。
所以不如直接传s的地址
实现2
#include <stdio.h>
struct S
{
int arr[100];
int n;
};
void print(struct S* ps)
{
int i = 0;
for (i = 0;i < 10;i++)
{
printf("%d ",ps->arr[i]);
}
printf("\n%d\n",ps->n);
}
int main()
{
struct S s = {{1,2,3,4,5},100};
print(&s);
return 0;
}
上面的实现1和实现2函数哪个好些?
答案是:首选实现2函数。
原因:
函数传参的时候,参数是需要压栈的。 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。
结论:
结构体传参的时候,要传结构体的地址。