编程实战:类C语法的编译型脚本解释器(九)编译语句

news2024/11/27 20:49:47

系列入口:编程实战:类C语法的编译型脚本解释器(系列)-CSDN博客

        前文已经介绍了编译入口,核心就是语句,本文介绍语句的编译。

目录

一、代码概览

二、辅助函数

2.1 tokens.IsPosNotToken(pos)

2.2 tokens.MoveCurrentToken(pToken, pos)

2.3 tokens.IsDelimiter(pos, ";")

2.4 tokens.MoveNextToken(pToken, pos)

2.5 tokens.IsOperator(pos, "(")

三、流程分析


一、代码概览

 

        代码太长,直接贴:

		bool GetSentence(CTokens& tokens, T_VARIABLE_S& vars, Sentence& sentence, Token*& pToken, size_t& pos)
		{
			sentence.clear();
			Expression* pExpression;

			if (tokens.IsPosNotToken(pos))return false;
			sentence.source_start = tokens.TokenStart(pos);
			sentence.source_end = tokens.TokenStart(pos);
			tokens.MoveCurrentToken(pToken, pos);
			switch (pToken->type)
			{
			case Token::IDENTIFIER:
			case Token::NUMBER:
			case Token::STRING:
			case Token::OPERATOR:
				sentence.type = Sentence::EXPRESSION;
				pExpression = GetExpression(tokens, vars, NULL, pos, ";");
				if (!tokens.IsPosNotToken(pos) && tokens.IsDelimiter(pos, ";"))
				{
					tokens.MoveNextToken(pToken, pos);
				}
				sentence.expressions.reserve(1);
				sentence.expressions.push_back(*pExpression);
				break;
			case Token::DELIMITER:
				if (pToken->text == "{")
				{
					sentence.type = Sentence::BLOCK;
					tokens.MoveNextToken(pToken, pos);
					while (true)
					{
						if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,块语句未结束");
						if (tokens.IsDelimiter(pos, "}"))
						{
							tokens.MoveNextToken(pToken, pos);
							break;
						}
						Sentence tmpsentence;
						if (!GetSentence(tokens, vars, tmpsentence, pToken, pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "获取块语句的语句出错");
						sentence.sentences.reserve(sentence.sentences.size() + 1);
						sentence.sentences.push_back(tmpsentence);
					}
				}
				else if (pToken->text == "}")
				{
					CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的块语句结束标记");
				}
				else if (pToken->text == ";")
				{
					sentence.type = Sentence::NULLSENTENCE;
					tokens.MoveNextToken(pToken, pos);
				}
				else
				{
					CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "尚未支持的分隔符");
				}
				break;
			case Token::KEYWORD:
				if (pToken->text == "return")
				{
					sentence.type = Sentence::RETURN;
					tokens.MoveNextToken(pToken, pos);
					pExpression = GetExpression(tokens, vars, NULL, pos, ";");
					Expression null_expression;
					if (NULL == pExpression)
					{
						pExpression = &null_expression;
					}
					if (!tokens.IsPosNotToken(pos) && tokens.IsDelimiter(pos, ";"))
					{
						tokens.MoveNextToken(pToken, pos);
					}
					sentence.expressions.reserve(1);
					sentence.expressions.push_back(*pExpression);
				}
				else if (pToken->text == "if")
				{
					sentence.type = Sentence::IF;
					tokens.MoveNextToken(pToken, pos);
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待左括号");
					if (!tokens.IsOperator(pos, "("))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待左括号");
					tokens.MoveNextToken(pToken, pos);
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待条件表达式");
					if (NULL == (pExpression = GetExpression(tokens, vars, NULL, pos, ")")))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "条件表达式为空");
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待右括号");
					if (!tokens.IsOperator(pos, ")"))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待右括号");
					sentence.expressions.reserve(1);
					sentence.expressions.push_back(*pExpression);
					tokens.MoveNextToken(pToken, pos);
					sentence.sentences.reserve(2);
					Sentence if_sentence;
					if (!GetSentence(tokens, vars, if_sentence, pToken, pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "分析if块的执行语句出错");
					sentence.sentences.push_back(if_sentence);
					if (!tokens.IsPosNotToken(pos))
					{
						if (pToken->type == Token::KEYWORD && pToken->text == "else")
						{
							tokens.MoveNextToken(pToken, pos);
							Sentence else_sentence;
							if (!GetSentence(tokens, vars, else_sentence, pToken, pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "分析else块的执行语句出错");
							sentence.sentences.push_back(else_sentence);
						}
					}
				}
				else if (pToken->text == "do")
				{
					sentence.type = Sentence::DO;
					tokens.MoveNextToken(pToken, pos);
					sentence.sentences.reserve(1);
					Sentence if_sentence;
					if (!GetSentence(tokens, vars, if_sentence, pToken, pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "分析do块的执行语句出错");
					sentence.sentences.push_back(if_sentence);
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待while");
					if (pToken->type != Token::KEYWORD || pToken->text != "while")CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待while");
					tokens.MoveNextToken(pToken, pos);
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待左括号");
					if (!tokens.IsOperator(pos, "("))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待左括号");
					tokens.MoveNextToken(pToken, pos);
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待条件表达式");
					if (NULL == (pExpression = GetExpression(tokens, vars, NULL, pos, ")")))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "条件表达式为空");
					tokens.MoveCurrentToken(pToken, pos);
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待右括号");
					if (!tokens.IsOperator(pos, ")"))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待右括号");
					sentence.expressions.reserve(1);
					sentence.expressions.push_back(*pExpression);
					tokens.MoveNextToken(pToken, pos);
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待分号");
					if (!tokens.IsDelimiter(pos, ";"))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待分号");
					tokens.MoveNextToken(pToken, pos);
				}
				else if (pToken->text == "while")
				{
					sentence.type = Sentence::WHILE;
					tokens.MoveNextToken(pToken, pos);
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待左括号");
					if (!tokens.IsOperator(pos, "("))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待左括号");
					tokens.MoveNextToken(pToken, pos);
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待条件表达式");
					if (NULL == (pExpression = GetExpression(tokens, vars, NULL, pos, ")")))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "条件表达式为空");
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待右括号");
					if (!tokens.IsOperator(pos, ")"))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待右括号");
					sentence.expressions.reserve(1);
					sentence.expressions.push_back(*pExpression);
					tokens.MoveNextToken(pToken, pos);
					sentence.sentences.reserve(1);
					Sentence if_sentence;
					if (!GetSentence(tokens, vars, if_sentence, pToken, pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "分析while块的执行语句出错");
					sentence.sentences.push_back(if_sentence);
				}
				else if (pToken->text == "for")
				{
					sentence.type = Sentence::FOR;//第一个分号前面是一个语句
					sentence.expressions.reserve(2);
					sentence.sentences.reserve(2);

					tokens.MoveNextToken(pToken, pos);
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待左括号");
					if (!tokens.IsOperator(pos, "("))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待左括号");

					tokens.MoveNextToken(pToken, pos);
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待初始化表达式");
					Sentence init_sentence;
					if (!GetSentence(tokens, vars, init_sentence, pToken, pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "分析for块的初始化语句出错");
					sentence.sentences.push_back(init_sentence);

					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待条件表达式");
					if (NULL == (pExpression = GetExpression(tokens, vars, NULL, pos, ";")))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "获取条件表达式出错");
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待分号");
					if (!tokens.IsDelimiter(pos, ";"))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待分号");
					sentence.expressions.push_back(*pExpression);

					tokens.MoveNextToken(pToken, pos);
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待循环递增表达式");
					if (NULL == (pExpression = GetExpression(tokens, vars, NULL, pos, ")")))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "获取循环递增表达式出错");
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待右括号");
					if (!tokens.IsOperator(pos, ")"))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待右括号");
					sentence.expressions.push_back(*pExpression);

					tokens.MoveNextToken(pToken, pos);
					Sentence for_sentence;
					if (!GetSentence(tokens, vars, for_sentence, pToken, pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "分析for块的执行语句出错");
					sentence.sentences.push_back(for_sentence);
				}
				else if ("break" == pToken->text)
				{
					sentence.type = Sentence::BREAK;
					tokens.MoveNextToken(pToken, pos);
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待分号");
					if (!tokens.IsDelimiter(pos, ";"))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待分号");
					tokens.MoveNextToken(pToken, pos);
				}
				else if ("continue" == pToken->text)
				{
					sentence.type = Sentence::CONTINUE;
					tokens.MoveNextToken(pToken, pos);
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待分号");
					if (!tokens.IsDelimiter(pos, ";"))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待分号");
					tokens.MoveNextToken(pToken, pos);
				}
				else if ("long" == pToken->text || "double" == pToken->text || "int" == pToken->text || "float" == pToken->text || "string" == pToken->text)
				{//声明语句
					sentence.type = Sentence::DECLARE;
					Variable var;
					if ("long" == pToken->text || "int" == pToken->text)var.type = Variable::LONG;
					else if ("double" == pToken->text || "float" == pToken->text)var.type = Variable::DOUBLE;
					else var.type = Variable::STRING;

					tokens.MoveNextToken(pToken, pos);
					if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待变量名");
					if (tokens.IsDelimiter(pos, ";"))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的分号,期待变量名");
					if (pToken->type != Token::IDENTIFIER)CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待标识符");
					sentence.expressions.resize(1);
					sentence.expressions[0].type = Expression::DEFINE;
					sentence.expressions[0].VariableName = pToken->text;
					sentence.expressions[0].m_variable = var;
					sentence.expressions[0].source_start = sentence.source_start;
					sentence.expressions[0].source_end = tokens.TokenStart(pos + 1);
					tokens.MoveNextToken(pToken, pos);
					if (tokens.IsPosNotToken(pos))
					{
					}
					else if (tokens.IsOperator(pos, "="))
					{//带有初始值
						tokens.MoveNextToken(pToken, pos);
						if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待初始化表达式");
						if (NULL == (pExpression = GetExpression(tokens, vars, NULL, pos, ";")))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "获取初始化表达式出错");
						if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待分号");
						if (!tokens.IsDelimiter(pos, ";"))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待分号");
						tokens.MoveNextToken(pToken, pos);
						sentence.expressions[0].AddLeftOperand(*pExpression);
					}
					else if (tokens.IsOperator(pos, "("))
					{//函数
						for (long i = 0; i < (long)m_functions.size(); ++i)
						{
							if (m_functions[i].script_name == sentence.expressions[0].VariableName)CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "函数重名");
						}
						m_functions.resize(m_functions.size() + 1);
						CScript* pFunction = &m_functions[m_functions.size() - 1];
						pFunction->FromParent(*this, sentence.expressions[0].VariableName);
						pFunction->return_type = var.type;
						pFunction->count_global_variable = vars.getGlobalCount();
					
						tokens.MoveNextToken(pToken, pos);
						while (!tokens.IsOperator(pos, ")"))
						{
							Variable param;
							if ("long" == pToken->text || "int" == pToken->text)param.type = Variable::LONG;
							else if ("double" == pToken->text || "float" == pToken->text)param.type = Variable::DOUBLE;
							else if("string"== pToken->text)param.type = Variable::STRING;
							else CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待参数类型");
							tokens.MoveNextToken(pToken, pos);
							if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待参数名");
							if (pToken->type != Token::IDENTIFIER)CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待标识符");
							if (!pFunction->m_EnvVariables.AddVariable(pToken->text, param))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "函数参数重名");
							if (NULL!=vars.FindVariable(pToken->text))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "函数参数与全局变量或环境变量重名");
							tokens.MoveNextToken(pToken, pos);
							if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,期待)");
							if (tokens.IsOperator(pos, ","))tokens.MoveNextToken(pToken, pos);
							else break;
						}
						if (!tokens.IsOperator(pos, ")"))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待)");
						tokens.MoveNextToken(pToken, pos);
						if (!tokens.IsDelimiter(pos, "{"))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待{");
						tokens.MoveNextToken(pToken, pos);
						
						T_VARIABLE_S tmpvars;
						tmpvars.FromParentVars(vars, pFunction->count_global_variable, &pFunction->m_EnvVariables);
						if (!pFunction->Build(tokens, tmpvars, pos))
						{
							m_msg += "编译失败\r\n";
							return false;
						}
						
						if (!tokens.IsDelimiter(pos, "}"))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待}");
						tokens.MoveNextToken(pToken, pos);
						if (!tokens.IsDelimiter(pos, ";"))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待分号");
						tokens.MoveNextToken(pToken, pos);
						
						return GetSentence(tokens, vars, sentence, pToken, pos);
					}
					else if (!tokens.IsDelimiter(pos, ";"))
					{
						CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待分号,一个语句只能定义一个变量");
					}
				}
				else
				{
					CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "非期待的的关键字,是否前面缺少分号?");
				}
				break;
			default:
				CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未支持的标记类型");
				break;
			}
			sentence.source_end = tokens.TokenStart(pos);
			return sentence.source_end != sentence.source_start;
		}

        整个过程通过pos贯穿,pos是当前的Token位置,大部分函数使用的都是pos的引用,在内部会修改pos,函数返回时pos总是处于下一个未处理的Token位置。 

二、辅助函数

        里面用到一些功能比较小的函数。

2.1 tokens.IsPosNotToken(pos)

        这个判断是否pos已经到达结束位置。

2.2 tokens.MoveCurrentToken(pToken, pos)

        这个将pToken指向pos处的Token,方便后面使用。

2.3 tokens.IsDelimiter(pos, ";")

        这个函数判断pos是否是给定的分隔符,需要同时判断Token类型和文本。

2.4 tokens.MoveNextToken(pToken, pos)

        同时将pToken和pos指向下一个Token。

2.5 tokens.IsOperator(pos, "(")

        这个函数判断是否是给定的操作符,需要同时判断Token类型和文本。

三、流程分析

        流程处理相对简单,根据获取到的第一个Token的类型做分支处理,每个分支根据各自的语法要求获取语句或变量。

        如果是标识符、数字、字符串、操作符,就是一个表达式,调用GetExpression()函数获取一个表达式,生成一个表达式语句:

			case Token::IDENTIFIER:
			case Token::NUMBER:
			case Token::STRING:
			case Token::OPERATOR:
				sentence.type = Sentence::EXPRESSION;
				pExpression = GetExpression(tokens, vars, NULL, pos, ";");
				if (!tokens.IsPosNotToken(pos) && tokens.IsDelimiter(pos, ";"))
				{
					tokens.MoveNextToken(pToken, pos);
				}
				sentence.expressions.reserve(1);
				sentence.expressions.push_back(*pExpression);
				break;

        如果是分隔符,只有一种合法类型,“{”,是块语句,循环获取语句直到遇到“}”:

			case Token::DELIMITER:
				if (pToken->text == "{")
				{
					sentence.type = Sentence::BLOCK;
					tokens.MoveNextToken(pToken, pos);
					while (true)
					{
						if (tokens.IsPosNotToken(pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的脚本结束,块语句未结束");
						if (tokens.IsDelimiter(pos, "}"))
						{
							tokens.MoveNextToken(pToken, pos);
							break;
						}
						Sentence tmpsentence;
						if (!GetSentence(tokens, vars, tmpsentence, pToken, pos))CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "获取块语句的语句出错");
						sentence.sentences.reserve(sentence.sentences.size() + 1);
						sentence.sentences.push_back(tmpsentence);
					}
				}
				else if (pToken->text == "}")
				{
					CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "未期待的块语句结束标记");
				}
				else if (pToken->text == ";")
				{
					sentence.type = Sentence::NULLSENTENCE;
					tokens.MoveNextToken(pToken, pos);
				}
				else
				{
					CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "尚未支持的分隔符");
				}
				break;

        剩下的就是关键字,对关键字再分别处理,虽然稍微负责一些,但用到的东西和上面的差不多。

        剩下的未介绍的部分就是表达式编译了。

(这里是结束,但不是整个系列的结束)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1291233.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为快应用遇到的坑(uniapp开发)

我这边是使用uniapp开发的华为快应用&#xff0c;我想实现的效果就是收藏功能&#xff0c;点击白色收藏&#xff0c;收藏变成红色&#xff0c;点击红色收藏变成白色收藏 <template><cover-view click"collect"><cover-image v-if"is_collect&quo…

cocos creator “TypeError: Cannot set property ‘string‘ of null

背景&#xff1a; 学习cocos creator时遇到"TypeError: Cannot set property string of null" 错误。具体代码如下&#xff1a;property({ type: Label })public stepsLabel: Label | null null;update(deltaTime: number) {this.stepsLabel.string Math.floor(…

在Linux系统中更换yum源为阿里云

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…

学生成绩管理系统(Java)

开发环境: Windows 11 IDEA 2021.3.3 需求: package com.it.neu;import java.util.ArrayList; import java.util.Scanner;import static java.time.Clock.system;class Student { //创建学生类private String Stu_name;private String Stu_id;public Student(String id, S…

C++使用策略模式,减少使用switch...case...

目录 原理函数类模板函数使用switch...case...不使用switch...case... 知识点decltypestd::remove_reference 原理 函数 #include <iostream> #include <functional> #include <map>void fun1(int a, int b) {std::cout << "fun1 : a "<…

学生成绩的增删改查

接上一篇MySQL数据库与其管理工具Navicat link 1.下载JDBC 可以登录MySQL的官方网站&#xff1a;www.mysql.com&#xff0c;下载JDBC-MySQL数据库驱动&#xff08;JDBC Driver for MySQL&#xff09;下载mysql-connector-java-5.1.40.zip后&#xff0c;将该zip文件解压至硬盘&a…

当使用RSA加密,从手机前端到服务器后端的请求数据存在+

将转成了空格&#xff0c;导致解密出错 将空格转成了

Numpy 实现基尼指数算法的决策树

基尼系数实现决策树 基尼指数 Gini ⁡ ( D ) 1 − ∑ k 1 K ( ∣ C k ∣ ∣ D ∣ ) 2 \operatorname{Gini}(D)1-\sum_{k1}^{K}\left(\frac{\left|C_{k}\right|}{|D|}\right)^{2} Gini(D)1−k1∑K​(∣D∣∣Ck​∣​)2 特征 A A A条件下集合 D D D的基尼指数&#xff1a; Gi…

『VUE3后台—硅谷甄选』

一、准备前期 pnpm create vite

学习Python的未来前景分析

文章目录 前言学python可以干什么如果具备Python编程&#xff0c;能用Python做什么&#xff1a;学Python语言能干什么1.常规软件开发2.科学计算3.自动化运维4.云计算 学python编程对未来的影响关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Py…

2024年江苏省职业院校技能大赛信息安全管理与评估 第二阶段学生组(样卷)

2024年江苏省职业院校技能大赛信息安全管理与评估 第二阶段学生组&#xff08;样卷&#xff09; 竞赛项目赛题 本文件为信息安全管理与评估项目竞赛-第二阶段样题&#xff0c;内容包括&#xff1a;网络安全事件响应、数字取证调查、应用程序安全。 本次比赛时间为180分钟。 …

星钻图形输出

答案&#xff1a; #include <stdio.h> int a 0, b 0; void printLine(int a , int b) //输出一行包含&#xff1a;若干个空格 若干个*&#xff0c;第一&#xff0c;二个参数为空格数和*数&#xff1b; (定义一个星钻输出函数) {while (a--) //打印a个空格{printf(…

小程序左右侧边栏

效果 点击左侧边栏&#xff0c;右侧会定位到对应内容&#xff1b; 右侧滑动&#xff0c;左侧也会显示对应的高亮&#xff1b; 也就是左右联动的效果 项目场景 tocc-app 应急巡检 传入数据: 左侧点击&#xff0c;右侧滚动到对应位置 点击左侧导航条&#xff0c;就计算出右…

JavaScript面向对象编程的奥秘揭秘:掌握核心概念与设计模式

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;JavaScript篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来JavaScript篇专栏内容:JavaScript-面向对象 目录 什么是面向对象&#xff1f; 类与对象的主要区别 创建…

【数据结构】- 详解哈夫曼树(用 C 语言实现哈夫曼树的构造和哈夫曼编码)

目录 一、哈夫曼树的基本概念 二、哈夫曼树的构造算法 2.1 - 哈夫曼树的构造过程 2.2 - 哈夫曼树的存储表示 2.3 - 算法实现 三、哈夫曼编码 3.1 - 哈夫曼编码的主要思想 3.2 - 哈夫曼编码的性质 3.3 - 算法实现 一、哈夫曼树的基本概念 哈夫曼树的定义&#xff0c;涉…

电脑字体大小怎么设置?学会这3个方法,轻松调节!

“感觉我近视又加深了&#xff0c;最近看电脑居然感觉字体有点小。我想把字体放大一点但却不知道应该怎么操作&#xff0c;有没有朋友可以指导一下我呀&#xff1f;” 在我们的日常生活中&#xff0c;电脑已经成为我们获取信息、交流和娱乐的重要工具。字体大小作为电脑显示的基…

厦门基础城建中排水管网作用,助力提升城市韧性

在厦门这个美丽的海滨城市&#xff0c;城市建设与发展日新月异&#xff0c;其中&#xff0c;城市生命线下的排水管网监测系统作为城市基础设施的重要组成部分&#xff0c;对保障城市安全、提升城市品质发挥着关键作用。 对于厦门城市建设中的排水管网监测系统安装策略 1. 合理…

【头歌系统数据库实验】实验2 MySQL软件操作及建库建表建数据

目录 第1关&#xff1a;创建数据库 第2关&#xff1a;创建供应商表S&#xff0c;并插入数据 第3关&#xff1a;创建零件表P&#xff0c;并插入数据 第4关&#xff1a;创建工程项目表J&#xff0c;并插入数据 第5关&#xff1a;创建供应情况表SPJ&#xff0c;并插入数据 …

软件开发文档的内容

软件开发文档是开发过程中用于记录、指导和沟通的重要工具。它可以包含多个文档&#xff0c;每个文档都有其特定的格式和目的。以下是一些常见的软件开发文档及其可能的格式&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#…

模拟目录管理 - 华为OD统一考试(C卷)

OD统一考试(C卷) 分值: 200分 题解: Java / Python / C++ 题目描述 实现一个模拟目录管理功能的软件,输入一个命令序列,输出最后一条命令运行结果。 支持命令: 1)创建目录命令: mkdir 目录名称,如mkdir abc为在当前目录创建abc目录,如果已存在同名目录则不执行任何操作…