当前位置: 首页 > news >正文

编译原理第一次实验报告

  • 源代码及附件:编译原理实验一源程序及附件资源-CSDN文库
  • 实验题目

  • 实验要求

  • 实验设计

前两部分指出了实验的宏观把控,为了具体实施实验,我们需要预先为实验做出如下设计:

本次实验我选取了C语言的一个子集进行设计词法分析器,其中单词种类如下:(也可参考附件中的单词种类表)

根据题目要求,我们用正则文法来定义我们的子集:

  1. S→关键字|运算符|分界符|整型常量|浮点型常量|标识符
  2. 关键字

→ void|main|int|float|for|while|switch|case|if|else|return|break

(3)运算符 → +|-|*|/|=|==|<|<=|>|>=

(4)分界符 → (|)|[|]|{|}|,|;|:

(5)整型常量 → digit(digit)*

(6)浮点型常量 → digit(digit).digit(digit)

(7)digit→ 0|1|2|3|4|5|6|7|8|9

(8)letter→ a|b|…|z|A|B|…|Z

(9)标识符 → letter(letter|digit)*

  • 实验分析

基本算法思想是:读取文件,逐个字符分析,若是空白符则跳过,为字母时将连续的字母使用超前搜索组合成为变量或关键字;若是数字,则要判断是否为浮点数,即利用超前搜索,判断扫描到的字符是否为小数点;若是分隔符或者操作符,利用switch语句判断并输出,若是其他字符,输出为未定义的字符。

相关代码段:

void lexicalAnalysis(FILE* fp)

{

    char ch;        

    while ((ch = fgetc(fp)) != EOF)    /

    {

        token = ch;                                   

        if (ch == ' ' || ch == '\t' || ch == '\n'//忽略空格、Tab和回车

        {

             if (ch == '\n')                            //遇到换行符,记录行数的row加1

                 row++;

             continue;                                

        }

        else if (isLetter(ch))        //以字母开头,关键字或标识符

        {

             token = "";                   //token初始化

             while (isLetter(ch) || isDigit(ch)) //非字母或数字时退出,将单词存储在token中

             {

                 token.push_back(ch);  //将读取的字符ch存入token中

                 ch = fgetc(fp);           //获取下一个字符

             }

             //文件指针后退一个字节,即重新读取上述单词后的第一个字符

             fseek(fp, -1L, SEEK_CUR);

             if (isKey(token)) //关键字

                 code = TokenCode(getKeyID(token));

             else //标识符

                 code = TK_IDENT; //单词为标识符

        }

        else if (isDigit(ch)) //无符号常数以数字开头

        {

             int isdouble = 0; //标记是否为浮点数

             token = "";          //token初始化

             while (isDigit(ch))   //当前获取到的字符为数字

             {

                 token.push_back(ch);      //读取数字,将其存入token中

                 ch = fgetc(fp);               //从文件中获取下一个字符

                 //该单词中第一次出现小数点

                 if (ch == '.' && isdouble == 0)

                 {

                     //小数点下一位是数字

                     if (isDigit(fgetc(fp)))

                     {

                         isdouble = 1;    //标记该常数中已经出现过小数点

                         fseek(fp, -1L, SEEK_CUR);     //将超前读取的小数点后一位重新读取

                         token.push_back(ch);          //将小数点入token中

                         ch = fgetc(fp);               //读取小数点后的下一位数字

                     }

                 }

             }

             if (isdouble == 1)

                 code = TK_DOUBLE; //单词为浮点型

             else

                 code = TK_INT;                //单词为整型

             //文件指针后退一个字节,即重新读取常数后的第一个字符

             fseek(fp, -1L, SEEK_CUR);

        }

        else switch (ch)

        {

             /*运算符*/

        case '+': code = TK_PLUS;     //+加号         

             break;

        case '-': code = TK_MINUS;    //-减号

             break;

        case '*': code = TK_STAR;     //*乘号     

             break;

        case '/': code = TK_DIVIDE;        //除号

             break;

        case '=':

        {

             ch = fgetc(fp);               //超前读取'='后面的字符

             if (ch == '=')                //==等于号

             {

                 token.push_back(ch);  //将'='后面的'='存入token中

                 code = TK_EQ;        //单词为"=="

             }

             else {                        //=赋值运算符

                 code = TK_ASSIGN;     //单词为"="

                 fseek(fp, -1L, SEEK_CUR); //将超前读取的字符重新读取

             }

        }

        break;

        case '<':

        {

             ch = fgetc(fp);               //超前读取'<'后面的字符

             if (ch == '=')                //<=小于等于号

             {

                 token.push_back(ch);  //将'<'后面的'='存入token中

                 code = TK_LEQ;            //单词为"<="

             }

             else {                        //<小于号

                 code = TK_LT;        //单词为"<"

                 fseek(fp, -1L, SEEK_CUR); //将超前读取的字符重新读取

             }

        }

        break;

        case '>':

        {

             ch = fgetc(fp);               //超前读取'>'后面的字符

             if (ch == '=')                //>=大于等于号

             {

                 token.push_back(ch);  //将'>'后面的'='存入token中

                 code = TK_GEQ;            //单词为">="

             }

             else {                        //>大于号

                 code = TK_GT;        //单词为">"

                 fseek(fp, -1L, SEEK_CUR); //将超前读取的字符重新读取

             }

        }

        break;

        /*分界符*/

        case '(': code = TK_OPENPA;        //(左圆括号

             break;

        case ')': code = TK_CLOSEPA;   //)右圆括号

             break;

        case '[': code = TK_OPENBR;        //[左中括号

             break;

        case ']': code = TK_CLOSEBR;   //]右中括号

             break;

        case '{': code = TK_BEGIN;    //{左大括号

             break;

        case '}': code = TK_END;      //}右大括号

             break;

        case ',': code = TK_COMMA;    //,逗号

             break;

        case ';': code = TK_SEMOCOLOM; //;分号

             break;

        case':':code = TK_MAO;//:冒号

             break;

             //未识别符号

        default: code = TK_UNDEF;

        }

        print(code);              //打印词法分析结果

    }

}

定义了如下数据结构作为状态终态:

    /* 关键字 */

    KW_VOID, //void关键字

    KW_MAIN, //main关键字

    KW_INT,      //int关键字

    KW_DOUBLE,   //double关键字

    KW_FOR,      //for关键字

    KW_WHILE,    //while关键字

    KW_SWITCH,   //switch关键字

    KW_CASE, //case关键字

    KW_IF,       //if关键字

    KW_ELSE, //else关键字

    KW_RETURN,   //return关键字

    KW_BREAK,//break关键字

    /* 运算符 */

    TK_PLUS, //+加号

    TK_MINUS,    //-减号

    TK_STAR, //*乘号

    TK_DIVIDE,   ///除号

    TK_ASSIGN,   //=赋值运算符

    TK_EQ,       //==等于号

    TK_LT,       //<小于号

    TK_LEQ,      //<=小于等于号

    TK_GT,       //>大于号

    TK_GEQ,      //>=大于等于号

    TK_MAO,    //:冒号

    /* 分隔符 */

    TK_OPENPA,   //(左圆括号

    TK_CLOSEPA//)右圆括号

    TK_OPENBR,   //[左中括号

    TK_CLOSEBR//]右中括号

    TK_BEGIN,    //{左大括号

    TK_END,      //}右大括号

    TK_COMMA,    //,逗号

    TK_SEMOCOLOM, //;分号

    /* 常量 */

    TK_INT,      //整型常量

    TK_DOUBLE,   //浮点型常量

    /* 标识符 */

TK_IDENT

  为了使得输出有所取分,使用不同颜色输出:

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED); //未识别的符号为红色

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);    //关键字为蓝色

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);   //运算符和分隔符为绿色

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);   //常量为黄色

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY); //关键字为灰色

利用文件作为输入。

输入文档1.txt:

double add(double x, double y)

{

    double a = 3.456;

    return x + y;

}

$

int main()

{

            int i;

            switch(i)

           {

               case 1:   break;

            }

            if(double(i,i)>i)

                  break;

            int a[10];

}         

输出结果为:

其中注意红色标记:

说明我们实现了错误识别的功能。

  • 源代码

#include <iostream>

#include <string>

#include <Windows.h>

using namespace std;

/* 单词编码 */

enum TokenCode

{

    /*未定义*/

    TK_UNDEF = 0,

    /* 关键字 */

    KW_VOID, //void关键字

    KW_MAIN, //main关键字

    KW_INT,      //int关键字

    KW_DOUBLE,   //double关键字

    KW_FOR,      //for关键字

    KW_WHILE,    //while关键字

    KW_SWITCH,   //switch关键字

    KW_CASE, //case关键字

    KW_IF,       //if关键字

    KW_ELSE, //else关键字

    KW_RETURN,   //return关键字

    KW_BREAK,//break关键字

    /* 运算符 */

    TK_PLUS, //+加号

    TK_MINUS,    //-减号

    TK_STAR, //*乘号

    TK_DIVIDE,   ///除号

    TK_ASSIGN,   //=赋值运算符

    TK_EQ,       //==等于号

    TK_LT,       //<小于号

    TK_LEQ,      //<=小于等于号

    TK_GT,       //>大于号

    TK_GEQ,      //>=大于等于号

    TK_MAO,    //:冒号

    /* 分隔符 */

    TK_OPENPA,   //(左圆括号

    TK_CLOSEPA//)右圆括号

    TK_OPENBR,   //[左中括号

    TK_CLOSEBR//]右中括号

    TK_BEGIN,    //{左大括号

    TK_END,      //}右大括号

    TK_COMMA,    //,逗号

    TK_SEMOCOLOM, //;分号

    /* 常量 */

    TK_INT,      //整型常量

    TK_DOUBLE,   //浮点型常量

    /* 标识符 */

    TK_IDENT

};

TokenCode code = TK_UNDEF;    //记录单词的种别码

const int MAX = 12;               //关键字数量

int row = 1;                  //记录字符所在的行数

string token = "";                //用于存储单词

char  keyWord[][10] = { "void","main","int","double","for","while","switch","case","if","else","return","break"};    //存储关键词

void print(TokenCode code)

{

    switch (code)

    {

        /*未识别的符号*/

    case TK_UNDEF:

        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED); //未识别的符号为红色

        cout << '(' << code << ',' << token << ")" << "未识别的符号在第" << row << "行。" << endl;

        return;

        break;

        /*关键字*/

    case KW_VOID:

    case KW_MAIN:

    case KW_INT:    

    case KW_DOUBLE

    case KW_FOR:    

    case KW_WHILE:  

    case KW_SWITCH

    case KW_CASE:

    case KW_IF:     

    case KW_ELSE:

    case KW_RETURN

    case KW_BREAK:

        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);    //关键字为蓝色

        break;

        /* 运算符 */

    case TK_PLUS:

    case TK_MINUS:  

    case TK_STAR:

    case TK_DIVIDE

    case TK_ASSIGN

    case TK_EQ:     

    case TK_LT:     

    case TK_LEQ:

    case TK_GT:     

    case TK_GEQ:        

    /* 分隔符 */

    case TK_OPENPA

    case TK_CLOSEPA:

    case TK_OPENBR

    case TK_CLOSEBR:

    case TK_BEGIN:  

    case TK_END:

    case TK_COMMA:  

    case TK_SEMOCOLOM:   

    case TK_MAO:   

        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);   //运算符和分隔符为绿色

        break;

        /* 常量 */

    case TK_INT:

    case TK_DOUBLE

        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);   //常量为黄色

        if (token.find('.') == token.npos)

             cout << '(' << code << ',' << atoi(token.c_str()) << ")" << endl;                     

        else

             cout << '(' << code << ',' << atof(token.c_str()) << ")" << endl;                         

        return;

        break;

        /* 标识符 */

    case TK_IDENT:

        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY); //关键字为灰色

        break;

    default:

        break;

    }

    cout << '(' << code << ',' << token << ")" << endl;

}

bool isKey(string token)

{

    for (int i = 0; i < MAX; i++)

    {

        if (token.compare(keyWord[i]) == 0)

             return true;

    }

    return false;

}

int  getKeyID(string token)

{

    for (int i = 0; i < MAX; i++)

    {   //关键字的内码值为keyWord数组中对应的下标加1

        if (token.compare(keyWord[i]) == 0)

             return i + 1;

    }

    return -1;

}

bool isLetter(char letter)

{

    if ((letter >= 'a' && letter <= 'z') || (letter >= 'A' && letter <= 'Z'))

        return true;

    return false;

}

bool isDigit(char digit)

{

    if (digit >= '0' && digit <= '9')

        return true;

    return false;

}

void lexicalAnalysis(FILE* fp1)

{

    char ch;        

    while ((ch = fgetc(fp1)) != EOF)  

    {

        token = ch;                                   

        if (ch == ' ' || ch == '\t' || ch == '\n'

        {

             if (ch == '\n')                           

                 row++;

             continue;                                

        }

        else if (isLetter(ch))       

        {

             token = "";                  

             while (isLetter(ch) || isDigit(ch))

             {

                 token.push_back(ch); 

                 ch = fgetc(fp1);     

             }

             fseek(fp1, -1L, SEEK_CUR);

             if (isKey(token))

                 code = TokenCode(getKeyID(token));

             else

                 code = TK_IDENT;

        }

        else if (isDigit(ch))

        {

             int isdouble = 0;

             token = "";         

             while (isDigit(ch))  

             {

                 token.push_back(ch);     

                 ch = fgetc(fp1);             

                

                 if (ch == '.' && isdouble == 0)

                 {

                     if (isDigit(fgetc(fp1)))

                     {

                         isdouble = 1;   

                         fseek(fp1, -1L, SEEK_CUR);   

                         token.push_back(ch);         

                         ch = fgetc(fp1);             

                     }

                 }

             }

             if (isdouble == 1)

                 code = TK_DOUBLE;

             else

                 code = TK_INT;               

             fseek(fp1, -1L, SEEK_CUR);

        }

        else switch (ch)

        {

        case '+': code = TK_PLUS;                 

             break;

        case '-': code = TK_MINUS;   

             break;

        case '*': code = TK_STAR;             

             break;

        case '/': code = TK_DIVIDE;       

             break;

        case '=':

        {

            ch = fgetc(fp1);             

             if (ch == '=')               

             {

                 token.push_back(ch); 

                 code = TK_EQ;       

             }

             else {                       

                 code = TK_ASSIGN;    

                 fseek(fp1, -1L, SEEK_CUR);

             }

        }

        break;

        case '<':

        {

             ch = fgetc(fp1);             

             if (ch == '=')               

            {

                 token.push_back(ch); 

                 code = TK_LEQ;           

             }

             else {                       

                 code = TK_LT;       

                 fseek(fp1, -1L, SEEK_CUR);

             }

        }

        break;

        case '>':

        {

             ch = fgetc(fp1);             

             if (ch == '=')               

             {

                 token.push_back(ch); 

                 code = TK_GEQ;           

             }

             else {                       

                 code = TK_GT;       

                 fseek(fp1, -1L, SEEK_CUR);

             }

        }

        break;

       

        case '(': code = TK_OPENPA;       

             break;

        case ')': code = TK_CLOSEPA;  

             break;

        case '[': code = TK_OPENBR;       

             break;

        case ']': code = TK_CLOSEBR;  

             break;

        case '{': code = TK_BEGIN;   

             break;

        case '}': code = TK_END;     

             break;

        case ',': code = TK_COMMA;   

             break;

        case ';': code = TK_SEMOCOLOM;

             break;

        case':':code = TK_MAO;

             break;

            

        default: code = TK_UNDEF;

        }

        print(code);              //打印词法分析结果

    }

}

int main()

{

    string filename;     

    FILE* fp1;               

    cout << "请输入源文件名:" << endl;

    while (true) {

        cin >> filename;     

        if ((fopen_s(&fp1, filename.c_str(), "r")) == 0)    

             break;

        else

             cout << "路径输入错误!" << endl; 

    }

    cout << "/=***************************词法分析结果***************************=/" << endl;

    lexicalAnalysis(fp1);     //词法分析

    fclose(fp1);

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); //字体恢复原来的颜色

    return 0;

}

  • 实验总结

这是编译原理的第一次实验,之前因为理解题意不明,也与老师探讨了多次,上网查阅各种资料等等,最终终于完成了实验。

在实验过程中发生过种种问题,一开始为图方便,想到过使用硬编码来实现实验,但最终还是使用了FA的方式。

通过本次实验,我对NFA、DFA的知识有了更深入的了解,编程能力也进一步增强,可以说这次实验是我对编译原理与实际应用的第一次初步实现,对我的影响深远!

相关文章:

编译原理第一次实验报告

源代码及附件&#xff1a;编译原理实验一源程序及附件资源-CSDN文库实验题目 实验要求 实验设计 前两部分指出了实验的宏观把控&#xff0c;为了具体实施实验&#xff0c;我们需要预先为实验做出如下设计&#xff1a; 本次实验我选取了C语言的一个子集进行设计词法分析器&…...

uniapp的video视频属性打包app后层级过高

问题&#xff1a;在使用uniapp开发APP时&#xff0c;使用video标签显示视频发现H5可以正常展示&#xff0c;但是打包到APP后&#xff0c;它的层级过高&#xff0c;把底部导航都盖住了。 官网说明&#xff1a;uni-app官网 官网给了cover-view组件或plus.nativeObj.view、subNVue…...

问:Redis为什么这么快?

Redis&#xff0c;全称Remote Dictionary Server&#xff0c;是一个开源的高性能键值对数据库。它以其卓越的性能、丰富的数据结构和灵活的使用方式&#xff0c;在现代互联网应用中扮演着重要角色。本文将探讨Redis之所以快的原因&#xff0c;包括其数据结构、内存管理、IO多路…...

环信鸿蒙IM SDK实现附件消息发送与下载

环信HarmonyOS IM SDK 正式版已经发布&#xff0c;该版本全面覆盖即时通讯&#xff08;IM&#xff09;的核心功能&#xff0c;为用户提供了完整的IM全功能体验&#xff0c;同时支持从Android APK到 NEXT 的数据迁移&#xff0c;更好地满足企业在不同业务场景下的适配需求。 点…...

探索NetCat:网络流量监测与数据传输的利器

从简单的数据传输到复杂的网络调试&#xff0c;NetCat的灵活性和多功能性让人赞叹不已&#xff0c;在这篇文章中我将深入探讨NetCat的魅力&#xff0c;揭示它的基本功能、实用技巧以及在日常工作中的应用场景&#xff0c;发现如何用这一小工具提升的网络技能与效率。 目录 Net…...

【运动的&足球】足球运动员球守门员裁判检测系统源码&数据集全套:改进yolo11-DBBNCSPELAN

改进yolo11-FocalModulation等200全套创新点大全&#xff1a;足球运动员球守门员裁判检测系统源码&#xff06;数据集全套 1.图片效果展示 项目来源 人工智能促进会 2024.10.28 注意&#xff1a;由于项目一直在更新迭代&#xff0c;上面“1.图片效果展示”和“2.视频效果展示…...

求最大公约数,最小公倍数

输入两个正整数 m 和 n&#xff0c;求其最大公约数和最小公倍数。 求最小公倍数算法&#xff1a; 最小公倍数 两整数的乘积 最大公约数 根据求最小公倍数的算法&#xff0c;可以看出如果已知最大公约数&#xff0c;就能很容易求出最小公倍数。而通过辗转相除法和相减法&#…...

Android——横屏竖屏

系统配置变更的处理机制 为了避免横竖屏切换时重新加载界面的情况&#xff0c;Android设计了一中配置变更机制&#xff0c;在指定的环境配置发生变更之时&#xff0c;无需重启活动页面&#xff0c;只需执行特定的变更行为。该机制的视线过程分为两步&#xff1a; 修改 Androi…...

scala---10.30

val、var package com_1030class Person {var name:String"rose"def sum(n1:Int,n2:Int):Int{n1n2} } object Person{def main(args: Array[String]): Unit {//创建person对象var personnew Person()println(person.sum(10,20))//30println(person.name)person.nam…...

Pinctrl子需要中client端使用pinctrl过程的驱动分析

往期内容 本专栏往期内容&#xff1a; Pinctrl子系统和其主要结构体引入Pinctrl子系统pinctrl_desc结构体进一步介绍Pinctrl子系统中client端设备树相关数据结构介绍和解析inctrl子系统中Pincontroller构造过程驱动分析&#xff1a;imx_pinctrl_soc_info结构体 input子系统专栏…...

【网络】传输层协议TCP

目录 四位首部长度 序号 捎带应答 标记位 超时重传机制 连接管理机制&#xff08;RST标记位&#xff09; 三次握手及四次挥手的原因 TCP的全称是传输控制协议&#xff08;Transmission Control Protocol&#xff09;&#xff0c;也就是说&#xff0c;对于放到TCP发送缓冲…...

00-开发环境 MPLAB IDE 配置

MPLAB IDE V8.83 File 菜单简介 New (CtrlN)&#xff1a; 创建一个新文件&#xff0c;用于编写新的代码。 Add New File to Project...&#xff1a; 将新文件添加到当前项目中。 Open... (CtrlO)&#xff1a; 打开现有文件。 Close (CtrlE)&#xff1a; 关闭当前打开的文件。 …...

<meta property=“og:type“ content=“website“>

<meta property"og:type" content"website"> ​ 这段代码是HTML中的一部分&#xff0c;具体来说&#xff0c;它是一个用于定义Open Graph协议的meta标签。 代码分析 <meta> 标签&#xff1a;这是一个HTML标签&#xff0c;用于在HTML文档的头…...

C++ 实现俄罗斯方块游戏

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

QT打包Macosx应用发布App Store简易流程

1、QC里编译工程&#xff0c;生成Release版的的app文件&#xff1b; 2、运行macdeployqt把需要的文件打包进app文件中&#xff1b; % ~/Qt/5.15.0/clang_64/bin/macdeployqt {编译的app文件所在路径}/Release/xxxx.app 3、使用codesign对app进行签名&#xff0c;如果要发App…...

untiy mlagents 飞机大战 ai训练

前言 之前那个python源码的飞机大战bug过多&#xff0c;还卡顿&#xff0c;难以继续训练。可直接放弃的话又不甘心&#xff0c;所以找了个unity版本的飞机大战继续(终于不卡了)&#xff0c;这次直接使用现成的mlagents库。 过程 前前后后花了两周时间&#xff0c;甚至因此拖…...

从0开始学统计-什么是中心极限定理

引言 中心极限定理&#xff08;Central Limit Theorem, CLT&#xff09;是统计学中的一块基石&#xff0c;它揭示了一个难以置信的数学现象&#xff1a;无论一个随机变量的原始分布如何&#xff0c;只要我们取足够大的样本量&#xff0c;这些样本的平均值&#xff08;或总和&a…...

工具方法 - 个人活动的分类

人类活动的分类是一个复杂的话题&#xff0c;因为人类的活动范围非常广泛且相互交叉。然而&#xff0c;我们可以尝试将人类的活动大致分为以下几个主要类别&#xff1a; 工作活动 工作活动是人类生活中不可或缺的一部分&#xff0c;通常包括以下方面&#xff1a; 1. 职业工作&a…...

11.1组会汇报-基于区块链的安全多方计算研究现状与展望

基础知识 *1.背书&#xff0c;这个词源来自银行票据业务&#xff0c;是指票据转让时&#xff0c;原持有人在票据背面加盖自己的印鉴&#xff0c;证明该票据真实有效、如果有问题就可以找原持有人。 区块链中的背书就好理解了。可以简单的理解为验证交易并声明此交易合法&…...

ubuntu【桌面】 配置NAT模式固定IP

DHCP分配导致虚拟机IP老变&#xff0c;SSH老要重新配置&#xff0c;设成静态方便些 一、设NAT模式 1、设为NAT模式 2、看模式对应的虚拟网卡 - VMnet8 3、共享主机网卡网络到虚拟网卡 - VMnet8 二、为虚拟网卡设置静态IP 记住这个IP 三、设置ubuntu固定IP 1、关闭DHCP并…...

评估 机器学习 回归模型 的性能和准确度

回归 是一种常用的预测模型&#xff0c;用于预测一个连续因变量和一个或多个自变量之间的关系。 那么&#xff0c;最后评估 回归模型 的性能和准确度非常重要&#xff0c;可以帮助我们判断模型是否有效并进行改进。 接下来&#xff0c;和大家分享如何评估 回归模型 的性能和准…...

如何下载安装TestLink?

一、下载TestLink、XAMPP TestLink 下载 |SourceForge.net 备用&#xff1a;GitHub - TestLinkOpenSourceTRMS/testlink-code&#xff1a; TestLink开源测试和需求管理系统 下载XAMPP&#xff1a; Download XAMPP 注意&#xff1a;TestLink与PHP版本有关系&#xff0c;所以XA…...

基于SSM+微信小程序的订餐管理系统(点餐2)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于SSM微信小程序的订餐管理系统实现了管理员和用户。管理端实现了 首页、个人中心、用户管理、菜品分类管理、菜品信息管理、订单信息管理、配送信息管理、菜品评价管理、订单投诉管理、…...

【C++排序 双指针】1996. 游戏中弱角色的数量|1996

本文涉及的基础知识点 排序 C算法&#xff1a;滑动窗口及双指针总结 本题其它解法 【C单调栈 排序】1996. 游戏中弱角色的数量|1996 LeetCode1996. 游戏中弱角色的数量 你正在参加一个多角色游戏&#xff0c;每个角色都有两个主要属性&#xff1a;攻击 和 防御 。给你一个…...

GESP4级考试语法知识(捕捉异常)

参考程序代码&#xff1a; #include <iostream> using namespace std;double divide(double a, double b) {if (b 0) {throw "Division by zero error"; // 抛出异常}return a / b; }int main() {double num1, num2;cout << "Enter two numbers:…...

HTML 基础标签——元数据标签 <meta>

文章目录 1. `<meta>` 标签概述2. 属性详解2.1 `charset` 属性2.2 `name` 属性2.3 `content` 属性2.4 `http-equiv` 属性3. 其他常见属性小结在 HTML 文档中,元数据标签 <meta> 是一种重要的标签,用于提供关于文档的信息,这些信息不直接显示在网页内容中,但对于…...

栈虚拟机和寄存器虚拟机,有什么不同?

本来这节内容是打算直接讲字节码指令的&#xff0c;但讲之前又必须得先讲指令集架构&#xff0c;而指令集架构又分为两种&#xff0c;一种是基于栈的&#xff0c;一种是基于寄存器的。 那不妨我们这节就单独来讲讲栈虚拟机和寄存器虚拟机&#xff0c;它们有什么不同&#xff0…...

Windows下基于fping进行批量IP测试

fping是Linux下一个很好用的IP测试工具&#xff0c;结合代码可以完成批量的IP测试&#xff0c;在网络调试中用途很广。本文是基于fping for Windows结合bat批处理&#xff0c;定制的测试脚本样例。 一、程序信息 本次测试使用fpingV5.1 for Windows版&#xff0c;版本信息如下…...

一款实用的Word文档图片转换与水印保护工具

目录 前言软件功能简介软件实现方法及关键代码 1. Word 文档转图片的实现2. 图片水印添加功能3. 生成数字指纹&#xff08;哈希值&#xff09;4. 保存图片信息到 JSON 文件 软件的实际使用场景软件操作指南 1. 下载和安装2. 操作流程 总结 1&#xff0c;前言 在日常办公和内…...

优化用于传感应用的衬底集成波导技术

ANSYS HFSS 是一款功能强大的电磁仿真软件&#xff0c;支持为微流体生物传感器应用设计和分析衬底集成波导 &#xff08;SIW&#xff09; 技术。它为快速设计优化、材料选择、系统集成和虚拟原型制作提供了一个强大的平台。借助 ANSYS HFSS&#xff0c;研究人员和工程师可以高效…...