Qt学习3-Qt Creator四则运算计算器(哔站视频学习记录)

计算器中的“=”按钮这部分的代码解释

目录

制作计算器中的“=”按钮这部分的代码解释

一、代码部分

二、解释

三、思路

四、死循环!


一、代码部分

void Widget::on_equalButton_clicked()
{
    QStack<int> s_num,s_opt; //声明两个int类型变量

    char opt[128]={0};//char型数组
    int i = 0,tmp = 0,num1,num2;//声明变量i,tmp,num1,num2

    //把QString 转换成 char*
    QByteArray ba;//字节数组
    ba.append(expression);//把QString转换成QByteArray
    strcpy(opt,ba.data());//data可以把QByteArray转换成char *

    while(opt[i]!='\0'||s_opt.empty()!=true)//在字符串中'\0'用作字符串的结束标志,字符串没结束且不为空的情况下
    {
        if(opt[i]>='0'&&opt[i]<='9')//字符在0-9之间
        {
            tmp=tmp*10+opt[i]-'0';
            i++;
            if(opt[i]<'0'||opt[i]>'9')//字符不在0-9之间
            {
                s_num.push(tmp);
                tmp = 0;
            }
        }
        else  //操作符
        {
            if(s_opt.empty() == true || Priority(opt[i]) > Priority(s_opt.top()) ||
                                                 (s_opt.top() == '(' && opt[i] != ')'))
            {
                    s_opt.push(opt[i]);
                    i++;
                    continue;
            }

            if(s_opt.top() == '(' && opt[i] == ')')
            {
                s_opt.pop();
                i++;
                continue;
            }

            if (Priority(opt[i]) <= Priority(s_opt.top() || (opt[i] == ')' && s_opt.top()) ||
                                             (opt[i]) == '\0' && s_opt.empty() != true))
            {
                char ch = s_opt.top();
                s_opt.pop();
                switch (ch)
                {
                    case '+':
                        num1 = s_num.top();//取出栈顶元素
                        s_num.pop();//删除栈顶元素
                        num2 = s_num.top();
                        s_num.pop();
                        s_num.push(num2+num1);  //进栈
                        break;
                    case '-':
                        num1 = s_num.top();
                        s_num.pop();
                        num2 = s_num.top();
                        s_num.pop();
                        s_num.push(num2-num1);  //进栈
                        break;
                    case '*':
                        num1 = s_num.top();
                        s_num.pop();
                        num2 = s_num.top();
                        s_num.pop();
                        s_num.push(num2*num1);  //进栈
                        break;
                    case '/':
                        num1 = s_num.top();
                        s_num.pop();
                        num2 = s_num.top();
                        s_num.pop();
                        s_num.push(num2/num1);  //进栈
                        break;
                }
            }
            else  //新增,解决2*3+7死循环时的问题
            {
                s_opt.push(opt[i]);
                i++;
                continue;
            }
        }

    }
    //最后留在栈里的就是结果,将结果显示
    ui->mainLineEdit->setText(QString::number(s_num.top()));  //QString中有个静态成员函数number(),可以把数字转换成字符串。
    expression.clear();
}
int Widget::Priority(char ch)
{
    switch (ch)
    {
        case '(':
            return 3;
        case '*':
        case '/':
            return 2;
        case '+':
        case '-':
            return 1;
        default:
            return 0;
    }
}

pop()删除栈顶元素

top() 是取出栈顶元素,不会删掉栈里边的元素


二、解释

这里有个优先级函数不好理解

三个并列的条件语句:

条件1:if(s_opt.empty() == true || Priority(opt[i]) > Priority(s_opt.top()) ||
                                                 (s_opt.top() == '(' && opt[i] != ')'))

//如果操作符s_opt是空,或者当前操作符的优先级Priority大于栈顶的优先级,或者栈顶的操作符   是‘(’ 不是 ')'           然后把操作符入栈

条件2:if(s_opt.top() == '(' && opt[i] == ')')

//如果操作符是 ‘(’  不是 ')'            直接操作符删除

条件3:if (Priority(opt[i]) <= Priority(s_opt.top() || (opt[i] == ')' && s_opt.top()) ||
                                             (opt[i]) == '\0' && s_opt.empty() != true))

//如果当前的操作符小于栈顶操作符,或者操作符是(且位于栈顶,或者操作符不是字符尾和不是空时   计算+-*/

例如(3-1)+1

  • ‘(’  满足条件1s_opt.empty() == true ,刚开始时s_opt未存入任何操作符,s_opt现在有‘(’
  • ‘-’满足条件1(s_opt.top() == '(' && opt[i] != ')'),s_opt.top()=='('且不等于‘)’
  • ')’满足条件3(Priority(opt[i]) <= Priority(s_opt.top() ,Priority(opt[i])是‘)’的优先级0,Priority(s_opt.top())是‘-’号的优先级1,0<1所有满足条件3,计算3-1,结果保存在s_num=2
  • ')’满足条件2,删除s_opt里面的操作符
  • ‘+’满足条件1s_opt.empty() == true,每次计算都会pop删除栈顶的操作符,所有s_opt此时为0,之前存入的操作符已经被删除完
  • ‘+’满足条件3(Priority(opt[i]) <= Priority(s_opt.top(),Priority(opt[i])是当i=7时的第七个字符‘\0’的优先级是0,Priority(s_opt.top())是‘+’号的优先级1,0<1所有满足条件3,计算2+1=3,结果继续入栈存入s_num中

三、思路

思路理解:

条件1是存入操作符

条件2在s_opt栈顶是'('和当前操作符是‘)’时删除s_opt栈顶操作符

条件3判断操作符优先级,当前操作符 优先级  小于  栈顶优先级时进行计算

四、死循环!

出现问题:运行2*3+7的时候报错!

产生原因:i无法正常加1,一直在i=3时循环

解决方法:

else  //新增,解决2*3+7死循环时的问题
            {
                s_opt.push(opt[i]);
                i++;
                continue;
            }

 完整代码参考博客和哔站QT基础教程:

w代码复现|QT快速入门 (课程来自B站)--其二_OZ__96的博客-CSDN博客

猜你喜欢

转载自blog.csdn.net/qq_26572229/article/details/129356155