11.0、C语言——初识结构体
结构体的声明:
结构体的基础知识:
结构是一些值的集合,这些值称为成员变量。和数组不同的是 -> 结构体的每个成员可以是不同类型的变量
????????结构体的声明和变量的创建【例如下面结构体描述的是一个学生对象】:
struct Student{
char name[20];
short age;
char tele[12];
char sex[5];
}s1,s2,s3; //这里声明的是结构体的全局变量,但是一般我们不这么用【代码中尽可能少的使用全局变量】
//记得加上分号";"这里的分号不可缺少
int main() {
struct Student stu1;
return 0;
}
????????用 typedef 重定义结构体类型,使创建结构体类型变量时变得更为简化:
//加上typedef之后可以将struct student 简化为stu,这样用stu就可以去定义结构体类型的变量了
typedef struct student {
char name[20];
short age;
char tele[12];
char sex[5];
}Stu;
int main() {
Stu stu2;
return 0;
}
????????struct:结构体关键字 ????????student:结构体标签 ????????struct student:结构体类型
? ? ? ? stu:typedef 过后的 结构体类型
????????当我们定义一个struct结构体的时候,他不占用任何内存空间,但是当我们用结构体类型创建变量的时候才会去占用相应的内存空间
结构体成员的类型:
????????结构体的成员可以是标量、数组、指针,甚至是其他结构体
结构体变量的定义和初始化: ? ? ? ? 定义结构体的同时初始化变量:
typedef struct Student {
char name[20];
short age;
char tele[12];
char sex[5];
}Stu;
int main() {
Stu stu2 = {"小澜",22,1234567890,"男"};
printf("name = %s",stu2.name);
return 0;
}
有时候结构体中的成员变量是另一个结构体,如下:
typedef struct Pople {
char name[20];
short age;
char sex[5];
}People;
typedef struct Student {
char stuCode[20];
char university[20];
char className[20];
People p1;
}Student;
int main() {
Student stu1 = { "266523","北京清华大学","计算机软件工程",{"小澜",22,"男"} };
return 0;
}
那如何去访问结构体中类型对象的信息呢? ? ? ? ? 结构体变量访问成员 结构变量的成员是通过点操作符(" . ")访问的。点操作符接受两个操作数,如下所示:
int main() {
Student stu1 = { "266523","北京清华大学","计算机软件工程",{"小澜",22,"男"} };
printf("university = %s",stu1.university);
printf("name = %s",stu1.p1.name);
return 0;
}
那么如果我们用?传值?或者?传址?的方式去访问结构体成员变量的时候,哪一种方式更好呢?
typedef struct Student {
char stuCode[20];
char university[20];
char className[20];
}Student;
void print1(Student s) {
printf("name = %s", s.className);
}
void print2(Student* s) {
printf("name = %s",s->className);
}
int main() {
Student stu1 = { "266523","北京清华大学","计算机软件工程" };
print1(stu1);
print2(&stu1);
return 0;
}
答案是:用传址的方式更好; ????????因为如果使用传值的方式,设想一下如果我们的结构体中所有成员变量占用的内存空间为 200byte 或者 2000byte ,那么传递给形参的时候就会拷贝一份相同的数据给形参,这时候由于参数是需要压栈的,如果结构体过大,参数压栈的系统开销比较大,会导致性能下降; ? ? ? ? 但是如果传递的是地址,也就是指针变量的话,那么传递过去的就仅仅是一个4byte或者8byte的地址,占用的内存空间大大减少,不会导致空间资源的浪费
结论: ? ? ? ? 结构体传参的时候,要传结构体的地址~
再来给大家举个例子,我们执行下面这个main()函数的时候内存分配是这样的:
?
? ? ? ? 看上图右边的栈区 -> 首先申请一块空间压入栈中 -> 分配给 main() 主函数; ????????main() 函数再将得到的空间,分配给变量 a、b、ret; ????????main() 函数调用 add() 函数,并且传递两个参数给 add(),此时将这两个实参a、b -> 拷贝一份给形参 x、y; ? ? ? ? 然后给 x、y 分配一块空间压入栈中: ? ? ? ? 最后给 add() 函数分配一块内存空间,add() 再将得到的内存空间分给变量 z ,最后拿到 x、y 的值进行相加,返回结果~
|