AutoLeaders控制组——C语言结构体的学习笔记

复合类型(自定义类型)目录

1.结构体

1.1概述

2结构体的定义和使用

3.结构体数组

4.开辟堆区空间存储结构体

5.结构体嵌套结构体

6.结构体与指针

6.1结构体成员为指针类型

6.2结构体指针

6.3开辟指针的堆区内存

 7.结构体做函数参数

7.1结构体普通变量做函数参数

7.2结构体指针变量做函数参数

7.3结构体数组名做函数参数

7.4const修饰的结构体指针与二级指针

2.(共用体)联合体

3.枚举

4.typedef


1.结构体

1.1概述

数组:描述一组具有相同类型数据的有序组合,用于大量相同类型的数据运算。

有时候我们需要将不同类型的数据组合成一个有机的整体,如一个学生有学号,姓名,年龄……等属性,显然单独定义以上变量比较繁琐,数据不便于管理。

C语言给出了另一种构造数据类型——结构体。

结构体基本概念:结构体属于用户自定义的数据类型,允许用户存储不同的数据类型。

2结构体的定义和使用

通过结构体创建变量的方式有三种:

(1)struct+结构体名+变量名 

(2)struct+结构体名+变量名 ={成员1值,成员2值}

(3)定义结构体时顺便创建变量 

三种创建方式示例:

#include<stdio.h>
#include<string.h>
struct student {
	char name[20];
	int age;
	int score;
}stu3={"丽丽",17,88};             //创建方式3:定义结构体时顺便创建变量stu3
int main(){
	struct student s1;    //创建方式1:struct+结构体名+变量名
	//拷贝赋值 
	strcpy(s1.name,"李四");    //使用用一个"."进行赋值 
    s1.age = 18 ;
    printf("名字:%s  年龄:%d\n",s1.name,s1.age);
    //创建方式2:struct+结构体名+变量名 ={成员1值,成员2值}
    struct student s2 ={"小米",19,100};       
    printf("名字%s 年龄%d 成绩%d\n",s2.name,s2.age,s2.score);    
	printf("名字%s  年龄%d  成绩%d\n",stu3.name,stu3.age,stu3.score);      
    return 0;
}

示例:结构体的录入

#include<stdio.h>
struct student {
	char name[20];
	int age;
	int score;
	char addr[20];
};
int main(){
	struct student s;
	//注意数组不用取地址,数组变身可表示地址; 
	scanf("%s %d %d %s",s.name,&s.age,&s.score,s.addr);
	printf("名字:%s 年龄%d 成绩%d  地址%s",s.name,s.age,s.score,s.addr);
	return 0;
}

3.结构体数组

作用:将自定义的结构体放入到数组中方便维护

语法:struct 结构体名 数组名{元素个数}={ {},{},{} ,{}…… {}  }

示例

#include<stdio.h>
#include<string.h> 
struct student{    //无sss 
	char name[20];
	int age;
};
int main(){
	//数组
	struct student sss[3]={      //struct student是数据类型 
		{"张三",22},
		{"李四",21},        //记得得有逗号 
		{"王五",25}
	};
	//可修改
	strcpy(sss[2].name,"老六"); 
	int i; 
	for(i = 0; i<3;i++){
	    printf("姓名%s 年龄%d\n",sss[i].name,sss[i].age);    
       //sss才是一个数组,不能把[i]写到name后面 
   }
	printf("结构体数组大小:%d\n",sizeof(sss));     //300
	printf("结构体元素大小:%d\n",sizeof(sss[0]));  //100
	printf("结构体元素个数:%d\n",sizeof(sss)/sizeof(sss[0]));   //3
   return 0;
}

结构体数组冒泡排序:形式改变,原理一样。

同理可以用sizeof(sss)/sizeof(sss[0])表示元素个数。

#include<stdio.h>
#include<string.h> 
struct student{   
	char name[20];
	int age;
};
int main(){
		//数组
	struct student sss[5]={     
		{"张三",22},
		{"李四",21},         
		{"王五",25},
		{"老六",27},
		{"老李",18}
		};
	int i,j;
	int len=sizeof(sss)/sizeof(sss[0]);
	for(i=0;i<len;i++){
		for(j=0;j<len-1-i;j++){
			if(sss[j].age>sss[j+1].age){
				int temp =sss[j].age ;
				sss[j].age =sss[j+1].age ;
				sss[j+1].age =temp;
			}
		}
	}
	for(i = 0; i<len;i++){
	    printf("姓名%s 年龄%d\n",sss[i].name,sss[i].age);     }
   return 0;
}

4.开辟堆区空间存储结构体

在结构体使用malloc

拓展:malloc使用相关

1、要有头文件#include<stdlib.h>

2、格式 数据类型  变量=(数据类型*)malloc(需要空间个数*字节大小);

例子:int *a =(int*)malloc(number*sizeof(int)); 

3、申请的空间大小以字节为单位,返回的结果是void*,需要自行转换,如加(int*)

4、最后空间用完返回值为0或者NULL ,则可以结合while语句使用。

5、 向malloc申请空间,需要归还 ,在使用后加free(变量);

 示例:

#include<stdio.h>
#include<stdlib.h>  //使用malloc加头文件
typedef struct student ss;   //起别名,简化
struct student{     
	char name[20];
	int age;
};
int main(){                           //区别于之前的是栈区数组 
	ss* p=(ss*)malloc(sizeof(ss)*3);   //此数组存于堆区
	int i;
    for(i=0;i<3;i++){
    	scanf("%s %d",p[i].name,&p[i].age);
	}	
	for(i=0;i<3;i++){
    	printf("姓名%s 年龄%d\n",p[i].name,p[i].age);
	}
	free(p);
	return 0; 
}

5.结构体嵌套结构体

作用:结构体成员可以是另一个结构体

例如:结构体学生,内部结构体是其分数

#include<stdio.h>
struct score{
	int yuwen;
	int shuxue;
};
struct student{    
	int age;
	char name[20];   //定义字符串用数组
	struct score ss;   
};
int main(){
	struct student a={22,"张三",100,98};     
	printf("年龄%d 姓名%s 语文%d 数学%d\n",a.age,a.name,a.ss.yuwen,a.ss.shuxue);
	//计算字节大小 
	printf("%d\n",sizeof(a));    //32=4+20+8
	printf("%d\n",sizeof(a.ss));   //8 =4+4
	printf("%d\n",sizeof(a.ss.shuxue));    //4
	printf("%d\n",sizeof(struct student));  //32
	return 0;	
}

6.结构体与指针

6.1结构体成员为指针类型

结构体成员为指针,直接用strcpy赋值会报错,可以通过malloc开辟一个空间,

#include<stdio.h> 
#include<string.h>
#include<stdlib.h>
//结构体成员为指针 
struct student{
	char*name;
	int age;
	int*score;
}; 
int main(){
	struct student s1;
	//strcpy(s1.name,"李四");   // 报错
	s1.name=(char*)malloc(sizeof(char)*2);
	//s1.age=(int*)malloc(sizeof(int)*4);  //错 
	s1.score=(int*)malloc(sizeof(int)*4);   //指针才能申请空间 
	strcpy(s1.name,"张三");
	strcpy(s1.name,"李四");
	s1.score[1]=22;
	s1.score[2]=21;
	printf("%s\n",s1.name);
	printf("%d",s1.score[1]);
	free(s1.name);    //记得最后释放空间
	free(s1.score);
	return 0; 
}

6.2结构体指针

作用:通过指针访问结构体中的成员

写法一:(*p).name   (括号和点)

写法二:  p->name  (减号和大于号)

示例:

#include<stdio.h> 
struct student{
	char name[20];
	int age;
};
//结构体指针
int main(){
	struct student ss;={"老六",23};
	struct student*p=&ss;     
	//*p->name ="张三";     //报错 
	(*p).age=19;
	printf("%s\n",p->name);   //两种写法皆可
	printf("%s\n",(*p).name);
	printf("%d\n",(*p).age);
	return 0; 
}

6.3开辟指针的堆区内存

先开辟3个指针内存,存储3个结构体,再结合for循环语句依次给结构体内部指针开辟堆区内存

#include<stdio.h> 
#include<stdlib.h>
typedef struct student ss; 
struct student{
	char* name;  //指针8字节 
	int* age;   //4字节 
};
//结构体指针
int main(){
	ss*p=(ss*)malloc(sizeof(ss)*3);
	int i;
	for(i=0;i<3;i++){  //
		//(p+i)->name=(char*)malloc(sizeof(char)*3);
		//(p+i)->age==(char*)malloc(sizeof(int)*3);//3个人 
		//或者写成p[i] 降维度操作,不表示指针
		p[i].name=(char*)malloc(sizeof(char)*3);
		p[i].age=(char*)malloc(sizeof(int)*3);	  
   //注意返回的还是指针不要写成 p[i].age=(int*)malloc(sizeof(int)*3)
	}
	for(i=0;i<3;i++){
		scanf("%s %d",p[i].name,&p[i].age);
	}
	for(i=0;i<3;i++){
		printf("姓名%s 年龄%d\n",(p+i)->name,(p+i)->age);
	}    
	for(i=0;i<3;i++){
		free(p[i].name);  //先释放内部再释放外部p 
		free(p[i].age); 
	}
	free(p);
	return 0; 
} 

运行结果如下

 7.结构体做函数参数

7.1结构体普通变量做函数参数

7.2结构体指针变量做函数参数

7.3结构体数组名做函数参数

7.4const修饰的结构体指针与二级指针

其实原理都一模一样,合并写代码如下:

#include<stdio.h>
#include<string.h> 
struct student{     
	char name[20];
	int age;
};
void text1(struct student ss){
	printf("%s\n",ss);     //张三 
}
void text2(struct student*p){
	strcpy(p->name,"李四"); 
	printf("%s\n",p->name);    //李四 
}
//数组作为函数参数退化为指针,丢失元素精度,需要传递个数  
void text3(struct student sss[3],int len){
	int i,j;
	for(i=0;i<len;i++){
		for(j=0;j<len-1-i;j++){
			if(sss[j].age>sss[j+1].age){
				int temp =sss[j].age ;
				sss[j].age =sss[j+1].age ;
				sss[j+1].age =temp;
			}
		}
	for(i=0;i<len;i++){
		printf("姓名%s 年龄%d\n",sss[i].name,sss[i].age);
	}
}
}
int main(){
	struct student ss={"张三",30};
	text1(ss); 
	struct student*p=&ss;
	text2(p);
	printf("%s\n",p->name);   //也打印李四——同理可以改变实参 
	struct student sss[3]={      
		{"张三",22},
		{"李四",21},       
		{"王五",25}
	};
	int len=sizeof(sss)/sizeof(sss[0]);
	text3(sss,len);
	const struct student*const p1=&ss;
	struct student**pp=&p1;
	(*pp)->age=888;
//二级指针的使用可以对变量的值进行修改
	printf("姓名%s 年龄%d\n",ss.name,ss.age);  //打印张三  888
	return 0;
}

2.(共用体)联合体

概念:

1、联合union是一个能在同一个存储空间存储不同类型数据的类型;

2、联合体所占的内存长度等于其最长成员的长度倍数;

3、同一存段可以用来存放几种不同类型的成员,但每一瞬间只有一种起作用;

4、共用体变量中起作用的成员是最后一次存放的成员,在存入一个新的成员后原有的成员的值会被覆盖;

5、共用体变量的地址和它的各成员的地址是同一个地址

示例如下:

#include<stdio.h>
union Var{
	int a;
	float b;
	char c;
	double d;
	long long e;
};
int main(){
	union Var vv;
	vv.a=80;
	printf("%d\n",vv.a);
	vv.b =8;
	printf("%d\n",vv.a);//乱码
	printf("%d\n",sizeof(vv));   //8
	printf("%p\n",&vv.a );   //地址均为000000000062FE10
	printf("%p\n",&vv.b );
	printf("%p\n",&vv.c );
	printf("%p\n",&vv.d );
	return 0; 
}

3.枚举

概念:将变量的值一一列举出来,变量的值只限于列举出来的值的范围内

#include<stdio.h>
enum COLOR{
	red=10,yellow=20,blue=30,green=40
}color;
int main(){
	int value;
	while(1){
	    scanf("%d",&value);
		switch(value){
			case red:
				printf("红色");
				break;
			case yellow:
				printf("黄色") ;
				break;
			case blue:
				printf("蓝色");
				break; 
			case green:
				printf("绿色"); 
				break;}
			}
	return 0;
} 

4.typedef

概念:typedef为C语言的关键字,作用是为一种数据类型定义新名字

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
项目:使用 JavaScript 编写的杀死幽灵游戏(附源代码) 杀死鬼魂游戏是使用 Vanilla JavaScript、CSS 和 HTML 画布开发的简单项目。这款游戏很有趣。玩家必须触摸/杀死游荡的鬼魂才能得分。您必须将鼠标悬停在鬼魂上 - 尽量得分。鬼魂在眨眼间不断从一个地方移动到另一个地方。您必须在 1 分钟内尽可能多地杀死鬼魂。 游戏制作 这个游戏项目只是用 HTML 画布、CSS 和 JavaScript 编写的。说到这个游戏的特点,用户必须触摸/杀死游荡的幽灵才能得分。游戏会根据你杀死的幽灵数量来记录你的总分。你必须将鼠标悬停在幽灵上——尽量得分。你必须在 1 分钟内尽可能多地杀死幽灵。游戏还会显示最高排名分数,如果你成功击败它,该分数会在游戏结束屏幕上更新。 该游戏包含大量的 javascript 以确保游戏正常运行。 如何运行该项目? 要运行此游戏,您不需要任何类型的本地服务器,但需要浏览器。我们建议您使用现代浏览器,如 Google Chrome 和 Mozilla Firefox。要玩游戏,首先,单击 index.html 文件在浏览器中打开游戏。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。
javascript 中的 Paint War Game 是使用 HTML、CSS 和 JavaScript 开发的。谈到游戏玩法,这款游戏的主要目标是建造比敌人更多的油漆砖。您所要做的就是使用 WASD 键输入玩家的动作。您可以使用 VS Code 来运行该项目。 关于项目 每次您的玩家走过一块瓷砖时,它都会被涂成您的团队颜色。您必须在同一块瓷砖上走 4 次才能获得更多游戏点数。瓷砖会被您的团队挡住,并且不能再被偷走。如果您走过另一支球队的瓷砖,它会像您第一次走过时一样被涂上颜色。如果您创建一个封闭的被阻挡瓷砖图形,图形内所有未被阻挡的瓷砖都将固定为您的团队颜色。这个游戏充满乐趣,创造和重新即兴发挥会更有趣。 要运行此项目,我们建议您使用现代浏览器,例如 Google Chrome、  Mozilla Firefox。该游戏可能还支持 Explorer/Microsoft Edge。 演示: javascript 中的 Paint War Game 是使用 HTML、CSS 和 JavaScript 开发的。谈到游戏玩法,这款游戏的主要目标是建造比敌人更多的油漆砖。您所要做的就是使用 WASD 键输入玩家的动作。您可以使用 VS Code 来运行该项目。 关于项目 每次您的玩家走过一块瓷砖时,它都会被涂成您的团队颜色。您必须在同一块瓷砖上走 4 次才能获得更多游戏点数。瓷砖会被您的团队挡住,并且不能再被偷走。如果您走过另一支球队的瓷砖,它会像您第一次走过时一样被涂上颜色。如果您创建一个封闭的被阻挡瓷砖图形,图形内所有未被阻挡的瓷砖都将固定为您的团队颜色。这个游戏充满乐趣,创造和重新即兴发挥会更有趣。 要运行此项目,我们建议您使用现代浏览器,例如 Google Chrome、  Mozilla Firefox。该游戏可能还支持 Explorer/Microsoft Edge。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值