c语言18-结构体定义、结构体指针和成员访问、结构体数组、相关例题

1、结构体定义

自定义数据类型

结构体:
struct 类型名
{
各成员
};

用数据类型定义单个变量:

定义内置类型举例:

int main()
{
	int a = 10;
	double b = 11.2;
	int *p1 = &a;
	double *p2 = &b;
	int arr[10] = {1,2,5};
	//...

	return 0;
}

定义结构体举例:

struct Student//定义Student数据类型
{
    //数据成员
	char name[20];
	int age;
};//定义完成后,其地位和内置类型一样

注意:结构体定义完成后,其地位和内置类型一样

所以以下代码可实现:

struct A
{
int a;
int b;
// struct B bb;//error,不合法
};

struct B
{
	double c;
	struct A d;//合法,可实现
	//struct B e;//error,不合法
	//struct B *f;//合法,例如设计列表的结点
};

struct Node//链表的结点
{
    int date;
    struct Node *next;
};

2、结构体指针和成员访问

结构体普通变量通过".“访问其成员;
结构体指针变量通过”->"访问其成员;

    struct Student stu2;
    struct Student *ps = &stu2;
    
    //*ps.age = 15;//error,'*'优先级低于'.'
	//(*ps).age = 15;//可行,但太过麻烦
	ps->age = 15;

*ps.age = 15;报错:
在这里插入图片描述

在这里插入图片描述
测试代码:

struct A
{
int a;
int b;
};

struct B
{
	double c;
	struct A d;//合法,可实现
};

struct Student//定义Student数据类型
{
	char name[20]; 
	int age;
};//定义完成后,其地位和内置类型一样

int main()
{
	int a = 10;
	double b = 11.2;
	int *p1 = &a;
	double *p2 = &b;
	*p1  = 100;
	int arr[10] = {1,2,5};

	//定义单个变量及初始化
	struct Student stu1 = {"yasuo",21};
	struct Student stu2;//不初始化,内容为随机值
	struct Student stu3={"jie"};//只初始化一部分,剩余部分为0

	//将stu3的年龄改为25
	stu3.age = 25;
	//输出stu3的信息
	printf("%s,%d\n",stu3.name,stu3.age);

	//类比:int *p1 = &a;
	struct Student *ps = &stu2;

	//stu2.name,stu2.age..
	//通过ps将stu2的信息改为bulong,15
	printf("原来的:%s,%d\n",stu2.name,stu2.age);
	//*ps.age = 15;//error,'*'优先级低于'.'
	//(*ps).age = 15;//可行,但太过麻烦
	ps->age = 15;

	//ps->name = "bulong";//error,数组不能整体复制
	strcpy(ps->name,"bulong");

	printf("更改后的:%s,%d\n",stu2.name,stu2.age);

	return 0;
}

运行结果:
在这里插入图片描述

什么时候使用’.‘什么时候使用’->'相关例子

代码:

//会出现大量非法访问的问题和野指针,但暂时不管
struct A
{
	int a;
	double *b;
};

struct B
{
	long *c;
	struct A d;
};

//练习'.'和'->'
int main()
{
	struct B aa;
	struct B *bb = &aa;
	
    //通过变量aa或bb访问其成员a,b,c
	aa.c;//访问自己内部的成员,所以使用'.'
	aa.d.a;
	aa.d.b;

	bb->c;
	bb->d.a;
	bb->d.b;

	return 0;
}

在这里插入图片描述

结构体传参:

因为结构体一般比较大,所以传参要比较注意:
结构体进行参数传递时,都是传递指针,不传本身,节约空间;

示例代码:

struct Student//定义Student数据类型
{
	char name[20];
	int age;
};

void Show1(struct Student stu)
{
	printf("%s,%d\n",stu.name,stu.age);
}

void Show2(const struct Student *pstu)
{
	printf("%s,%d\n",pstu->name,pstu->age);
}

int main()
{
	struct Student stu1={"yasuo",21};

	printf("%s,%d\n",stu1.name,stu1.age);
	Show1(stu1);//设计 不好,传递的数据(实参24字节)太大
	Show2(&stu1);

	return 0;
}

运行结果:

在这里插入图片描述

3、结构体数组

使用示例:

struct Student//定义Student数据类型
{
	char name[20];
	int age;
};
struct Student arr[3]={"caocao",20,"liubei",25,"sunquan",18};

图形结构:

在这里插入图片描述

使用示例代码:

struct Student//定义Student数据类型
{
	char name[20];
	int age;
};

void Show1(struct Student stu)
{
	printf("%s,%d\n",stu.name,stu.age);
}

void Show2(const struct Student *pstu)
{
	printf("%s,%d\n",pstu->name,pstu->age);
}

void Show(const struct Student *parr,int len)
{
	for(int i=0;i<len;++i)
	{
		printf("%s,%d\n",parr[i].name,parr[i].age);
		printf("%s,%d\n",(parr+i)->name,(parr+i)->age);
	}
}

int main()
{
	struct Student stu1={"yasuo",21};

	struct Student arr[3]={"caocao",20,"liubei",25,"sunquan",18};

	arr[1].age = 26;

	//输出arr的内容
	for(int i=0;i<sizeof(arr)/sizeof(arr[0]);++i)
	{
		printf("%s,%d\n",arr[i].name,arr[i].age);
	}

	Show(arr,sizeof(arr)/sizeof(arr[0]));


	return 0;
}

运行结果:
在这里插入图片描述

4、相关例题

1)投票器的实现

在这里插入图片描述

代码实现:

struct Person
{
	char name[20];//候选人姓名
	int count;//票数
};

void Show(const struct Person *arr,int len)
{
	for(int i=0;i<len;i++)
	{
	printf("候选人:%s的票数为:%d\n",arr[i].name,arr[i].count);
	}
}

//计票函数
void Ticket(struct Person *arr,int len)//仅实现基础功能,未进行优化
{
	char name[20];//从键盘读票
	for(int i=0;i<5;i++)
	{
		scanf("%s",name);
		for(int j=0;j<len;j++)//遍历候选人列表
		{
			if(strcmp(arr[j].name,name)==0)
			{
				arr[j].count++;
				break;
			}
		}
	}
}


int main()
{

	struct Person arr[]={"caocao",0,"liubei",0,"sunquan",0};
	
	Ticket(arr,sizeof(arr)/sizeof(arr[0]));

	Show(arr,sizeof(arr)/sizeof(arr[0]));


	return 0;
}

运行结果:

在这里插入图片描述

2)学生信息的读写及排序

在这里插入图片描述

代码:

struct Student//定义Student数据类型
{
	int id;//学号
	char name[20];//姓名
	int score;//分数
};

//从键盘读取学生信息
void Input(struct Student *arr,int len)
{
	for(int i=0;i<len;i++)
	{
		scanf("%d%s%d",&arr[i].id,arr[i].name,&arr[i].score);//arr[i].name不需要加取地址符,因为数组名本身表示地址
	}
}

//void BubbleSort(int *arr,int len)
//{
//	int tmp;
//	for(int i=0;i<len-1;i++)
//	{
//		for(int j=0;j+1<len-i;j++)
//		{
//			if(arr[j]<arr[j+1])
//			{
//				tmp =arr[j];
//				arr[j]=arr[j+1];
//				arr[j+1]=tmp;
//			}
//		}
//	}
//}

//分数从高到低排序(冒泡,从大到小)
void Sort(struct Student *arr,int len)
{
	struct Student tmp;
	for(int i=0;i<len-1;i++)//趟数
	{
		for(int j=0;j+1<len-i;j++)//j+1,小小心越界
		{
			if(arr[j].score < arr[j+1].score)
			{
				tmp =arr[j];
				arr[j]=arr[j+1];
				arr[j+1]=tmp;
			}
		}
	}
}


//输出信息
void Show(const struct Student *arr,int len)
{
	for(int i=0;i<len;i++)
	{
		printf("学号:%d  学生:%s的成绩为:%d\n",arr[i].id,arr[i].name,arr[i].score);
	}
}



int main()
{
	struct Student arr[5];

	Input(arr,sizeof(arr)/sizeof(arr[0]));

	Show(arr,sizeof(arr)/sizeof(arr[0]));

	Sort(arr,sizeof(arr)/sizeof(arr[0]));

	printf("------------\n");

	Show(arr,sizeof(arr)/sizeof(arr[0]));


	return 0;
}

运行代码:

在这里插入图片描述

C语言有两个自带*的符号

"[]“和”->"自带解引用

因为:
p[i] == *(p+i)
p->age == (*p).age

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值