初识结构体

目录

1.结构体是什么的,为什么要用?

2.结构体的定义与使用

3.结构体数组

4.结构体指针(重点)

5.结构体大小计算(面试宝典)

6.结构体 函数 指针 结合


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;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值