目录
1.结构体是什么的,为什么要用?
都说C语言是面向过程的语言,而结构体是C语言面向对象的方式,数组是存放同类型的集合体,而结构体是存放不同类型的集合体。
2.结构体的定义与使用
结构体的三种定义方式
1.全部赋值;2.先定义,后赋值,不需要全部赋值; 3.常用赋初值方式
如何访问结构体内的成员?
stu1.chineseScore 结构体名字.成员名
结构体相当于旧知识的集合体,只是纸老虎,多用多练不用怕!!!
#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 = 'M';
printf("c=%c\n",c);
float f = 1.2;
printf("f=%f\n",f);
double d = 3.14;
printf("d=%lf\n",d);
//char *str = "chenlichen hen shuai";//初始化可以直接用指针变量指向该字符串
char *str;//野指针 段错误
str = (char *)malloc(128);
memset(str,'/0',128);
strcpy(str,"chenlichen hen shuai");
puts(str);
void (*p)(int data)=func;
p(10);
puts("==============================");
//结构体初始化
struct Datas d1;
d1.a = 89;
d1.c = 'b';
d1.f = 5.2;
d1.d = 127.8;
strcpy(d1.str,"chenlichen bu shuai");
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(10);
system("pause");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
1.数组和结构体的区别?
数组是存放同类型的集合体,而结构体是存放不同类型的集合体
2.结构体的三种定义方式
全部赋值;先定义,后赋值,不需要全部赋值;常用赋初值方式
3.如何访问结构体内的成员?
stu1.chineseScore 结构体名字.成员名
*/
//结构体 struct(关键字)
struct Datas
{
int a;
char c;
float f;
char *p;
int array[3];
};//结构体定义时后面的分号易忘记
struct Student
{
int chineseScore;
int mathScore;
int englishScore;//成绩
char name[128]; //名字
//void (*printroduce)(char *pname);//行为(自我介绍)
};
int main()
{
struct Student stul = {98,99,69,"周星星"};//赋值方式一:全部赋值
struct Student stu2;
stu2.chineseScore = 100;
stu2.name = "周杰伦";
//strcpy(stu2.name,"周杰伦");//赋值方式二:先定义,后赋值,不需要全部赋值
//三:常用赋初值方式,多见于内核源码对结构体的定义
struct Student stu3 = {
.name = "柯南",
.chineseScore = 66,
.mathScore = 100,//此处是逗号
};//易漏分号
printf("stu1的名字是:%s,语文分数:%d\n",stul.name,stul.chineseScore);
printf("stu2的名字是:%s,语文分数:%d\n",stu2.name,stu2.chineseScore);
printf("stu3的名字是:%s,语文分数:%d\n",stu3.name,stu3.chineseScore);
return 0;
}
运行结果:
stu1的名字是:周星星,语文分数:98
stu2的名字是:周杰伦,语文分数:100
stu3的名字是:柯南,语文分数:66
为什么使用strcpy?
如果不在结构体变量初始化的时候就对具有数组类型的表达式赋值,则要使用strcpy,即不能直接赋值。
3.结构体数组
简单应用:结构体数组来玩成绩
#include <stdio.h>
#include <stdlib.h>
struct Student
{
int score;
char *name;//指针4个字节 Linux 8
};
int main()
{
int i;
struct Student stus[4];
struct Student maxStu;
struct Student minStu;
for(i=0;i<sizeof(stus)/sizeof(stus[0]);i++){
printf("请输入%d个学生的名字:\n",i+1);
stus[i].name =(char *)malloc(128);//指针开辟空间
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);
}
maxStu = minStu = stus[0];
for(i=0;i<sizeof(stus)/sizeof(stus[0]);i++){
if(maxStu.score < stus[i].score){
maxStu = stus[i];
}
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;
}
跟后面的结构体指针很像
4.结构体指针(重点)
如果用结构体指针,就不能用点运算符访问结构体的变量 要用->
#include <stdio.h>
#include <stdlib.h>
struct Student
{
int score;
char name[128];
};
int main()
{
struct Student stul;
stul.score = 100;
strcpy(stul.name,"张三");
printf("名字:%s,分数:%d\n",stul.name,stul.score);
struct Student *p;
//p.score = 100;
//如果用结构体指针,就不能用点运算符访问结构体的变量 要用->
p = (struct Student *)malloc(sizeof(struct Student));
p->score = 88;
strcpy(p->name,"李四");
printf("名字:%s,分数:%d\n",p->name,p->score);
free(p);//不会内存泄漏
p = &stul;
//指针是存放地址的变量,之前19行指向malloc的那块空间,现在存放的是stul.
printf("名字:%s,分数:%d\n",p->name,p->score);
printf("地址是%p\n",p++);
printf("加加后地址%p\n",p);
system("pause");
return 0;
}
简单应用:结构体指针来玩成绩
#include <stdio.h>
#include <stdlib.h>
struct Student
{
int score;
char *name;
};
int main()
{
int i;
struct Student stus[5];
struct Student *p = stus;
for(i=0;i<sizeof(stus)/sizeof(stus[0]);i++){
printf("请输入名字:\n");
p->name = (char *)malloc(128);
//gets(p->name);
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;
}
5.结构体大小计算(面试宝典)
#include <stdio.h>
#include <stdlib.h>
/*结构体大小计算 面试常用!!!!
原则1.结构体成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)
原则2.结构体大小必须是所有成员大小的整数倍(数组,结构体除外)
对齐方式很浪费空间 确实。 可是按照计算机的访问规则,这种对齐方式提升了效率
*/
struct S1
{
int a; //4
char c; //1
char b;//1
};
struct S2
{
char ch1;//1
int i;//4
char ch2;//1
};
struct S3
{
char ch1;//1
int i; //4
char str[12];//12 大小24
};
struct S4
{
char ch;
int i;
struct s{
int b;
char m;
double l;
}stmp;
/* struct s{
int b;
char m;
}; 后面没有变量名时不占空间!!!
*/
float f;
};
struct S5
{
char ch;
int i;
union{ //联合体 大小看最大的 4
char ch1;
int j;
};
};
struct S6
{
char ch;
int i;
float f;
double d;
};
//#pragma pack(4) 指定向4对齐
#pragma pack(10)
struct S7
{
char ch;
int i;
float f;
double d;
};
int main()
{
printf("int:%d\n",sizeof(int));
printf("char:%d\n",sizeof(char));
printf("float:%d\n",sizeof(float));
printf("double:%d\n",sizeof(double));
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;
}
运行结果:
int:4
char:1
float:4
double:8
S1:8
S2:12
S3:20
S4:32
S5:12
S6:24
S7:24
6.结构体 函数 指针 结合
#include <stdio.h>
#include <stdlib.h>
//结构体 函数 指针
struct Student
{
int score;
char *name;
};
struct Student *initStuScores(int len)
{
int i;
struct Student *p = (struct Student *)malloc(len*sizeof(struct Student));//在堆上面开辟空间,函数结束调用不会释放
for(i=0;i<len;i++){
printf("请输入人名:\n");
p->name = (char *)malloc(128);
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 *max;
max = p;
for(i=0;i<len;i++){
if(max->score < p->score){
max = p;
}
p++;
}
return max;
};
struct Student* findMinStu(struct Student *p,int len)
{
int i;
struct Student *min;
min = p;
for(i=0;i<len;i++){
if(min->score > p->score){
min = p;
}
p++;
}
return min;
};
int findSomeOneForName(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;
}
float getAverage(struct Student *p,int len)
{
int i;
int totol = 0;
for(i=0;i<len;i++){
totol += p->score;
p++;
}
return (float)totol/len;
}
int main()
{
int len = 0;
printf("请输入总人数:\n");
scanf("%d",&len);
struct Student *max = NULL;
struct Student *min = NULL;
struct Student *puts = initStuScores(len);
printMes(puts,len);
max = findMaxStu(puts,len);
min = findMinStu(puts,len);
printf("min=%s,%d\n max=%s,%d\n Average=%f\n",min->name,min->score,max->name,max->score,getAverage(puts,len));
if(findSomeOneForName(puts,len,"zhangsan") == -1){
printf("没有此人\n");
}else{
printf("恭喜你找到了张三\n");
}
system("pause");
return 0;
}