结构体
结构体的含义
-
自定义的数据类型
-
它是由很多的数据组合成的一个整体,结构型数据
-
其中的每一个数据,都是结构体的成员
书写的位置:
函数的里面:局部位置,只能再本函数中使用
函数的外面:全局位置,在所有的函数中都可以使用
#include<stdio.h> #include<string.h> struct myFriend { char name[100]; int age; char gender; double height; }; int main() { struct myFriend f1; //因为这步是要把现定义的字符串传入字符数组,所以使用strcopy函数 strcpy(f1.name,"刘慧玲"); f1.age = 19; f1.gender = 'F'; f1.height = 1.63; printf("我朋友的名字是%s\n",f1.name); printf("我朋友的年龄是%d岁\n",f1.age); printf("我朋友的性别是%c\n",f1.gender); printf("我朋友的身高是%.2f米\n",f1.height); return 0; }
结构化数组代码案例(3种方式)
直接定义结构体数组
#include<stdio.h> #include<string.h> struct student { char name[100]; int age; }; int main() { //定义student型变量并传入实参 struct student st1 = {"张三",18}; struct student st2 = {"李四",19}; struct student st3 = {"王五",20}; //定义数组来接收3个student变量 struct student strArr[3] = {st1,st2,st3}; int i; for(i=0;i<3;i++) { printf("学生的名字为:%s;学生的年龄为:%d\n",strArr[i].name,strArr[i].age); } return 0; }
直接将三个 struct student
对象初始化到一个数组中,这在某些编译器中可能会引发类型不匹配的错误
定义结构体指针数组存放数据
#include<stdio.h> #include<string.h> struct student { char name[100]; int age; }; int main() { struct student st1 = {"张三", 18}; struct student st2 = {"李四", 19}; struct student st3 = {"王五", 20}; //定义指针数组来接收3个student变量的内存地址 struct student *strArr[3] = {&st1, &st2, &st3}; int i; for(i = 0; i < 3; i++) { //指向结构体或类对象的指针数组访问数据需使用-> //strArr[i]->name 表示访问 strArr 数组中第 i 个元素所指向的对象的 name 成员。 printf("学生的名字为:%s;学生的年龄为:%d\n", strArr[i]->name, strArr[i]->age); } return 0; }
先定义结构体数组,再依次写入数据
#include<stdio.h> #include<string.h> struct student { char name[100]; int age; }; int main() { //struct student strArr[3] = {{"张三", 18}, {"李四", 19}, {"王五", 20}}; //上面的定义效果与下面的一致,是依次初始化结构体数组中的元素 struct student strArr[3]; int i; strcpy(strArr[0].name, "张三"); strArr[0].age = 18; strcpy(strArr[1].name, "李四"); strArr[1].age = 19; strcpy(strArr[2].name, "王五"); strArr[2].age = 20; for(i = 0;i < 3;i++) { printf("学生的名字为:%s;学生的年龄为:%d\n", strArr[i].name, strArr[i].age); } return 0; }
起别名
代码案例
#include<stdio.h> //其中的gameRole可以省略不写 typedef struct gameRole { char name[100]; int attact; int defend; int blood; //GR就是起的别名 }GR; int main() { //定义时直接使用GR GR gr1 = {"火男",100,50,50}; GR gr2 = {"狐狸",100,40,60}; GR gr3 = {"岳山",40,80,80}; GR *grArr[3] = {&gr1,&gr2,&gr3}; int len = sizeof(grArr) / sizeof(grArr[0]); int i; for(i=0;i<len;i++) { printf("角色名字:%s;角色攻击:%d;角色防御:%d;角色血量:%d;\n",grArr[i]->name,grArr[i]->attact,grArr[i]->defend,grArr[i]->blood); } return 0; }
结构体作为函数参数
函数中可以传递结构体
代码案例(通过函数修改结构体变量内的数据)
#include<stdio.h> //定义一个结构体 typedef struct student { char name[100]; int age; }S; //因为函数中需要结构体传参,所以要声明在结构体下方,(代码自上往下依次执行) void method1(S *str); void method2(S str); int main() { //定义结构体变量 S st = {"name",0}; //调用method2函数修改结构体变量中的数据 method2(st); printf("main中调用method2修改后的的姓名:%s,年龄%d\n",st.name,st.age);//name,0;结构体数据未被修改 printf("--------------------------------------------\n"); method1(&st); printf("main中调用method1修改后的的姓名:%s,年龄%d\n",st.name,st.age);//张三,18;结构体数据已被修改 return 0; } //method1函数中是传递结构体变量的内存地址,直接指向了结构体变量,所以可以修改函数外部的数据 void method1(S *str) { printf("接收到的姓名:%s,年龄%d\n",str->name,(*str).age); printf("请输入你要更新的姓名:"); scanf("%s",(*str).name); printf("请输入你要更新的年龄:"); scanf("%d",&(str->age)); printf("method1中修改后的的姓名:%s,年龄%d\n",str->name,(*str).age); } //method2函数中是传递结构体变量的数据赋给str,str是函数内的数据,所以函数外部的数据未被修改,修改的是函数内的str void method2(S str) { printf("接收到的姓名:%s,年龄%d\n",str.name,str.age); printf("请输入你要更新的姓名:"); scanf("%s",str.name); printf("请输入你要更新的年龄:"); scanf("%d",&(str.age)); printf("method2中修改后的的姓名:%s,年龄%d\n",str.name,str.age); }
结构体嵌套
结构体中的成员是其他的结构体
代码案例
#include<stdio.h> #include<string.h> typedef struct contactWay { char phone[12]; char mail[12]; }CW; typedef struct student { char name[100]; char sex; int age; double height; CW cw; }ST; int main() { ST st1 = {"小柒",'M',19,1.78,{"15976633334","[email protected]"}}; ST st2; strcpy(st2.name,"小扒"); st2.sex = 'F'; st2.age = 19; st2.height = 1.62; strcpy(st2.cw.phone,"15979673555"); strcpy(st2.cw.mail,"[email protected]"); printf("姓名:%s,性别:%c,年龄:%d,身高:%.2lf,电话:%s,邮箱:%s\n",st1.name,st1.sex,st1.age,st1.height,st1.cw.phone,st1.cw.mail); printf("姓名:%s,性别:%c,年龄:%d,身高:%.2lf,电话:%s,邮箱:%s\n",st2.name,st2.sex,st2.age,st2.height,st2.cw.phone,st2.cw.mail); return 0; }
内存对齐:
不管是结构体,还是普通的变量都存在内存对齐
规则:
只能放在自己类型整数倍的内存地址上
简单理解: 内存地址 /占用字节 = 结果可以整除
举例:
int存放的位置:内存地址一定能被4整除
1ong 1ong存放的位置:内存地址一定能被8整除
double存放的位置:内存地址一定能被8整除
结构体的内存对齐:
结构体在上面的基础上又多了一条,结构体的总大小,是最大类型的整数倍(用来确定最后一个数据补位的情况)
切记!:对齐的时候会补空白字节,但是不会改变原本字节的大小,例:char补位之后,本身还是1个字节
定义结构体时,小的数据类型定义在上面,大的数据类型定义在下面,可以有效节约空间
代码案例
#include<stdio.h> struct ram { //内存地址从0开始 char a; //此时内存地址为0 char必须放在1的整数倍的内存地址内 0可以放 放入后就占用了0 int c; //此时内存地址为1 int必须放在4的整数倍的内存地址内 4可以放 放入后就占用了4-8 char b; //此时内存地址为9 char必须放在1的整数倍的内存地址内 9可以放 放入后就占用了9 double d; //此时内存地址为10 double必须放在8的整数倍的内存地址内 16可以放 放入后就占用了16-24 }; int main() { struct ram a; printf("%d",sizeof(a));//一共占用了24个字节 return 0; }标签:name,int,age,struct,C语言,----,str,printf,结构 From: https://blog.csdn.net/2301_80464770/article/details/141092661