链表与结构体制作多级菜单

#include <iostream>
#include <string>
#include<conio.h>
using namespace std;

struct menu//节点结构体
{
	menu* father;//上级父节点连接
	menu* brother_up;//同级兄节点连接
	menu* brother_down;//同级弟节点连接
	menu* son;//下级子节点连接

	string name;//节点名
	int ID;//节点级别号,但是我没有用
	void* fun;//节点功能函数指针,只有执行函数不为空
};

struct control
{
	menu* now;//需要实时标志现在菜单指针的位置
	void(*p)(void);//一个void类型的函数指针
	char  input;//哈哈哈这个我也没有用
}dir;


void getnow(menu* now);//跟踪指针位置,解析输入命令
void showmenu(menu* now);//显示函数
void controlMENU();//控制函数

menu* creat_head(string s, void* func);//创建头节点
menu* creat_brother(menu* brother, string s, void* func);//往下生成一个兄项(并列关系)
menu* creatson(menu* father, string s, void* func);//往右生成一个子项(从属关系)

//功能函数定义,各个子目录的功能函数
void func1();
void func2_1();
void func2_2();
void func2_3();
void func3();
void func4();



int  main()
{
	menu* head;
	menu* temp;

	//菜单定义区,只有最末端的菜单才拥有执行函数,像“选项2”这样的中继菜单,不用执行函数直接给null
	head = creat_head("选项1", func1);//创建头节点

	temp=creat_brother(head, "选项2",NULL);//头节点往下建立一个与头节点同级的兄弟节点
			temp = creatson(temp,"选项2的子选项1", func2_1);//兄弟节点创建子节点
			temp = creat_brother(temp, "选项2的子选项2", func2_2);//由兄弟节点的子节点创建子节点的同级节点
			temp = creat_brother(temp, "选项2的子选项3",func2_3);
	creat_brother(head, "选项3", func3);
	creat_brother(head, "选项4", func4);

	dir.now = head;

	controlMENU();

	return 0;
}

//功能函数定义,各个子目录的功能函数
void func1()
{
	system("cls");
	cout << "选项1功能调用!" << endl;
	cout << "选项1功能调用完毕,按任意键返回上级菜单!" << endl;
	system("pause");
}
void func2_1()
{
	system("cls");
	cout << "选项2.1功能调用!" << endl;
	cout << "选项2.1功能调用完毕,按任意键返回上级菜单!" << endl;
	system("pause");
}void func2_2()
{
	system("cls");
	cout << "选项2.2功能调用!" << endl;
	cout << "选项2.2功能调用完毕,按任意键返回上级菜单!" << endl;
	system("pause");
}
void func2_3()
{
	system("cls");
	cout << "选项2.3功能调用!" << endl;
	cout << "选项2.3功能调用完毕,按任意键返回上级菜单!" << endl;
	system("pause");
}void func3()
{
	system("cls");
	cout << "选项3功能调用!" << endl;
	cout << "选项3功能调用完毕,按任意键返回上级菜单!" << endl;
	system("pause");
}
void func4()
{
	system("cls");
	cout << "选项4功能调用!" << endl;
	cout << "选项4功能调用完毕,按任意键返回上级菜单!" << endl;
	system("pause");
}



void getnow(menu* now)//跟踪指针位置,解析输入命令
{
	dir.now = now;

	switch (_getch())
	{
		//上移
	case 'w':
	case 'W':
		if (dir.now->brother_up != NULL)
			dir.now = dir.now->brother_up;
		break;

		//下移
	case's':
	case'S':
		if (dir.now->brother_down != NULL)
			dir.now = dir.now->brother_down;
		break;

		//左移返回上一级菜单
	case 'a':
	case 'A':
		if (dir.now->father != NULL)
			dir.now = dir.now->father;
		break;

		//右移去到下一级菜单
	case'd':
	case'D':
		if (dir.now->son != NULL)
			dir.now = dir.now->son;
		break;

	case '\r'://换行和回车还不一样,换行符\n,回车符\r,如果你要检测键盘输入的回车,就要输入\r,而不是\n
		if (dir.now->fun != NULL)//注意,不能在switch语句内部定义变量,语法不允许,会报错!!!所以这个p就在外面定义了
		{
			dir.p = (void(*)(void))dir.now->fun;//强制类型转换,void*模糊类型强制转换为void(*)(void)函数指针的类型
			dir.p();
		}
		break;

	default:
		break;
	}
}

menu* creat_head(string s, void* func)//创建头节点,他没有父亲,我规定他的父亲就是自己。。。太可怜了
{
	menu* p = new menu;

	p->father = p;
	p->brother_down = NULL;
	p->brother_up = NULL;
	p->son = NULL;

	p->name = s;
	p->ID = 1;
	p->fun = func;

	return p;
}

menu* creat_brother(menu* brother, string s, void* func)//往下生成一个兄项(并列关系)
{
	menu* p;
	menu* p1;

	p = brother;
	p1 = new menu;


	while (p->brother_down != NULL)
		p = p->brother_down;

	p->brother_down = p1;

	p1->father = p->father;//既然是兄弟,他们的老爹肯定是一样的
	p1->brother_down = NULL;
	p1->brother_up = p;
	p1->son = NULL;

	p1->name = s;
	p1->ID = p->ID;
	p1->fun = func;

	return p1;
}

menu* creatson(menu* father, string s, void* func)//往右生成一个子项(从属关系)
{
	menu* p;
	menu* p1;

	p = father;
	p1 = new menu;

	p->son = p1;

	p1->father = p;
	p1->brother_up = NULL;
	p1->brother_down = NULL;
	p1->son = NULL;

	p1->name = s;
	p1->ID = p->ID + 1;
	p1->fun = func;

	return p1;
}

void showmenu(menu* now)
{
	menu* show;
	show = now;

	cout << "请通过键盘控制选项!" << endl;
	while (show->brother_up != NULL)//先依次往最上面找大哥
		show = show->brother_up;

	while (show != NULL)//从大哥开始往下显示所有小弟
	{
		if (now->name == show->name)//标记现在指针指向的位置
			cout << "--》";

		cout << show->name << endl;
		show = show->brother_down;
	}
}

void controlMENU()
{
	showmenu(dir.now);//先显示最初信息后等待输入

	while (1)//逻辑是:等待输入命令、清除旧信息、显示新信息
	{
		getnow(dir.now);
		system("cls");
		showmenu(dir.now);
	}
}

多级菜单是初学者的噩梦吧......本来觉得应该做一个菜单类出来,呜呜呜太菜了,面向对象根本不会啊......只能先到这儿了,浅浅标记一下摸鱼的结果吧。

  • 8
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
STM32菜单链表程序是一种用于嵌入式系统的程序设计结构。它利用链表数据结构来管理不同的菜单选项,并提供用户界面以方便用户进行选择和操作。 该程序的主要目的是实现一个可扩展的菜单系统,用户可以通过按键或触摸屏等输入设备来浏览不同的菜单选项,并选择相应的操作或子菜单。 在STM32菜单链表程序中,每个菜单选项都被定义为一个菜单节点,节点中包含菜单的名称、标识符、父菜单节点、子菜单节点以及操作函数等信息。这些节点之间通过链表的方式连接起来,形成一个菜单链表。 程序的运行流程如下:首先,程序初始化时会构建整个菜单链表,将所有的菜单选项按照一定的顺序连接起来。然后,程序会进入一个主循环中,在主循环中通过读取用户输入来判断用户的操作,并根据用户选择的菜单节点进行相应的操作。 用户输入的方式可以根据具体的应用场景进行设定,比如可以通过外部按键、触摸屏、串口或者无线通信等方式实现。程序会根据用户的操作来判断下一步应该显示哪个菜单节点,并调用相应的操作函数来执行相应的操作。 通过这种方式,STM32菜单链表程序可以灵活地管理和扩展菜单选项,方便用户进行各种操作和功能的选择。同时,菜单链表的实现也使得程序的结构清晰、易于维护和扩展。 总的来说,STM32菜单链表程序是一种基于链表数据结构的嵌入式系统程序设计结构,它能够提供灵活的菜单系统,方便用户进行选择和操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诗和远方曾来过

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值