C语言实现简单计算器

article/2025/10/24 0:32:52

C语言实现简单计算器

  • 一、背景
  • 二、代码
  • 1、数据结构
  • 2、弟弟行为的编程
  • 三、基本逻辑
    • 中缀转后缀
      • (1)为什么要转
      • (2)怎么转
      • (3)注意事项
  • 四、演示图片

一、背景

自己希望通过这个处女帖,来互相学习、经验积累,故将本次课设的代码发到CSDN,希望可以得到网友们的指点。我用的是DEVC++,作出来后,能实现简单的整数加减乘除。

二、代码

1、数据结构

下面展示全部的头文件。

//简单的计算器
#include<iostream>
#include<cstring>
#include<math.h>
#include<windows.h>
#define E 10000000	//定义一个极大值,读取到加减乘除时将加减乘除+E,
//压入int类型栈里,表示加减乘除 
#define MAXSIZE 100 //栈容量 using namespace std;
typedef char ElemType;typedef struct {	//定义char栈 ElemType *base;	//栈底指针 ElemType *top;	//栈顶指针 int stacksize;	//栈的容量 
}SqStack;
typedef struct {	//定义int栈 int *base;int *top;int stacksize;
}SqStack_int;//分别初始化char、int类型栈 
int InitStack(SqStack &S);	//S为要初始化的栈 
int InitStack_int(SqStack_int &S);//S为要初始化的栈 //分别做char、int类型栈的入栈出栈 
int Push_char(SqStack &S,ElemType e);	//S为要初始化的栈 ,e为要入栈元素 
int Push_int(SqStack_int &S,int e);	//S为要初始化的栈 ,e为要入栈元素
char Pop_char(SqStack &S,ElemType &e);//S为要初始化的栈 ,e为要出栈元素
char Pop_int(SqStack_int &S,int &e);//S为要初始化的栈 ,e为要出栈元素
ElemType GetTop(SqStack S);	//返回ElemType类型S栈顶元素 
int Empty(SqStack S);	//S栈判空 
int Length(SqStack_int S);	//返回int类型S栈元素个数 
int replace(char a);	//给运算符a赋值 
int compare(char a,char b);	//a为栈顶运算符,b为扫描到的运算符,返回他们优先级对比的结果 
void count(int a[],int m);	//计算 后缀表达式a的值并输出 ,m表示表达式位数 
int jisuan();	//中缀转后缀,并且划分各个整数 ,返回运算状态,s值控制是否进行该操作 
void xunhuan(int x);//循环函数,让用户循环多次使用 ,x值控制是否循环和判断用户输入正确与否 
void rel(SqStack_int &S,SqStack &S_num,SqStack &S_fuhao,char x);//判断优先级并且入栈出栈 

2、弟弟行为的编程

int main(){	//主函数 system("mode con cols=38 lines=25");//窗口宽度高度char s;			//char类型的s做判断用户是否进入计算器的控制元素 printf("欢迎使用简单计算器!\n该计算器可以运算多位的正负整数\n");	//使用指导 system("title 简单计算器");    //设置cmd窗口标题system("color 0c");		// 设置窗口颜色 printf("是否使用计算器(Y/N):"); 	//用户输入Y/N进行选择是否进入计算器 cin>>s;		//用户输入 if(s=='N')	printf("已退出计算器!");	//N表示退出,执行退出 while(s!='N'){		//如果不是N,有两种情况进行判断和循环 if(s=='Y'){			//第一种情况:Y则进入计算器 xunhuan(jisuan()); 	//运用循环函数,进行递归循环,实现循环计算 break;	//当上个循环只有用户选择退出时才会结束循环,之后直接break,结束程序 }elseprintf("输入错误,请重新输入,是否使用计算器(Y/N):");//第二种情况 :输入错误(不是Y也不是N),继续让用户选择 cin>>s;	//输入s进行循环 }	 return 0;	//程序正常结束 
}int InitStack(SqStack &S)	//SqStack类型S栈初始化 
{S.base=new ElemType[MAXSIZE];	//分配空间 if(!S.base)	return -1;	//如果分配失败返回-1 S.top=S.base;		//初始化为空栈 S.stacksize=MAXSIZE;	//S的容量设为MAXSIZE return 1;} //同上个S栈的初始化 ,只不过这里是SqStack_int 类型的S栈 int InitStack_int(SqStack_int &S)
{S.base=new int[MAXSIZE];if(!S.base)	return -1;S.top=S.base;S.stacksize=MAXSIZE;return 1;} int Push_char(SqStack &S,ElemType e)	//将元素e入SqStack类型的S栈 
{if(S.top-S.base==S.stacksize)	return -1;	//如果栈满则无法入栈 *S.top++=e;	//将e赋值给top指针所指位置,栈顶指针top加一 return 1;	
}//同上面入栈操作,只是入栈元素类型 和栈类型不同 
int Push_int(SqStack_int &S,int e)
{if(S.top-S.base==S.stacksize)	return -1;*S.top++=e;return 1;	
}char Pop_char(SqStack &S,ElemType &e)	//S栈栈顶元素出栈  
{if(S.top==S.base)	return printf("错误");	//如果栈空,返回错误 e=*--S.top;	//栈顶指针减一,之后栈顶元素值赋值给 e return e; 	//返回e值 
}//同上面操作,只是类型不同 
char Pop_int(SqStack_int &S,int &e)
{if(S.top==S.base)	return printf("错误");e=*--S.top;return e; 
}ElemType GetTop(SqStack S)//取S栈栈顶元素 
{if(S.top!=S.base)	//如果S栈非空返回 栈顶元素值 return *(S.top-1);else return '#';	//否则返回"#" 
}int Empty(SqStack S){//判断S栈是否为空 if(S.top-S.base==0)	//栈空返回1,否则返回0 return  1;return 0;
}int Length(SqStack_int S)//求S栈的元素个数 
{return (S.top-S.base);
}int replace(char a)//判断a符号优先级
{switch (a)//考虑运算符a的类型,并且对相应的类型赋值 {case '+':return 1;case '-':return 1;case '*':return 2;case '/':return 2;case '(':return 0;case '#':return 0;}
}
int compare(char a,char b)//对比a和b符号的优先级 
{return (replace(a)<replace(b)) ? 1:0;//如果b优先级大于a则返回0,否则返回1 }
void count(int a[],int m)
//计算元素个数m的表达式a 
{SqStack_int Sw;//定义一个SqStack_int类型的栈Sw InitStack_int(Sw);//Sw栈初始化 for(int h=0;h<m;h++){//循环遍历表达式,判断其中数字是代表运算符还是数字 //10000045、10000042、10000047、10000043分别对应4个运算符 if(a[h]!=10000045&&a[h]!=10000042&&a[h]!=10000047&&a[h]!=10000043){Push_int(Sw,a[h]);//数字入栈 }else{//如果出现上述4个数字,表示是运算符 int c,d,sum;//分类讨论+—*/四种情况,并且求值,最后入栈 if(a[h]==10000045){Pop_int(Sw,c);Pop_int(Sw,d);sum=d-c;Push_int(Sw,sum);}if(a[h]==10000043){Pop_int(Sw,c);Pop_int(Sw,d);sum=c+d;Push_int(Sw,sum);}if(a[h]==10000042){Pop_int(Sw,c);Pop_int(Sw,d);sum=c*d;Push_int(Sw,sum);}if(a[h]==10000047){Pop_int(Sw,c);Pop_int(Sw,d);sum=d/c;Push_int(Sw,sum);}}}int x;Pop_int(Sw,x);//将最后的栈内计算出的最后结果出栈,赋值给x printf("%d\n",x);//输出最后结果x 
}int jisuan()//进行中缀转后缀 
{printf("请输入您想计算的表达式(输入#退出):\n");//定义SqStack_int类型的栈S,用于存储int类型的最终表达式 SqStack_int S;	//定义SqStack类型的S_num、S_fuhao,用于中缀转后缀用 SqStack S_num,S_fuhao;InitStack_int(S);InitStack(S_num);InitStack(S_fuhao);int tag=0;	//tag的值表示输入的数字以后应该转化为几位数 char e;//e用来存储后面的出栈元素 char ex[100];//定义一个容量为100的字符串,供用户输入表达式 cin>>ex;	//输入 if(ex[0]=='#')	return 1;//如果输入#号表示用户不想继续使用计算器了,则返回1 for(int x=0;ex[x]!='\0';x++){	//判断输入的内容合不合规 if(ex[x]!='+'&&ex[x]!='-'&&ex[x]!='*'&&ex[x]!='/'&&ex[x]!='('&&ex[x]!=')'&&ex[x]!='1'&&ex[x]!='2'&&ex[x]!='3'&&ex[x]!='4'&&ex[x]!='5'&&ex[x]!='6'&&ex[x]!='7'&&ex[x]!='8'&&ex[x]!='9'&&ex[x]!='0'){printf("错误");return -1;	//如果输入的不合规返回-1 }
}for(int i=0;ex[i]!='\0';i++){		//开始遍历字符串 if(ex[i]!='+'&&ex[i]!='-'&&ex[i]!='*'&&ex[i]!='/'&&ex[i]!='('&&ex[i]!=')'){	//遍历到元素是数字 if(i==0&&ex[i]=='0'){	//考虑第一个数字是 0的情况 int a=ex[i]-48;	//将字符类型的0转化成int类型的0 Push_int(S,a);	//入S栈 continue;	//跳过该i值 ,进行下个i值循环 }tag++;			//tag记录数字个数,后面Pop划成一个整数用 Push_char(S_num,ex[i]);//将ex[i] 的值入S_num栈 }else{			//遍历到运算符 if(i==0&&ex[i]=='-'){	//讨论如果第一个数是负数情况 int cn=0,mk=0;for(int j=1;ex[i+j]!='+'&&ex[i+j]!='-'&&ex[i+j]!='*'&&ex[i+j]!='/';j++){	//第一个负数格式为 -xx 是一个整数 cn++;	//判断第一个元素是负数,除第一个负号外,数字所占的位数 }	 for(int k=0;k<cn;k++){// 把入的数字元素划成整数 mk+=(ex[k+1]-48)*pow(10,cn-k-1);//每位累加,最后 mk为最终整数值 }Push_int(S,0-mk);	//压入int栈一个负数,0-mk //跳过这个负数继续向后遍历 i+=cn;	continue;}if(ex[i]=='('&&ex[i+1]=='-'){	//讨论如果是括号内负数情况 int cn=0,mk=0;Push_char(S_fuhao,ex[i]);for(int j=2;ex[i+j]!=')'&&ex[i+j]!='+'&&ex[i+j]!='-'&&ex[i+j]!='*'&&ex[i+j]!='/';j++){	//负数格式必须为(-xx) xx是一个整数 cn++;}	 for(int k=0;k<cn;k++){// 把入的数字元素划成整数 mk+=(ex[i+cn+1-k]-48)*pow(10,k);}Push_int(S,0-mk);	//压入int栈一个负数,0-mk i+=cn+1;	//跳过这个负数继续向后遍历 continue;//进行下一个i值循环 }if(tag==0){			//如果扫描到符号前,tag==0,表示之前没有数字字符 if(Empty(S_fuhao)||ex[i]=='(')	//如果是空栈或者左括号 {Push_char(S_fuhao,ex[i]);//直接入S_fuhao栈 continue;//进行下一个i值循环 }rel(S,S_num,S_fuhao,ex[i]); }//如果扫描到运算符之前tag!=0,则需先Pop出数字字符,进行整合成一个整数 else{int a=0;//a是最后的数字元素整合结果 for(int lk=0;lk<tag;lk++){char ad;Pop_char(S_num,ad);int ax=ad;a+=(ax-48)*pow(10,lk);}Push_int(S,a);//将a入S栈 tag=0;//最后将计数器tag置零 rel(S,S_num,S_fuhao,ex[i]);}}}if(tag!=0){	//处理字符串最后的数字,进行出栈求值再入栈 int a=0;for(int lk=0;lk<tag;lk++){char ad;Pop_char(S_num,ad);int ax=ad;a+=(ax-48)*pow(10,lk);}Push_int(S,a);tag=0;}while(!Empty(S_fuhao)){	//清空符号栈,将剩余的符号出S_fuhao栈,再+E入S栈 Pop_char(S_fuhao,e);Push_int(S,e+E);}int m=Length(S);//m表示栈S的元素个数 int a[m];//a[m] for(int qw=m-1;qw>-1;qw--){Pop_int(S,a[qw]);} count(a,m);//计算后缀表达式 return 2;//如果程序循行到这里,说明是正常运行,返回2 
}void rel(SqStack_int &S,SqStack &S_num,SqStack &S_fuhao,char x)//判断优先级并且 入栈出栈 
{char e;if(x==')'){//如果是右括号 while(GetTop(S_fuhao)!='('){//取S_fuhao 栈的栈顶元素 ,如果不是左括号 //将其中的符号挨个出栈,并且转为int类型元素,再加E Pop_char(S_fuhao,e);Push_int(S,e+E);}	Pop_char(S_fuhao,e);//最后将左括号出栈 }else{//运算符优先级然后入栈 if(compare(GetTop(S_fuhao),x))	 Push_char(S_fuhao,x);//扫描到的元素比栈顶元素优先级高,直接入S_fuhao栈 else{//否则进行S_fuhao栈栈顶元素先出栈后+E入S栈Pop_char(S_fuhao,e);Push_int(S,e+E);while(!compare(GetTop(S_fuhao),x)){//只要扫描到的该符号的 优先级不大于栈顶元素优先级 ,就重复之前的出栈,+E入S栈的操作 Pop_char(S_fuhao,e);Push_int(S,e+E); }Push_char(S_fuhao,x);//最后将这个扫描的运算符入S_fuhao栈 }	}
}void xunhuan(int x){ //循环函数 ,根据x的值进行循环、退出、判断输入是否正确 if(x==-1){	//如果x是-1,则提示输入错误 printf("输入错误,是否重新输入(Y/N):");char s;//定义一个char类型的s cin>>s;//用户输入s switch(s){//s代表用户在输入错误的表达式时是否还想继续输入表达式求值 case 'Y'://如果s是符号Y xunhuan(jisuan());//继续进行循环计算 case 'N':	//如果s是符号N printf("正在退出...");//表示用户想退出,页面提示正在退出。。。 break;//终止该循环 default://否则表示用户输入的错误 xunhuan(-1); //将-1赋值给该循环函数,继续 让用户进行使用选择 }}if(x==2) xunhuan(jisuan()); //如果x是2,将jisuan()函数带入循环函数,继续运行循环函数,实现循环计算的功能 int i=1;while(i>0){//做一次循环 i--;if(x==1){//如果x是1 ,表明用户想要退出 printf("正在退出...");//提示正在退出。。。 break;//终止该循环 }} 
}

三、基本逻辑

中缀转后缀

(1)为什么要转

因为我们平时计算的表达式都是中缀表达式,但是相比中缀,电脑更喜欢计算后缀表达式。实现逆波兰式的算法,难度并不大,但为什么要将看似简单的中缀表达式转换为复杂的逆波兰式?原因就在于这个简单是相对人类的思维结构来说的。但是对计算机而言中序表达式是非常复杂的结构。相对的,逆波兰式在计算机看来却是比较简单易懂的结构。因为计算机普遍采用的内存结构是栈式结构,它执行先进后出的顺序。

(2)怎么转

说到中缀转后缀表达式,肯定第一想法就是建两个栈,一个存储运算符,一个存储操作数。然后循环遍历扫描输入的字符串,遇到数字直接入操作数栈,遇到运算符分类讨论,最后将整个字符串都入到操作数栈。最后转成后缀表达式。

但是我所做的还与这个有些不同,因为传统的中缀转后缀一般都是1位数的,如果要实现多位数,还需要对字符串类型数字进行划分整合。所以多位数相比个位数的中缀转后缀可以说是有些难了。

具体思想如下:

我是定义并初始化了三个栈;S,S_num,S_fuhao,S用于存储最终的后缀表达式,S_num作为中转站,存储字符串类型的数字,通过入栈出栈,进行操作数整合,并且类型装换成int,入S栈,而S_fuhao也是一个中转栈,将转成后缀的符号入S栈。
依旧先是循环遍历,因为输入的是字符串,所以并不是一个数字代表一个int型整数,得用一个tag计数器进行位数记录,然后扫描到运算符后,根据tag值进行字符串型的数字划分,将各个字符串型的数字整合成各自的int型整数。遇到左括号和右括号依旧跟传统处理办法一样,遇到左括号直接入栈,遇到右括号扫描之前的符号,直到扫描到左括号,将括号内的符号和操作数进行出入栈操作,最后将左括号出栈。遇到加减乘除,则开始判断优先级。之后进行出栈入栈操作,在最终入栈时,我直接定义了一个E,E的值为1亿,将加减乘除最终入S栈时都与E相加,将这4个破亿的int型整数代表加减乘除,这样S栈内的数据只要不是破亿,都不会影响结果。以此循环,最后清理S_num和S_fuhao栈,将里面的剩余元素出栈,入S栈。

(3)注意事项

1.因为输入的是字符串,所以并不是一个数字代表一个int型整数,得用一个tag计数器进行位数记录,然后扫描到运算符后,根据tag值进行字符串型的数字划分,将各个字符串型的数字整合成各自的int型整数。
2.考虑负数所在的位置(首位:“-3+2”,中间:“3*(-3)”)
3.考虑字符0在开头想要表示的数字就是int型的0该如何处理
4.运算符优先级判断

下面展示一下运算符优先级比较代码

int replace(char a)//判断a符号优先级
{switch (a)//考虑运算符a的类型,并且对相应的类型赋值 {case '+':return 1;case '-':return 1;case '*':return 2;case '/':return 2;case '(':return 0;case '#':return 0;}
}
int compare(char a,char b)//对比a和b符号的优先级 
{return (replace(a)<replace(b)) ? 1:0;//如果b优先级大于a则返回0,否则返回1 }

四、演示图片

在这里插入图片描述 因为自己电脑不知道为什么,没法执行mode指令,导致无法把输出窗口的大小修改成正常计算器大小,但是还是附上了代码,别的计算机应该是可以修改的。

最后希望自己的第一次编程分享可以得到网友们的批评与指正,我会虚心接受建议与指教,谢谢!在这里插入图片描述


http://chatgpt.dhexx.cn/article/i3WOPHJl.shtml

相关文章

PHP实现简单计算器

目录 一、题目&#xff1a; 二、基本界面设计代码&#xff1a; 三、分析&#xff1a; 四、实现编程三个步骤 五、完整实现代码 一、题目&#xff1a; 题目描述&#xff1a;下列列表框中有、-、*、/四种运算符&#xff0c;选择不同的运算符进行&#xff0c;单击计算按钮进行不…

Linux:简单计算器

四则运算 vim一下1. 思路2. 代码分析及展示3. 运行结果 vim一下 用vi编写一个简单的四则运算程序&#xff0c;可以接受键盘输入的两个数和一个运算符号&#xff0c;并在控制台输出结果。 1. 思路 从键盘输入变量的值&#xff0c;获取这个值调用加减乘除这些函数&#xff0c;…

HTML实现简单计算器

简单计算器 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>简易计算器</title><style type"text/css">*{margin: auto;padding: 0px;text-align: center;font-family: "微软雅黑";}.con…

C语言实现简单计算器程序

简单计算器程序 编写一个简单计算器程序&#xff0c;输入格式为&#xff1a;data1 op data2。其中data1和data2是参加运算的两个数&#xff0c;op为运算符&#xff0c;它的取值只能是、-、*、/。。要求必须使用switch-case语句实现。 输出结果精确到小数点后2位&#xff1a;如…

AndroidStudio案例——简单计算器

效果展示 实验内容及步骤 设计一款带有可视化界面的简单计算器&#xff0c;供用户输入数据并查看结果。用户通过点击相应按钮&#xff08;加减乘除运算符、等号、数字&#xff09;输入正确的表达式&#xff0c;计算器进行相应的加减乘除运算&#xff0c;且可以进行小数和整数的…

Android简单计算器

文章目录 一、案列一、步骤1、activity_main.xml2、colors.xml3、strings.xml4、图片 一、案列 实现简易计算器 一、步骤 线性布局实现计算器&#xff0c;一个线性垂直布局里嵌套多个线性水平布局&#xff0c;插入文本框&#xff0c;编辑框&#xff0c;按钮多个控件&#x…

19:简单计算器

原题链接 总时间限制: 1000ms 内存限制: 65536kB 描述 一个最简单的计算器&#xff0c;支持, -, *, / 四种运算。仅需考虑输入输出为整数的情况&#xff0c;数据和运算结果不会超过int表示的范围。 输入 输入只有一行&#xff0c;共有三个参数&#xff0c;其中第1、2个参数…

python制作简单计算器

​ 做一个计算器&#xff0c;这是我们想要的效果。 1、准备工作 导入time、tqdm、math库 from tqdm import* from time import* from math import*2、开始 添加一个重复循环并添加变量s while True:#清屏print(\033c)while True:#如果用法输入的是str类型将打印输入错误&…

JavaScript实现简单计算器

一、两个输入框输入数值计算 步骤 1、编写html代码&#xff0c;实现计算器页面视图效果 2、编写js&#xff0c;实现点击输入数字和符号输出结果 1、编写html 1.1定义两个输入框和一个隐藏框。 1.2定义加减乘除四个按钮&#xff0c;并在里面设置一个单击事件onclick&#…

Java编写简单计算器

本文用Java的swing来实现一个简单计算器&#xff0c;主要内容为图形用户界面GUI的实现以及运算表达式核心算法的设计编写。 程序运行环境为Windows10 &#xff0c;编译环境为IntelliJ IDEA Community Edition 2022.2.3 一、具体功能&#xff1a; 1、&#xff1a;输入&#x…

项目一:简单计算器的实现

项目概述 1.1项目目标和主要内容 学习图形界 面的设计&#xff0c;利用 MFC 应用程序&#xff08;Java swing 或 QT 框架&#xff0c;或 C#&#xff09;创建基于对话框的应用程序&#xff0c;添加按钮、编辑框等控件&#xff1b; 能通过设计的按钮控件输入并实现简单算术运算&a…

【C语言】实现简易计算器

目录 1.实现逻辑 2.运行过程 3.优化前代码分析 主函数 计算函数 4.优化后代码分析 主函数 计算方法函数 输入操作数的函数 5.完整代码展示 1.实现逻辑 实现一个简易的计算器&#xff0c;可以计算两个整数的加减乘除 2.运行过程 3.优化前代码分析 主函数 int main()…

java工作流引擎,roadflow(一个强大的工作流引擎)

JAVA工作流引擎(J-RoadFlow) J-RoadFlow工作流平台是知名的.NET工作流引擎RoadFlow的JAVA移植版。该工作流平台由从事多年OA和工作流实施及开发的团队研发&#xff0c; 采用最简单的SM架构实现大中小企业中日常复杂业务流程审批。JAVA版不仅仅是.NET版本的移植&#xff0c;从架…

Easy-Flows - Java的简单愚蠢的工作流引擎

The simple, stupid workflow engine for Java 源代码名称&#xff1a;easy-flows源代码网址&#xff1a;http://www.github.com/j-easy/easy-flowseasy-flows 源代码文档easy-flows 源代码下载 Git URL git://www.github.com/j-easy/easy-flows.git Git Clone 代码到本地 g…

Flowable工作流引擎

Flowable工作流引擎 Flowable-基础篇(根据BV1Pb4y1p7Ku整理) 一、简介 Flowable是BPMN的一个基于java的软件实现&#xff0c;不过Flowable不仅仅包括BPMN&#xff0c;还有DMN决策表和CMMN Case管理引擎&#xff0c;并且有自己的用户管理、微服务API等一系列功能&#xff0c;…

Java工作流引擎

Java工作流引擎有很多&#xff0c;有免费和商业的 主流免费&#xff1a;Activiti和Flowable Activiti和Flowable都是来自于一个叫JBPM的开源工作流。在早期Jboss发行JBPM4的时候&#xff0c;因为合作伙伴关系闹的不开心。于是其中一个核心人员离职。加入了Alfresco(Activiti所…

工作流引擎技术选型

一、主流开源框架介绍 1、工作流相关文档 1.Camunda 官方文档&#xff1a;https://camunda.com/ 中文文档&#xff1a;介绍 | docs.camunda.org 2.Activiti 官方文档&#xff1a;https://www.activiti.org/ 中文文档&#xff1a;[activiti6用户手册 3.Snaker 官方文档&…

Java开源工作流引擎 介绍

Java开源工作流引擎 http://www.open-open.com/08.htm 身为拿来主义者&#xff0c; 很好的吸取经验才是我们的目的&#xff01; Willow 由Huihoo Power开发详细可到其中文主页查看。 更多Willow信息 OpenWFE OpenWFE是一个开放源码的Java工作流引擎。它是一个完整的业务处理…

最近进行的一次技术选型(工作流引擎)及相关知识介绍

前言 最近有个新项目&#xff0c;需要实现类似工作流引擎的效果&#xff0c;如果不知道是啥&#xff0c;看完本文就懂了。 公司内其实也有些自研的&#xff0c;可能就是不像开源的这些那样&#xff0c;还支持这个那个规范&#xff0c;都是基于需求定制开发的&#xff0c;扩展…

java工作流引擎(j-roadflow)快速入门教程

使用j-roadflow java工作流引擎创建一个流程分为两个步骤&#xff0c;创建表单和创建流程。 一、创建表单。 在流程管理--表单管理下点新建表单即开始创建一个新的表单&#xff1a; 点击之后打开表单设计器并弹出表单属性设置&#xff1a; 表单名称&#xff1a;为您新建的表单…