目录
1. 结构体的声明
1.1 结构的基础知识
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。如:对于人来说,姓名,年龄,性别等就是成员变量
1.2 结构的声明
struct tag //声明一个结构体类型,并不占用空间
{
member-list;
}variable-list;
如:声明一个结构体类型 - 书:
#include <stdio.h>
#include <string.h >
//声明了一个结构体类型 - 书
/*struct Book
{
char name[20];//书名
short price; //定价
}b4,b5,b6;*/ //b4,b5,b6都是结构体变量 - 全局变量(尽量少使用全局变量)
typedef struct Book
{
char name[20];//书名
short price; //定价
}Book; //这里的Book是一种类型,而不是变量
int main()
{
//利用结构体类型创建结构体变量 - 局部变量
struct Book b1; //创建了一本书
struct Book b2;
struct Book b3;
Book b4;
Book b5;
//字符串拷贝
//把"c语言"拷贝到name数组中。因为不能直接用b.name = "c语言"来写
strcpy(b1.name, "c语言");
b1.price = 55;
printf("%s\n", b1.name);
printf("%d\n", b1.price);
return 0;
}
1.3 结构成员的类型
结构的成员可以是标量、数组、指针,甚至是其他结构体
struct B
{
int a;
char c;
};
struct S
{
int a; //标量
char arr[20];//数组
int* p;//指针
struct B sb;//结构体
};
1.4 结构体变量的定义和初始化
有了结构体类型,那如何定义变量?
struct Point
{
int x;
int y;
}p1; //声明类型的同时定义变量p1
struct 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};//结构体嵌套初始化
2. 结构体成员的访问
1. 操作符( . ) 结构体变量.成员名
2. 操作符( -> ) 结构体指针->成员名
void print1(struct Stu stu)
{
printf("%s %d\n", stu.name, stu.age);
}
void print2(struct Stu* ps)
{
printf("%s %d\n", (*ps).name, (*ps).age);//正确,但麻烦
printf("%s %d\n", ps->name, ps->age);//结构体指针->成员
}
int main()
{
struct Stu s = { "张三", 20 };
print1(s); //传值调用 stu是s的一份临时拷贝
print2(&s); //传址调用(优于传值调用)
return 0;
}
上述 print1 和 print2 函数哪个好些? 答:首选print2函数
函数传参的时候,参数是需要压栈的。 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。
对"压栈"的讲解:
任何一次函数调用都要向内存申请空间:申请的是栈空间
例如:
int Add(int c, int d)
{
int z = 0;
z = c + d;
return z;
}
int main()
{
int a = 10;
int b = 20;
int c = Add(a, b);
return 0;
}
系统栈中:
结论: 结构体传参的时候,要传结构体的地址。