C语言–备忘
C - Struct
一、Struct-声明
- 结构体特点:包含大量变量,且对变量数据类型无要求;
- 结构体也是一种数据类型,是程序员自行定义的一种数据类型;
- 使用方法:
方法一:单独声明【较少用】
说明:每次定义一个结构体变量,结构体成员都要重新写一遍【不推荐】【只声明一个小弟,每次都要定义】
struct {
结构体成员;
}结构体变量;
//举例:定义一个 学生信息 结构体变量
struct{
int age;
int id;
float score;
char name[30];//描述学生姓名
}student1;
方法二: 先声明一个结构体数据类型 【声明一个大哥】
注意:分配内存,结构体定义放在源文件中来写;
struct student{
int age;
int id;
float score;
char name[30];//描述学生姓名
};
struct student student1;//每次都写 struct student ,很烦
struct student student2;
struct student student1,student2;
方法三: 使用Typedef 声明 【推荐】
说明:先用 Typedef 关键字给一个声明的结构体数据类型取别名,然后用别名定义结构体变量;
- 声明一:用 typedef 声明个小弟 【后面】;
typedef struct {
结构体成员;
}别名_t;
typedef struct {
int age;
int id;
float score;
char name[30];//描述学生姓名
}stu_t;
stu_t student1; // 可直接定义变量
- 声明二:用typedef 声明大哥【前面】和小弟【后面】,最全面;
typedef struct 结构体名{
结构体成员;
}别名_t;
typedef struct student{
int age;
int id;
float score;
char name[30];//描述学生姓名
}stu_t;
stu_t student1; // 可直接定义变量
- 声明三:声明+ typedef 后置;
struct student{
int age;
int id;
float score;
char name[30];//描述学生姓名
};
typedef struct student stu_t;//取别名
二、Struct初始化
方式一:可以不按顺序,不需要全部成员
(struct 结构体名)或者别名 结构体变量={
.某个成员=初始化值,
.某个成员=初始化值,
....
};
// 使用大哥
struct student student1={
.name="yujinlong",
.age=18,
.score=99.1
};
// 使用小弟
stu_t student1={
.name="yujinlong",
.age=18;
.score=99.1;
};
方式二:初始化需要按照顺序初始化
(struct 结构体名)或者别名 结构体变量={初始化};
// 使用大哥
struct student student1={18,666,100,"yujinlong"};
// 使用小弟
stu_t student1={18,666,100,"yujinlong"}; //缺陷:初始化需要按照顺序初始化
三、Struct成员访问
方式一:使用对象
- 通过 ’ . ’ 来访问结构体变量成员:
语法:结构体变量名.成员名
stu_t student1={
.name="yujinlong",
.age=18,
.score=99.1
};
printf("%s,%d,%d\n",student1.name,student1.age,student1.score);//查看
student1.name="woshichina";//GCC报错
// *name是无法修改的,已指向常量存储区
strcpy(student.name,"woshichina");//正确,需要使用string函数
方式二:使用指针
- 通过 ’ -> ’ 来访问结构体变量成员:
语法:结构体变量名->成员名 ;//可以访问内存区域;
stu_t student1={
.name="yujinlong",
.age=18,
.score=99.1
};
stu_t *p=&student1;//定义结构体指针变量p,指向student1结构体变量
printf("%s,%d,%d\n",p->name,p->age,p->score);//查看
p->age=20;
p->score=88;
strcpy(p->name,"woshichina");//正确,需要使用string函数
方式三:嵌套访问
typedef struct birthday{
int year;//年
int month;//月
int date;//日
}birthday_t;//声明结构体变量
//声明学生信息的结构体
typedef struct student{
char name[30];//姓名
int age;//年龄
birthday_t birth;//结构体嵌套
}stu_t;
int main(void)
{ //定义结构体变量
stu_t student1={ //标记初始化
.name="yujinlong",
.age=18,
.birth={
.year=2021,
.month=2,
.date=10
}
};
stu_t *p=&student1;//定义结构体指针变量p,指向student1结构体变量
printf("%s,%d,%d\n",p->name,p->age,p->birth.year,p->birth.month,p->birth.date);//查看
return 0;
}
四、函数形参和Struct
- 直接传递结构体变量,函数通过形参不能修改结构体实参;
- 直接传递结构体变量的地址,可直接修改结构体实参,代码执行效率高,只需要拷贝4字节;【推荐】
- 如果函数对结构体变量不进行修改,形参使用const 修饰;
#include <stdio.h>
typedef struct student{
char name[30];
int age;
}stu_t;
void grow(stu_t *st1)
{
st1->age++;
strcpy(st1->name,"我是"); //可以用
}
int main(void)
{
//定义一个结构体变量
stu_t student1={
.name="yujinlong",
.age=18
};
stu_t *p=&student1;//切记一定要申请变量,strcpy才能用
grow(p);//实参传递到实参,指针对应内存区域+1
}
五、字节对齐
- gcc对结构体成员编译时,默认按照4字节对齐;【ARM模式下】
对齐原理:
struct A{
char buf[2];
int val;
};
printf ("%d\n",sizeof (struct A));//8个字节
struct B{
char c;//4
short s[2];//4
int i;//4
};
printf ("%d\n",sizeof (struct B));//12个字节
总结:
本章温习结构体常见用法,复习备用;