C语言结构体
一、什么是结构体?
结构体相当于一个类型,先在主函数前定义,之后才可使用此类型。
结构是一些值的集合,这些值成为成员变量。结构的每个成员可以是不同类型的变量。
结构体成员可以是 [标量(普通变量)、数组、指针、甚至是其他结构体]
二、结构体类型的声明
结构体声明格式
声明结构体类型的格式如下:
struct tag //struct:结构体关键字 tag:结构体标签 struct tag:结构体类型
{
member - list;//成员列表;
}variable - list;//变量列表;(在这里可以创建全局变量)但是写代码尽量不用全局变量
下面我们用具体例子来展示结构体类型声明:
e.g. 描述一个学生 – 一些数据
名字
年龄
电话
性别
//定义一个结构体类型(不占用空间)
struct stu // struct-结构体关键字 stu-结构体标签 struct stu-新创建的结构体类型
{
char name[20];//字符串,用于存汉字
int age;
char tele[12];//11位电话号+'\0'
char sex[5];
}s1,s2,s3; //s1,s2,s3;是三个[全局]的结构体变量
//结构体的[声明]是一条语句,结尾要加[;]
int main()
{
struct stu s;//创建结构体变量(向内存申请了空间)
return 0;
}
结构体的typedef
原本结构体类型名称太长,可以用typedef定义类型名字, typedef放开头 , 新名字放结尾分号前
(虽然定义了新名字但是原本的名字还是可以使用哦)
typedef struct stu
{
char name[20];
int age;
char tele[12];
char sex[5];
}stu;//新变量名
int main()
{
stu s1;
struct stu s2;
return 0;
}
三、结构体变量的定义和初始化
定义结构体时,我们可以像定义数组那样,在花括号中用逗号隔开每个成员,为对应位置的成员赋值(对成员进行初始化操作)。
结构体的定义方法如下:
typedef struct stu
{
char name[20];
int age;
char tele[12];
char sex[5];
}stu1;
int main()
{
struct stu s1 = { "张三",18,"11451419198","男" };
stu1 s2 = { "李四",19,"14544191981","女" };
return 0;
}
注:结构体类型里也可以包含结构体类型
具体例子如下
struct a
{
int i;
int j;
char a[14];
};
struct b
{
int num;
struct a s;
char* p;
};
int main()
{
struct b S = { 12,{2,3,"张三"},NULL };//结构体类型嵌套的初始化方法
printf("%d\n", S.num);
printf("%d\n", S.s.i);
printf("%d\n", S.s.j);
printf("%s\n", S.s.a);//结构体类型的打印
printf("%p\n", S.p);
return 0;
}
四、结构体成员访问 (.)和(->)
结构体变量访问成员时,通过点操作符(.) 和 箭头操作符(->)进行访问
点操作符(.) 接受两个操作数 : 结构体变量 . 成员名
箭头操作符(->) 的两个操作数:结构体指针 ->成员名
typedef struct S
{
char A;
int B;
char C[10];
}S;
void print1(S a)//传递结构体类型;(.)调用并打印结构体内的变量值
{
printf("%c\n", a.A);
printf("%d\n", a.B);
printf("%s\n", a.C);
}
void print2(S* pa)//传递结构体指针;(->)调用并打印结构体内变量的值
{
printf("%c\n", pa->A);
printf("%d\n", pa->B);
printf("%s\n", pa->C);
}
int main()
{
S a = { '?',233,"伞兵" };
S* pa = &a;
print1(a);
printf("\n");
print2(&a);
return 0;
}
print1 与 print2哪个好?
·print1传参,实参传递给形参时,形参是实参的一份临时拷贝,会新开辟一块空间,若结构体较大,形参占空间多,拷贝时间长
·print2传递指针,形参是地址,只传4/8字节,通过地址找到数据
·所以首选print2(传地址)
官方解释:函数传参时,参数需要压栈。如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,会导致性能下降
知识点补充:
内存:栈区+堆区+静态区
栈区:局部变量,函数的形式参数,函数调用也开辟空间
堆区:动态内存分配,malloc/free,ralloc,calloc
静态区:全局变量,静态变量