1、什么是结构体?
结构体就是不同类型变量组成的一个集合,我们自己可以定义的。
使用结构体至少包含两个步骤:
第一,创建一个自定义的结构体类型。(结构体声明,系统不需要给类型分配内存空间)
第二,用这个自己定义出来的类型定义结构体变量。(定义结构体, 需要分配内存空间)
2、如何声明一个结构体:
struct 结构体标签
{
成员变量1 ;
成员变量2 ;
成员变量3 ;
成员变量4 ;
......
}; // 不要漏了分号
struct my_Type //struct是结构体关键字 my_Type是结构体标签 struct my_Type是结构体类型
{
char name [ 32 ] ; //姓名
int age ; //年龄
float num ; //学号
//....
}s1,s2,s3; //s1,s2,s3这三个在这里创建的结构体变量属于是全局变量!!(一般不这样用)
int main()
{
//S这个结构体变量则是局部变量!
struct my_Type s;
}
/*创建一个结构体类型,系统是不会分配空间的。只有创建结构体变量,系统才会分配空间。!!!*/
注意:
- struct 是一个关键字, 用来说明这是一个结构体类型
- 结构体标签 ,用来区分各种不同类型的结构体
- 成员 指的是结构体内部的每一个成员的类型,可以是任意类型(也可以是一个结构体)
2.1、使用typedef 来给结构体类型重命名
Stu相当于struct Stu,Stu相当于是struct Stu的重命名。这样创建对象的时候可以直接用Stu来创建了。
创建变量的同时给可以给结构体变量进行初始化。
//利用typedef给struct Stu这个结构体类型重新起个名字叫Stu
//例如:
typedef struct Stu
{
char name[20]; //名字
short age; //年龄
char sex[5]; //性别
char id; //学号
}Stu; //注意:这个地方的Stu是一个结构体类型,而绝非是结构体变量!!!
int main()
{
Stu S1 = {"张三" , 29 ,'男' , "1712220534"}; //创建变量的同时初始化。
return 0;
}
3、嵌套结构体变量的初始化及其它的成员的访问形式
- 关于结构成员的类型
- 结构的成员可以是变量量、数组、指针,甚至是其他结构体。
#include <stdio.h>
struct Stu
{
int a;
char c;
char arr [20];
double d;
};
typedef struct Tea
{
char ch[10];
struct Stu s;
char *pc;
}Tea; //注意:这个地方的Stu是一个结构体类型,而不是结构体变量!!!
int main()
{
char arr[] = "hello World";
Tea T = {"hello" ,{123 , 'w' ,"hello struct" ,3.14} ,arr};
printf("%s\n" ,T.ch); //hello
printf("%s\n" ,T.s.arr); //hello struct
printf("%lf\n" ,T.s.d); //3.14
printf("%s\n" ,T.pc); //hello world
}
4、结构体作为函数参数传递以及结构体成员的访问
- 方法有两种:
- . : 用于应用普通类型的结构体变量引用
- -> : 用于指针类型的结构体变量引用
下面还是直接上代码说明。
#include <stdio.h>
typedef struct Stu
{
char name[100];
short age;
char tele[15];
char sex[5];
}Stu;
void printf1(Stu tmp)
{
printf("name:%s\n" ,tmp.name);
printf("age:%d\n" ,tmp.age);
printf("tele:%s\n" ,tmp.tele);
printf("sex:%s\n" ,tmp.sex);
}
//以取地址的方式传过来,那么这里Stu要用指针的类型接收
void printf2(Stu* tmp)
{
printf("name1:%s\n" ,tmp->name);
printf("age1:%d\n" ,tmp->age);
printf("tele1:%s\n" ,tmp->tele);
printf("sex1:%s\n" ,tmp->sex);
}
int main()
{
Stu s = {"李四" ,20 ,"1573454532" ,"男"};
printf1(s);
printf2(&s); //采用传地址的方式
return 0;
}
总结:
printf1();
函数参数传递其实也是一个压栈的过程。如果传递的结构体对象过大,参数压栈的1系统开销比较大,会消耗一定的时间,以及消耗一定的内存(形参是实参的一份临时拷贝)。
printf2();
采用传址的方式,速度相比于printf1();还是比较快的。同时也只是创建了一个4字节或8字节的指针变量,对比printf1来说还是节省了不少空间。
所以结构体传参的时候,可以的话还是尽量使用传结构体地址的方式。