结构体struct
1.声明结构体
struct 结构体名
{
成员表列;
};
#include<stdio.h>
struct data
{
int year;
int month;
int day;
}; //一定记得这个 ;分号
在声明结构体时,允许嵌套结构体(上文声明过的结构体)
#include<stdio.h>
struct data
{
int year;
int month;
int day;
};
struct student
{
int num;
char name[16];
char sex;
struct data days; //结构体嵌套结构体
float score;
};
使用时必须要有struct跟在前面
int main()
{
struct student stu1,stu2;
return 0;
}
※结构体占内存大小
1.地址对齐数
在分配内存时,一次划分多少个字节
char 1
short 2
int 4
float 4
double 4(32位) 8(64位);;测试发现:二者都是8,有待探讨
在结构体成员分配内存时,地址对齐数一旦上升就不会下降
2.基准点+偏移量
基准点:结构体首地址
偏移量:基于基准点向后偏移多少字节
最终的结构体占用内存大小需要符合以下两点:
条件1、结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)。
条件2、结构体大小必须是最大内存地址对齐数的大小的整数倍。
#include<stdio.h>
struct A
{
int a;
char b;
int c;
};
struct B
{
char a;
int b;
char c;
};
struct C
{
char a;
char b;
int c;
};
struct D
{
char a;
int b;
char c;
short d;
};
struct E
{
short a;
short b;
char c;
char d;
};
int main()
{
printf("The A is %d\n",sizeof(struct A));
printf("The B is %d\n",sizeof(struct B));
printf("The C is %d\n",sizeof(struct C));
printf("The D is %d\n",sizeof(struct D));
printf("The E is %d\n",sizeof(struct E));
return 0;
}
2.定义结构体
1.先声明再定义:struct 关键字在结构体时不可省略
2.在声明结构体时直接定义
#include<stdio.h>
struct student
{
char sex;
int num;
int score;
char name[16];
}stu2;
int main()
{
struct student stu3;
return 0;
}
3.声明结构体过程中,省略结构体名,然后直接定义
struct
{
char sex;
int num;
int score;
char name[16];
}stu1;
在Jave这个叫匿名内部类
. :直接引用结构体成员运算符
如果两个结构体变量类型完全相同,结构体变量允许直接赋值
#include<stdio.h>
#include<string.h>
struct student
{
int num;
char name[16];
char sex;
};
int main()
{
struct student stu1,stu2;
stu1.num = 10101;
strcpy(stu1.name,"Jiang Tiancai");
stu1.sex = 'm';
stu2 = stu1; //直接赋值
printf("stu2.num is %d\n",stu2.num);
printf("stu2.name is %s\n",stu2.name);
printf("stu2.sex is %c\n",stu2.sex);
return 0;
}
结构体初始化
struct student stu3={10102,"Yang Gunian",'f'};
printf("stu3.num is %d\n",stu3.num);
printf("stu3.name is %s\n",stu3.name);
printf("stu3.sex is %c\n",stu3.sex);
如果出现嵌套结构体,那么必须寻找(. . .)最里面的成员才可以进行操作
3.结构体数组
一个数组里面全都是结构体
#include<stdio.h>
#include<string.h>
struct student
{
int num;
char name[16];
char sex;
};
int main()
{
struct student stu[3]={
10101,"Jiang Tiancai",'m',
10102,"Yang Guniang",'f',
10103,"Jiang Shuaige",'m'
};
int i;
for(i = 0; i<3; i++)
{
printf("第%d个人的信息:\n",i+1);
printf("The stu[%d] num is %d\n",i,stu[i].num);
printf("The stu[%d] name is %s\n",i,stu[i].name);
printf("The stu[%d] sex is %c\n",i,stu[i].sex);
printf("\n");
}
return 0;
}
例题:有三个候选人,有10个选民进行投票,每个选民只能投票给一个人,要求编写一个统计选票的程序,先后输入被选人的姓名,最后输出每个人的选票结果。
#include<stdio.h>
#include<string.h>
struct piao //定义结构体变量
{
char name[16];
int cc;
};
int main()
{
struct piao Bxr[4]={
[0]={"Jiang",0},
[1]={"Yang",0},
[2]={"Liu",0},
[3]={"Wang",0}
};
char name[16];
int i,j;
int x;
printf("请输入有多少选民:");
scanf("%d",&x);
for(i = 0; i<x;i++)
{
printf("备选人有:Jiang;Yang;Liu;Wang\n");
printf("你是选民%d你的选择是:",i+1);
scanf("%s",name);
for(j = 0; j<4; j++)
{
if(strcmp(name,Bxr[j].name)==0) //输入的数据与结构体数组的数据进行比较
{
Bxr[j].cc++;
break;
}
}
if(j>=4) //错误相应机制
{
printf("输入错误请重新输入");
i--; //通过 i-- 让循环停留在这次(相当于这次循环没有做)
}
}
printf("结果是:Jiang\tYang\tLiu\tWang\t\n");
printf("选票为:");
for(j = 0; j<4; j++)
{
printf("%d\t",Bxr[j].cc);
}
printf("\n");
return 0;
}
例题:有五个人学生的成绩信息如下:
1011,"jiang",100,
1013,"li",78,
1012,"Yang",99,
1015,"Hu",89,
1014,"Liu",95 先按照学号从小到大输出,再按照分数从大到小输出(使用冒泡排序)
#include<stdio.h>
struct student
{
int num;
char name[24];
float score;
};
void print(struct student stu[],int len) //输出函数
{
int i;
printf("学号\t姓名\t成绩\n");
for(i = 0; i<len; i++)
{
printf("%d\t%s\t%.2f\n",stu[i].num,stu[i].name,stu[i].score);
}
}
void bubble_num(struct student stu[],int len) //按照学号从小到大排序
{
int i,j;
struct student tmp; //交换时不能只交换学号,而是要交换整个学生的信息
for(i = 0; i<len; i++) //冒泡排序
{
for(j = 0; j<len-i-1; j++)
{
if(stu[j].num>stu[j+1].num)
{
tmp = stu[j];
stu[j] = stu[j+1];
stu[j+1] = tmp;
}
}
}
}
void bubble_sc(struct student stu[],int len) //按照成绩从大到小排序
{
int i,j;
struct student tmp;
for(i = 0; i<len; i++)
{
for(j = 0; j<len-i-1; j++)
{
if(stu[j].score<stu[j+1].score)
{
tmp = stu[j];
stu[j] = stu[j+1];
stu[j+1] = tmp;
}
}
}
}
int main()
{ //对结构体数组的初始化
struct student stu[]={
1011,"jiang",100,
1013,"li",78,
1012,"Yang",99,
1015,"Hu",89,
1014,"Liu",95
};
int len = sizeof(stu)/sizeof(stu[0]); //计算数组的长度-->可以说是有几个结构体
bubble_num(stu,len);
print(stu,len);
printf("--------------------我是分隔符----------------------\n");
bubble_sc(stu,len);
print(stu,len);
return 0;
}
4.结构体指针
直接引用结构体成员运算符
struct student stu1;
struct student *p;
p = &stu1;
(*p).number = 10101;
间接引用结构体成员运算符(语法糖)
(*p).number <--> p->number
结构体指针与malloc()应用
可以创建一种,一次创建一个结构体,不会出现空间多余或缺少的情况
二者可以结合构成链表(数据结构详细说明)
用户重命名数据类型
typedef
typedef 旧类型 新类型
typedef unsigned int uint32
uint32 a,b,c; <==> unsigned int a,b,c;
函数指针的重命名方法