简体   繁体   English

2 while循环vs if else语句在1 while循环中

[英]2 while loops vs if else statement in 1 while loop

First a little introduction: 首先介绍一下:

I'm a novice C++ programmer (I'm new to programming) writing a little multiplication tables practising program. 我是一名新手C ++程序员(我是编程新手)编写一个小的乘法表练习程序。 The project started as a small program to teach myself the basics of programming and I keep adding new features as I learn more and more about programming. 该项目最初是一个小程序,用于自学编程的基础知识,随着我对编程的了解越来越多,我不断添加新功能。 At first it just had basics like ask for input, loops and if-else statements. 起初它只是有一些基础知识,比如要求输入,循环和if-else语句。 But now it uses vectors, read and writes to files, creates a directory etc. 但现在它使用向量,读取和写入文件,创建目录等。

You can see the code here: Project on Bitbucket 你可以在这里看到代码: Bitbucket上的项目

My program now is going to have 2 modes: practise a single multiplication table that the user can choose himself or practise all multiplication tables mixed. 我的程序现在将有两种模式:练习单个乘法表,用户可以选择自己或练习所有乘法表混合。 Now both modes work quite different internally. 现在两种模式在内部完全不同。 And I developed the mixed mode as a separate program, as would ease the development, I could just focus on writing the code itself instead of also bothering how I will integrate it in the existing code. 我开发混合模式作为一个单独的程序,因为可以简化开发,我可以专注于编写代码本身,而不是打扰我将如何将它集成到现有代码中。

Below the code of the currently separate mixed mode program: 在当前单独的混合模式程序的代码下面:

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <time.h> 

using namespace std;
using std::string;

int newquestion(vector<int> remaining_multiplication_tables, vector<int> multiplication_tables, int table_selecter){
  cout << remaining_multiplication_tables[table_selecter] << " * " << multiplication_tables[remaining_multiplication_tables[table_selecter]-1]<< " =" << "\n";
  return remaining_multiplication_tables[table_selecter] * multiplication_tables[remaining_multiplication_tables[table_selecter]-1];
}

int main(){
  int usersanswer_int;
  int cpu_answer;
  int table_selecter;
  string usersanswer;
  vector<int> remaining_multiplication_tables = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  vector<int> multiplication_tables(10, 1);//fill vector with 10 elements that contain the value '1'. This vector will store the "progress" of each multiplication_table.
  srand(time(0));

  table_selecter = rand() % remaining_multiplication_tables.size();
  cpu_answer = newquestion(remaining_multiplication_tables, multiplication_tables, table_selecter);
  while(remaining_multiplication_tables.size() != 0){
    getline(cin, usersanswer);
    stringstream usersanswer_stream(usersanswer);
    usersanswer_stream >> usersanswer_int;
    if(usersanswer_int == cpu_answer){
      cout << "Your answer is correct! :)" << "\n";
      if(multiplication_tables[remaining_multiplication_tables[table_selecter]-1] == 10){
       remaining_multiplication_tables.erase(remaining_multiplication_tables.begin() + table_selecter);
      }
      else{
    multiplication_tables[remaining_multiplication_tables[table_selecter]-1] +=1;
      }
      if (remaining_multiplication_tables.size() != 0){
    table_selecter = rand() % remaining_multiplication_tables.size();
    cpu_answer = newquestion(remaining_multiplication_tables, multiplication_tables, table_selecter);
      }
    }
    else{
      cout << "Unfortunately your answer isn't correct! :(" << "\n";
    } 
  }
  return 0;
}

As you can see the newquestion function for the mixed mode is quite different. 正如您所看到的,混合模式的newquestion函数是完全不同的。 Also the while loop includes other mixed mode specific code. while循环还包括其他混合模式特定代码。

Now if I want to integrate the mixed multiplication tables mode into the existing main program I have 2 choices: -I can clutter up the while loop with if-else statements to check each time the loop runs whether mode == 10 (single multiplication table mode) or mode == 100 (mixed multiplication tables mode). 现在,如果我想将混合乘法表模式集成到现有的主程序中,我有两个选择: - 我可以使用if-else语句来混乱while循环来检查每次循环运行是否模式== 10(单个乘法表模式)或模式== 100(混合乘法表模式)。 And also place a if-else statement in the newquestion() function to check if mode == 10 or mode == 100 -I can let the program check on startup whether the user chose single multiplication table or mixed multiplication tables mode and create 2 while loops and 2 newquestion() functions. 并在newquestion()函数中放置一个if-else语句来检查mode == 10或mode == 100 -I是否可以让程序在启动时检查用户是选择单乘法表还是混合乘法表模式并创建2 while循环和2个newquestion()函数。 That would look like this: 这看起来像这样:

int newquestion_mixed(){
 //newquestion function for mixed mode
}
int newquestion_single(){
 //newquestion function for single mode
}

//initialization
if mode == 10
 //create necessary variables for single mode
 while(){
  //single mode loop
 }
else{
 //create necessary variables for mixed mode
 while(){
  //mixed mode loop
 }
}

Now why would I bother creating 2 separate loops and functions? 现在为什么我要打扰创建2个独立的循环和函数? Well isn't it inefficient if the program checks each time the loop runs (each time the user is asked a new question, for example: '5 * 3 =') which mode the user chose? 如果程序每次循环运行时检查(每次向用户询问一个新问题,例如:'5 * 3 ='),用户选择的模式是不是效率低? I'm worried about the performance with this option. 我担心这个选项的性能。 Now I hear you think: but why would you bother about performance for such a simple, little non-performance critical application with the extremely powerful processors today and the huge amounts of RAM? 现在我听到你的想法:但是为什么你会为这样一个简单的,非常小的非性能关键应用程序以及当今极其强大的处理器和大量的RAM而烦恼? Well, as I said earlier this program is mainly about teaching myself a good coding style and learning how to program etc. So I want to teach myself the good habits from the beginning. 好吧,正如我之前所说,这个程序主要是教自己一个好的编码风格和学习如何编程等。所以我想从一开始就教会自己好习惯。

The 2 while loops and functions option is much more efficient will use less CPU, but more space and includes duplicating code. 2 while循环和函数选项更有效,将使用更少的CPU,但更多的空间,并包括重复的代码。 I don't know if this is a good style either. 我不知道这是不是一个好的风格。

So basically I'm asking the experts what's the best style/way to handle this kind of things. 所以基本上我问专家什么是处理这类事情的最佳风格/方式。 Also if you spot something bad in my code/bad style please tell me, I'm very open to feedback because I'm still a novice. 此外,如果你发现我的代码/坏风格的坏事请告诉我,我很乐意反馈,因为我还是一个新手。 ;) ;)

First, a fundamental rule of programming is that of "don't prematurely optimize the code" - that is, don't fiddle around with little details, before you have the code working correctly, and write code that expresses what you want done as clearly as possible. 首先,编程的基本规则是“不要过早地优化代码” - 也就是说,在代码正常工作之前不要弄乱细节,并编写表达你想要做的事情的代码尽可能清楚。 This is good coding style. 这是很好的编码风格。 To obsess over the details of "which is faster" (in a loop that spends most of it's time waiting for the user to input some number) is not good coding style. 想要了解“哪个更快”(在一个花费大部分时间等待用户输入某个数字的循环中)的细节并不是很好的编码风格。

Once it's working correcetly, analyse (using for example a profiler tool) where the code is spending it's time (assuming performance is a major factor in the first place). 一旦它正确地工作,分析(使用例如分析器工具)代码花费它的时间(假设性能是首要的主要因素)。 Once you have located the major "hotspot", then try to make that better in some way - how you go about that depends very much on what that particular hot-spot code does. 一旦找到主要的“热点”,然后尝试以某种方式改善它 - 你如何去做,这在很大程度上取决于特定热点代码的作用。

As to which performs best will highly depend on details the code and the compiler (and which compiler optimizations are chosen). 哪个表现最佳将高度依赖于代码和编译器的细节(以及选择哪些编译器优化)。 It is quite likely that having an if inside a while-loop will run slower, but modern compilers are quite clever, and I have certainly seen cases where the compiler hoists such a choice out of the loop, in cases where the conditions don't change. 很可能在while循环中使用if会运行得更慢,但是现代编译器非常聪明,而且我确实看到过编译器在循环中提出这样一个选择的情况,如果条件没有更改。 Having two while-loops is harder for the compiler to "make better", because it most likely won't see that you are doing the same thing in both loops [because the compiler works from the bottom of the parse-tree up, and it will optimize the inside of the while-loop first, then go out to the if-else side, and at that point it's "lost track" of what's going on inside each loop]. 有两个while循环对于编译器来说更难“变得更好”,因为它很可能不会看到你在两个循环中都做同样的事情[因为编译器从解析树的底部开始工作,并且它将首先优化while循环的内部,然后转到if-else侧,并且在那时它“丢失了”每个循环内部发生的事情。

Which is clearer, to have one while loop with an if inside, or an if with two while-loops, that's another good question. 哪个更清楚,有一个while循环带有if,或者if有两个while循环,这是另一个好问题。

Of course, the object oriented solution is to have two classes - one for mixed, another for single - and just run one loop, that calls the relevant (virtual) member function of the object created based on an if-else statement before the loop. 当然,面向对象的解决方案是有两个类 - 一个用于混合,另一个用于单个 - 并且只运行一个循环,它调用在循环之前基于if-else语句创建的对象的相关(虚拟)成员函数。

现代CPU分支预测器非常好,如果在循环期间条件永远不会改变,它可能与在每个分支中具有两个while循环一样快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM