C语言结构体笔记
一、为什么使用结构体
结构体是一种数据类型(不同于int、float等的数据类型),使用目的是为了储存各种不同类型的信息
二、如何声明结构体类型
1、struct的基本用法
struct 数据类型名 {成员变量; 成员变量; 成员变量;};
以储存学生的信息为例:
struct student{
int id;
char *name;
int age;
float score;
};
/*如图结构体可以存储不同类型的变量。当然,也可以暂
时不放内容,当作空结构体。如下:*/
struct student{};
2、匿名结构体
结构体也可以匿名,在大括号后面可以定义该类型的变量,例如:
struct{
int id;
char *name;
int age;
float score;
}stu1, stu2;
/*如上是匿名结构体,定义了stu1,stu2两个变量
3、用typedef定义结构体类型
一般来说,使用结构体定义变量,需在结构体类型名前加上struct,即 struct 数据类型名 变量名; 例如:
struct student{
int id;
char *name;
int age;
float score;
};
//定义一个类型名为student的变量stu1
int main(){
struct student stu1;
return 0;
}
通过typedef可以给类型取一个新的名字,简化结构体的使用。例如:
typedef struct student{
int id;
char *name;
int age;
float score;
}student;
/*上式中,将原本的struct student类型名(第一行),
转变为新类型名student(最后一行)。使用时可以直接
用student类型名定义变量。如下:*/
int main(){
student stu1;
return 0;
}
4、结构体的嵌套
结构体可以嵌套另一个结构体。例如在student结构体中嵌套Birthday结构体:
typedef struct Birthday{
int year;
int month;
int day;
}Birthday;
typedef struct student{
int id;
char *name;
int age;
float score;
Birthday birthday;
}student;
三、结构体变量
1、声明结构体变量
用typedef定义完后,结构体变量定义:
结构体类型名 变量名, 变量名;(在typedef处有示例)
2、结构体变量的赋值
赋值方法:结构体类型名 变量名{, , , ,};(大括号内的值按顺序赋予结构体内的成员变量)
typedef struct Birthday{
int year;
int month;
int day;
}Birthday;
typedef struct student{
int id;
char *name;
int age;
float score;
Birthday birthday;
}student;
//定义结构体变量
int main(){
studhent stu1={
114/*学号*/,
"阿巴阿巴"/*姓名*/,
18/*年龄*/,
514/*分数*/,
{1919/*年*/, 8/*月*/, 10/*日*/ }/*生日*/
};
return 0;
}
3、访问结构体变量(运用 . 运算符)
访问:结构体变量名.成员变量名
访问嵌套结构体:结构体变量名.嵌套结构体变量名.成员变量名
以上图代码为基础,printf函数为例(主函数中):
printf("学号:%d 姓名:%s 年龄%d 分数:%.2f\n\
生日:%d-%d-%d", stu1.id, stu1.name, stu1.age, stu1.score,
stu1.Birthday.year, stu1.Birthday.month, stu1.Birthday.day)
4、结构体作为函数参数
使用函数:函数名 (结构体类型名 结构体变量名)
仍以学生的基本信息的结构体为例,后接(省略结构体定义):
void printstu(student stu)
{
printf("学号:%d 姓名:%s 年龄%d 分数:%.2f\n\
生日:%d-%d-%d", stu.id, stu.name, stu.age, stu.score,
stu.Birthday.year, stu1.Birthday.month, stu.Birthday.day)
}
int main(){
studhent stu1={
114/*学号*/,
"阿巴阿巴"/*姓名*/,
18/*年龄*/,
514/*分数*/,
{1919/*年*/, 8/*月*/, 10/*日*/ }/*生日*/
};
printstu(student stu1);
return 0;
}
若使用指针的结构体变量,函数访问成员变量时不应用“.”运算符而是用->(减号+大于号)。
即:结构体变量名->成员变量名
访问嵌套结构体:结构体变量名->嵌套结构体变量名.成员变量名(后面的.不用改变)(为什么呢?)
void printstu(student *stu)
{
printf("学号:%d 姓名:%s 年龄%d 分数:%.2f\n\
生日:%d-%d-%d", stu->id, stu.name, stu->age, stu->score,
stu->Birthday.year, stu1->Birthday.month, stu->Birthday.day)
}
四、结构体的内存
结构体占用的字节数是:成员变量中,所占字节数最大的成员变量的字节数 x 成员变量的数量(内存对齐)。如:结构体中有4个char类型(一个字节)的成员变量和1个int类型(四个字节)的成员变量 ,则结构体占用的字节数为5*4=20(个字节)
五、结构体数组
将结构体和数组结合,可更加高效的储存读取信息。仍以学生的基本信息的结构体为例,下为代码(省略结构体定义):
void printstu(student *stu, int len)
{
//遍历数组,打印数组内每个学生的信息
for (int i=0; i<len; i++){
/*(stu+i)->成员变量,依次遍历数组里的结构体变量,
也可以用stu[i].成员变量,来实现*/
printf("学号:%d 姓名:%s 年龄%d 分数:%.2f\n\
生日:%d-%d-%d", (stu+i)->id, (stu+i).name, (stu+i)->age, (stu+i)->score,
(stu+i)->Birthday.year, (stu+i)->Birthday.month, (stu+i)->Birthday.day)
}
int main(){
//定义student类型的数组stu,其中储存了三个学生的信息
student stu[] = {
//学生1-----------------------------------
{1/*学号*/,
"阿巴阿巴1"/*姓名*/,
1/*年龄*/,
1/*分数*/,
{1/*年*/, 1/*月*/, 1/*日*/ }/*生日*/},
//学生2-----------------------------------
{2/*学号*/,
"阿巴阿巴2"/*姓名*/,
2/*年龄*/,
2/*分数*/,
{2/*年*/, 2/*月*/, 2/*日*/ }/*生日*/},
//学生3-----------------------------------
{3/*学号*/,
"阿巴阿巴3"/*姓名*/,
3/*年龄*/,
3/*分数*/,
{3/*年*/, 3/*月*/, 3/*日*/ }/*生日*/},
}
//传入stu地址,用sizeof计算stu的长度(结构体变量数)
void printstu(stu, sizeof(stu)/sizeof(stu[0]))
return 0;
}
六、后记
本笔记从b站up主:杜远超官方频道的《C语言结构体详解【干货】》学习得到,如有错误请帮忙指正。