结构体struct
C语言中,结构体类型属于一种构造类型(其他的构造类型还有:数组类型,联合类型)。
为什么要有结构体?
在实际问题中,一组数据往往有很多种不同的数据类型。例如,登记学生的信息,可能需要用到 char型的姓名,int型或 char型的学号,int型的年龄,char型的性别,float型的成绩。
使用结构体是解决多类型数据集合存放的问题
结构体声明
struct 结构名{ 成员列表 };
struct关键词表示接下来是一个结构。
struct Student{ //声明结构体
char name[20]; //姓名
int num; //学号
float score; //成绩
void (*pintroduce)(char *pname); //行为:函数指针
};
结构体定义
struct 结构体名 结构体变量名;
struct Student stu1; //定义结构体变量
结构体变量的初始化
stu1 = {"Tom", 15, 88.0};
strcpy(stu1.name, "Jack");
stu1.num = 18;
stu1.score = 90.5;
访问结构成员
结构变量名 . 成员名
stu1.name //表示学生stu1的姓名
结构体基础应用案例
#include <stdio.h>
#include <stdlib.h>
struct Student{
char name[20];
int score;
};
int main()
{
struct Student stu1 = {"木易杨",100};
printf("结构体:name = %s\n",stu1.name);
printf("结构体:score = %d\n",stu1.score);
struct Student test;
strcpy(test.name,"弓长张");
test.score = 60;
printf("test:name = %s\n",test.name);
printf("test:score = %d\n",test.score);
system("pause");
return 0;
}
执行结果:
结构体:name = 木易杨
结构体:score = 100
test:name = 弓长张
test:score = 60
结构体整合数据类型案例应用
#include <stdio.h>
#include <stdlib.h>
void func(int data)
{
printf("函数:data = %d\n",data);
}
struct Datas{
int a;
char c;
float f;
double d;
char str[128];
void (*p)(int a);
};
int main()
{
int a = 10;
printf("a = %d\n",a);
char c = 'A';
printf("c = %c\n",c);
float f = 1.2;
printf("f = %f\n",f);
double d = 3.14159;
printf("d = %lf\n",d);
char *str = "木易杨";
puts(str);
void (*p)(int data) = func;
p(20);
printf("========================\n");
struct Datas d1;
d1.a = 13;
d1.c = 'b';
d1.f = 6.5;
d1.d = 5.3435;
strcpy(d1.str,"弓长张");
d1.p = func;
printf("a = %d\n",d1.a);
printf("c = %c\n",d1.c);
printf("f = %f\n",d1.f);
printf("d = %lf\n",d1.d);
puts(d1.str);
d1.p(40);
system("pause");
return 0;
}
执行结果:
a = 10
c = A
f = 1.200000
d = 3.141590
木易杨
函数:data = 20
========================
a = 13
c = b
f = 6.500000
d = 5.343500
弓长张
函数:data = 40
结构体使用注意
要注意结构体内的指针开辟空间问题
#include <stdio.h>
#include <stdlib.h>
struct Datas
{
char *p;
};
struct Test
{
char p[128];
};
int main()
{
struct Test a;
strcpy(a.p,"木易杨");
puts(a.p);
struct Datas b;
b.p = (char *)malloc(128);
memset(b.p, '\0', 128);
strcpy(b.p,"弓长张");
puts(b.p);
system("pause");
return 0;
}
执行结果:
木易杨
弓长张
学生成绩用结构体案例
struct Student stus[3];
结构体数组
#include <stdio.h>
#include <stdlib.h>
struct Student
{
char *name;
int score;
};
int main()
{
int i;
struct Student stus[3];
for(i=0;i<sizeof(stus)/sizeof(stus[0]);i++){
printf("请输入第%d个学生的名字:\n",i+1);
stus[i].name = (char *)malloc(20);
memset(stus[i].name, '\0', 20);
scanf("%s",stus[i].name);
printf("请输入第%d个学生的分数:\n",i+1);
scanf("%d",&stus[i].score);
}
for(i=0;i<sizeof(stus)/sizeof(stus[0]);i++){
printf("第%d个学生的成绩:\n",i+1);
printf("%s:%d\n",stus[i].name,stus[i].score);
}
struct Student maxStu;
maxStu = stus[0];
struct Student minStu;
minStu = stus[0];
for(i=0;i<sizeof(stus)/sizeof(stus[0]);i++){
if(maxStu.score < stus[i].score){
maxStu = stus[i];
}else if(minStu.score > stus[i].score){
minStu = stus[i];
}
}
printf("最高分是%s分数为%d\n",maxStu.name,maxStu.score);
printf("最低分是%s分数为%d\n",minStu.name,minStu.score);
system("pause");
return 0;
}
结构体指针应用
struct Student *p;
结构体指针
1、如果用结构体指针,访问就不能用!!!点运算符!!!访问结构体中的变量 要用->
2、指针要注意是否是野指针或者NULL
#include <stdio.h>
#include <stdlib.h>
struct Student
{
char name[128];
int score;
};
int main()
{
int i;
struct Student stu1;
strcpy(stu1.name,"木易杨");
stu1.score = 100;
printf("名字:%s\n分数:%d\n",stu1.name,stu1.score);
struct Student *p = NULL;
p = (struct Student *)malloc(sizeof(struct Student));
memset(p,'\0',sizeof(struct Student));
p->score = 20;
strcpy(p->name,"弓长张");
printf("名字:%s\n分数:%d\n",p->name,p->score);
free(p);
p = &stu1;
printf("名字:%s\n分数:%d\n",p->name,p->score);
printf("p的地址是:%p\n",p++);
printf("p++后的地址是:%p\n",p);
system("pause");
return 0;
}
执行结果:
名字:木易杨
分数:100
名字:弓长张
分数:20
名字:木易杨
分数:100
p的地址是:0060FE78
p++后的地址是:0060FEFC
结构体的一个偏移量是跨过整个结构体
struct Student
{
char name[128];
int score;
};
name = 128 score = 4
DEC:0060FEFC - 0060FE78 = 132
结构体数组跟结构体指针统合应用
p = stus;
把结构体数组的首地址给到指针
(*p).name;
取结构体指针内容,在选结构体内的元素
学生成绩录入案例:
#include <stdio.h>
#include <stdlib.h>
struct Student
{
char *name;
int score;
};
int main()
{
int i;
struct Student stus[3];
struct Student *p = stus;
for(i=0;i<sizeof(stus)/sizeof(stus[0]);i++){
printf("请输入姓名:\n");
p->name = (char *)malloc(20);
memset(p->name,'\0',20);
scanf("%s",(*p).name);
printf("请输入分数:\n");
scanf("%d",&(p->score));
p++;
}
p = stus;
for(i=0;i<sizeof(stus)/sizeof(stus[0]);i++){
printf("名字:%s,分数:%d\n",p->name,p->score);
p++;
}
system("pause");
return 0;
}
学生成绩录入全结构体指针操作
#include <stdio.h>
#include <stdlib.h>
struct Student
{
char *name;
int score;
};
int main()
{
int i;
int len = 0;
printf("选择要录入的人数:\n");
scanf("%d",&len);
struct Student *p = (struct Student *)malloc(len*sizeof(struct Student));
for(i=0;i<len;i++){
printf("请输入姓名:\n");
p->name = (char *)malloc(20);
memset(p->name,'\0',20);
scanf("%s",(*p).name);
printf("请输入分数:\n");
scanf("%d",&(p->score));
p++;
}
p = p - len;
for(i=0;i<len;i++){
printf("名字:%s,分数:%d\n",p->name,p->score);
p++;
}
system("pause");
return 0;
}
结构体指针结合函数应用
#include <stdio.h>
#include <stdlib.h>
struct Student
{
char *name;
int score;
};
int initNumber(int len)
{
printf("选择要录入的人数:\n");
scanf("%d",&len);
return len;
}
struct Student* initStuScore(struct Student *p,int len)
{
int i;
p = (struct Student *)malloc(len*sizeof(struct Student));
for(i=0;i<len;i++){
printf("请输入姓名:\n");
p->name = (char *)malloc(20);
memset(p->name,'\0',20);
scanf("%s",(*p).name);
printf("请输入分数:\n");
scanf("%d",&(p->score));
p++;
}
return p - len;
}
void printMes(struct Student *p,int len)
{
int i;
for(i=0;i<len;i++){
printf("名字:%s,分数:%d\n",p->name,p->score);
p++;
}
}
struct Student* findMaxStu(struct Student *p,int len)
{
int i;
struct Student *maxStu;
maxStu = p;
for(i=0;i<len;i++){
if(maxStu->score < p->score){
maxStu = p;
}
p++;
}
return maxStu;
}
struct Student* findMinStu(struct Student *p,int len)
{
int i;
struct Student *minStu;
minStu = p;
for(i=0;i<len;i++){
if(minStu->score > p->score){
minStu = p;
}
p++;
}
return minStu;
}
float getAverage(struct Student *stus,int len)
{
int i;
float average;
for(i=0;i<len;i++){
average += stus->score;
stus++;
}
return (float)average/len;
}
int main()
{
int i;
int len = 0;
struct Student *stu = NULL;
struct Student *max = NULL;
struct Student *min = NULL;
float average;
len = initNumber(len);
stu = initStuScore(stu,len);
printMes(stu,len);
max = findMaxStu(stu,len);
min = findMinStu(stu,len);
average = getAverage(stu,len);
printf("%s最高分:%d\n%s最低分:%d\n平均分:%f\n",max->name,max->score,min->name,min->score,average);
system("pause");
return 0;
}
字符串对比:
int findForName(struct Student *p,int len,char *name)
{
int i;
for(i=0;i<len;i++){
if(strcmp(name,p->name) == 0){
return 1;
}
p++;
}
return -1;
}
if(findForName(stu,len,"wang") == -1){
printf("查无此人\n");
}else if(findForName(stu,len,"wang") == 1){
printf("找到了\n");
}
结构体对齐计算方式
1、结构体成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍) 2、结构体大小必须是所有成员大小(不考虑数组,结构体内部的结构体)的整数倍 3、对齐方式会很浪费空间,但按照计算机的访问规则,这种对齐方式提升了效率
#pragma pack(4)
- 指定向4对齐,最大是8
- 指定一般只能写一个,多个就按第一个来
- 成员小于限制,则按最大的来,成员大于限制则按限制来对齐
struct s6
{
char ch;
int i;
float f;
double d; //20--24
};
#include <stdio.h>
#include <stdlib.h>
struct s1
{
char ch1;
char ch2;
int i;
};
struct s2
{
char ch1;
int i;
char ch2;
};
struct s3
{
char ch;
int i;
char str[10];
};
struct s4
{
char ch;
int i;
struct s{
char ch1;
int j;
};
float f;
};
struct s5
{
char ch;
int i;
union{
char ch1;
int j;
};
};
struct s6
{
char ch;
int i;
float f;
double d;
};
#pragma pack(10)
struct s7
{
char ch;
int i;
float f;
double d;
};
int main()
{
printf("计算变量大小\n");
printf("char:%d\n",sizeof(char));
printf("int:%d\n",sizeof(int));
printf("float:%d\n",sizeof(float));
printf("double:%d\n",sizeof(double));
printf("计算结构体变量大小\n");
printf("s1:%d\n",sizeof(struct s1));
printf("s2:%d\n",sizeof(struct s2));
printf("s3:%d\n",sizeof(struct s3));
printf("s4:%d\n",sizeof(struct s4));
printf("s5:%d\n",sizeof(struct s5));
printf("s6:%d\n",sizeof(struct s6));
printf("s7:%d\n",sizeof(struct s7));
system("pause");
return 0;
}
执行结果:
计算变量大小
char:1
int:4
float:4
double:8
计算结构体变量大小
s1:8
s2:12
s3:20
s4:12
s5:12
s6:24
s7:24
typedef关键字
typedef typedef 为C语言的关键字 作用是为一种数据类型定义一个新名字 这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)
和struct来匹配,为了代码编写的简洁 和普通类型匹配,通过名字来获取一些信息
#include <stdio.h>
#include <stdlib.h>
typedef unsigned char u_int8;
typedef unsigned short int u_int16;
typedef unsigned int u_int32;
typedef struct Student
{
char *name;
int score;
void (*p)(struct Student stu);
}STU,*PSTU;
typedef struct
{
char *name;
int score;
}STUS,*PSTUS;
typedef struct Node
{
int data;
struct Node* next;
}NODE,*PNODE;
int main()
{
u_int8 data = 10;
u_int16 data2 = 20;
u_int32 data3 = 40;
unsigned short int data4 = 70;
printf("%d, %d, %d, %d\n",data,data2,data3,data4);
struct Student stu1;
stu1.score = 100;
printf("stu1:score = %d\n",stu1.score);
STU stu2;
stu2.score = 50;
printf("stu2:score = %d\n",stu2.score);
struct Student *pstus;
pstus = (struct Student *)malloc(sizeof(struct Student));
pstus->score = 79;
printf("pstu:score = %d\n",pstus->score);
PSTU pstu;
pstu = (PSTU)malloc(sizeof(STU));
pstu->score = 99;
printf("pstu:score = %d\n",pstu->score);
system("pause");
return 0;
}
|