1、结构体类型的申明
2、结构体初始化
3、结构体成员访问
4、结构体传参
结构体类型申明:结构是一些值的集合,这些值称为结构成员变量。成员变量类型可以是不同的。
#include<stdio.h>
struct tag
{
char name[20];//member-list
int age;//member-list
char tellnumber[12];//member-list
char sex[5];//member-list
}s1,s2,s3;//variaber-list,s1,s2,s3是全局结构变量。
int main()
{
struct tag s;//s是局部的结构体变量
return 0;
}
variaber-list 变量列表; struct-结构体关键字;tag-结构体标签;struct tag-定义了结构体类型(类似int、char、float等,不占内存空间,只有在定义变量时才给出内存空间);struct tag s-创建结构体变量s;
#include<stdio.h>
typedef struct stu//将结构体类型重新命名为stu
{
char name[20];
int age;
char tellnumber[12];
char sex[5];
}stu;
int main()
{
stu s1={"zhangsan",18,"15528204052","man"};//结构体变量初始化。
}
结构成员类型可以是:标量、变量、数组、指针、结构体。
2、结构体变量的定义与初始化
#include<stdio.h>
struct point
{
int x;
int y;
}p2;//结构类型定义与变量p2定义。
int mian()
{
struct point p1;//定义结构体变量p1
}
//或者
struct point p3={x,y};
若一个结构体类型里包含另外一个结构体类型,那怎么初始化,看下面例子:
#include<stdio.h>
struct S
{
int a;
char c;
char arr[10];
double d;
};
struct T
{
char ch[10];
struct S s;
char *pc;
};
int main()
{
char arr[]="hello world\n";
struct T t={"hehe",{100,'w',"hello davie",3.14},arr};//嵌套结构体初始化
printf("%s\n",t.ch);//hehe
printf("%s\n",t.s.arr);//hello davie
printf("%lf\n",t.s.d);//3.14
return 0;
}
3.结构体成员的访问 :结构体变量.结构体成员名 指针变量->结构体成员名
#include<stdio.h>
typedef struct stu//将结构体类型重新命名为stu
{
char name[20];
int age;
char tellnumber[12];
char sex[5];
}stu;
void print1(stu tmp)//传参结构:结构体标签+结构体变量名
{
printf("%s\n",tmp.name);//用新建的结构体变量名去访问结构体成员
printf("%d\n",tmp.age);
printf("%s\n",tmp.tellnumber);
printf("%s\n",tmp.sex);
}
void print2(stu* ptr)
{
printf("%s\n",ptr->name);//指针访问成员->,用箭头
printf("%s\n",ptr->age);
printf("%s\n",ptr->tellnumber);
printf("%s\n",ptr->sex);
}
int main()
{ //初始化:结构体标签+结构体变量名
stu s={"zhangsan",40,"15528204052","man"};
print1(s);//结构体传参,把结构体变量s传入函数print1里面,采用传值的形式。
print2(&s);//结构体传参,把结构体变量s传入函数print2里面,采用传址的形式。
return 0;
}
上述两种传参形式肯定是传地址形式要好一点,形参是实参的临时拷贝,若采用传值的形式,内存将开辟临时空间,而传地址只需开辟4个字节的空间存放指针变量,内存利用率上更好。(传参过程实际上是压栈操作)。
4.结构体自引用:比如链表结点的创建
#include<stdio.h>
struct Node
{
int data;
struct Node* nxet;//结构体要能够找到同类型的结构体,用指针串联起来
};
5.类型重命名:
#include<stdio.h>
typedef struct Node
{
int data;
struct Node* next;
}Node;
int main()
{
Node n1;
}
7.结构体内存对齐:
#include<stdio.h>
struct S1
{
char c1;
int a;
char c2;
};
struct S2
{
char c1;
char c2;
int a;
};
int main()
{
struct S1 s1={0};
printf("%d\n",sizeof(s1));
struct S2 s2={0};
printf("%d\n",sizeof(s2));
return 0;
}//打印结果为12和8
内存对齐以空间换时间、在写code时应尽量让占用空间小的成员集中在一起。
7.1结构体内存对齐之修改默认对齐数:预处理命令 #pragma。
#include<stdio.h>
#pragma pack(4)//设置默认对齐数为4
struct s
{
double d;
int a;
};
#pragma pack()//取消设置的默认对齐数。
int main()
{
printf("%d\n",offsetof(struct s,d));//offsetof(structName,memberName)计算结构体成员偏移量
printf("%d\n",offsetof(struct s,a));//offsetof是宏,不是函数
return 0;
}
offsetof(structName,memberName)