【问题标题】:While loop with two conditions joined by an AND operator in HLA. Converting C++ to HLAWhile 循环有两个条件,由 HLA 中的 AND 运算符连接。将 C++ 转换为 HLA
【发布时间】:2021-12-10 11:28:44
【问题描述】:

我想将我的程序从 c++ 翻译(或手动编译)为 HLA。程序读取输入的数字。然后减去三和十或仅十,确定该值是以零还是三结尾。连续三个这样的数字赢得比赛!一个不以这些数字结尾的值就输了。

我不知道如何使用 HLA 中的 AND 运算符连接两个条件来执行 while 循环。

while ((iend != 1) && (iscore < 3))

这是我用 C++ 编写的完整代码,我想把它翻译成 HLA:

#include <iostream>
using namespace std;

int main() {
  int inum;
  int iend = 0;
  int iscore = 0;
  int icheckthree; //To check if it ends in 3
  int icheckzero; //To check if it ends in zero

  while ((iend != 1) && (iscore < 3)) {
    cout << "Gimme a number: ";
    cin >> inum;

    //Case 1: ends in three
    icheckthree = inum - 3;
    while (icheckthree > 0) {
      icheckthree = icheckthree - 10;
      if (icheckthree == 0) {
        cout << "It ends in three!" << endl;
        iscore++;
      }
    }

    icheckzero = inum;
    while (icheckzero > 0) {
      icheckzero = icheckzero - 10;
    }
    //Case 2: ends in zero
    if (icheckzero == 0) {
      cout << "It ends in zero!" << endl;
      iscore++;
    }
    //Case 3: Loose the game
    else {
      if (icheckzero != 0) {
        if(icheckthree != 0) {
          iend = 1;
        }
      }
    }
    
    if (iend == 1) {
      cout << "\n";
      cout << "Sorry Charlie!  You lose the game!" << endl;
    }
    else if (iscore == 3) {
      cout << "\n";
      cout << "You Win The Game!" << endl;
    } else {
      cout << "Keep going..." << endl;
      cout << "\n";
    }
  }
}

【问题讨论】:

  • 通常只有两个独立的 cmp/jcc,任何一个都可以让你脱离循环。看看 C 编译器如何在 godbolt.org 上执行此操作。 (当然 C 编译器会使用普通的 asm,而不是 HLA,但指令是一样的。)

标签: c++ assembly compilation translate hla


【解决方案1】:

使用逻辑转换。

例如语句:

if ( <c1> && <c2> ) { <do-this-when-both-true> }

可以翻译成:

if ( <c1> ) {
    if ( <c2> ) {
        <do-this-when-both-true>
    }
}

这两个结构是等价的,但后者不使用连词。


if-goto-label 可以采用 while 循环,如下所示:

while ( <condition> ) {
    <loop-body>
}

Loop1:
    if ( <condition> is false ) goto EndLoop1;
    <loop-body>
    goto Loop1;
EndLoop1:

接下来,单独的 if 语句涉及取反的连词 &&,如下所示:

if ( <c1> && <c2> is false ) goto label;

又名

if ( ! ( <c1> && <c2> ) ) goto label;


简化如下:

if ( ! <c1> || ! <c2> ) goto label;

这是根据德摩根的逻辑定律,将否定与合取和析取联系起来。


最后,上面的析取可以很容易地简化(类似于上面的合取简化)如下:

   if ( ! <c1> ) goto label;
   if ( ! <c2> ) goto label;

如果while循环的条件是合取(&&),你可以把上面的变换放在一起来创建一个条件退出析取序列。

【讨论】:

  • 是的,我在 //Case 3: Loose the game else { if (icheckzero != 0) { if(icheckthree != 0) { iend = 1; } } } 但我不知道如何让它在 while 循环中工作
  • 逻辑转换。尽可能多地使用。查看我的编辑。
猜你喜欢
  • 1970-01-01
  • 2021-10-19
  • 2012-09-04
  • 1970-01-01
  • 2012-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-19
相关资源
最近更新 更多