【c语言】结构体
1.结构体的声明
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。数组:一组相同类型元素的集合
为什么出现结构体?
普通的内置类型无法表示一个复杂的对象
声明:
struct tag //tag结构体自定义名{member - list ; //成员变量列表} variable - list ; //变量列表
struct Stu {
//学生的相关属性
char name[20];
int age;
char sex[5];
char tele[12];
}s3, s4;
struct Stu s6;//s6也是全局变量
typedef struct Stu {
//学生的相关属性
char name[20];
int age;
char sex[5];
char tele[12];
}Stu;
//Stu是重命名产生的新的类型
//s3,s4是结构体类型的变量——全局变量
int main() {
struct Stu s1;//struct Stu是结构体类型,s1,s2是结构体类型的变量——局部变量
struct Stu s2;
Stu s5;
return 0;
}
结构体成员变量类型:
结构的成员可以是标量、数组、指针,甚至是其他结构体。
#include <stdio.h>
struct B {
int a;
char b;
};
struct S {
//结构体局部变量类型
char c;
int num;
int arr[10];
double* p;
struct B sb;//结构体嵌套初始化
struct B* pb;
};
int main() {
//初始化
double d =3.14;
//按照顺序初始化
struct S s = {'a',10,{1,2,3},&d,{1,'q'},NULL};
//指定成员初始化
struct S s1 = {.num = 1000,.arr = {1,2,3}};
//NULL需要包含头文件
return 0;
}
2.结构体成员的访问以及结构体的传参
结构体变量.成员名
结构体指针->成员名
#include <string.h>
#include <stdio.h>
struct S {
char name[20];
int age;
};
//void set_s(struct S t) {
// //t.name = "zhangsan"; //error:name是数组名,是首元素的地址,是一个常量,不能存储数据
// strcpy(t.name, "zhangsan");//字符串拷贝:strcpy(目标空间,source);
// t.age = 18;
//}
error:形参是实参的一份临时拷贝,不能通过形参传变量名直接改变实参
void set_s(struct S* p) {
/*strcpy((*p).name, "zhangsan");
(*p).age = 18;*/
//简化:
strcpy(p->name, "zhangsan");
p->age = 18;
}
void print_s(struct S t) {
printf("%s %d\n", t.name, t.age);
}
int main() {
struct S s = { 0 };
//写一个函数给s中存放数据
//set_s(s);//error
set_s(&s);
//改变实参——只能传地址
//写一个函数打印s中的数据
print_s(s);
//不改变实参
//可以传地址,也可以传结构体变量
return 0;
}
注意:
结构体传参的时候,要传结构体的地址。函数传参的时候,参数是需要压栈的。如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。而传递地址,只需要为形参开辟4/8字节,效率更高。