2 while循环vs if else语句在1 while循环中 [英] 2 while loops vs if else statement in 1 while loop

查看:118
本文介绍了2 while循环vs if else语句在1 while循环中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

先简单介绍一下:



我是一个新手C ++程序员(我刚刚编程)编写一个小乘法表练习程序。该项目开始作为一个小程序,教自己的编程的基础,我不断添加新的功能,因为我越来越多地了解编程。起初,它只是有基本的要求输入,循环和if-else语句。但现在它使用向量,读取和写入文件,创建一个目录等。



您可以在这里看到代码: Bitbucket上的项目



我的程序现在是有两种模式:练习一个乘法表,用户可以自己选择或练习所有乘法表混合。现在这两种模式在内部工作相当不同。我开发了混合模式作为一个单独的程序,这将缓解开发,我可以只关注编写代码本身,而不是也打扰我将其集成到现有的代码。



在当前独立的混合模式程序的代码下面:

  #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]< *<< multiplier_tables [remaining_multiplication_tables [table_selecter] -1]< =<< \\\
;
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); //填充包含值为'1'的10个元素的向量。该向量将存储每个乘法表的进度。
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<< 你的回答是正确的!)<< \\\
;
if(multiplication_tables [remaining_multiplication_tables [table_selecter] -1] == 10){
remaining_multiplication_tables.erase(remaining_multiplication_tables.begin()+ table_selecter);
}
else {
multiplier_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<< 不幸的是你的回答是不正确的:(<\\\
;
}
}
return 0;
}

正如你可以看到,混合模式的newquestion函数是完全不同的,while循环包括其他混合模式特定的代码。 / p>

现在,如果我想将混合乘法表模式集成到现有的主程序中,我有两个选择:
- 我可以混乱while循环if- else语句检查每次循环运行是否mode == 10(单乘法表模式)或mode == 100(混合乘法表模式)并且还在newquestion()函数中放置一个if-else语句以检查模式== 10或mode == 100
- 我可以让程序在启动时检查用户是选择单乘法表还是混合乘法表模式,并创建2个while循环和2个newquestion()函数,看起来像这样:

  int newquestion_mixed(){
//混合模式的newquestion函数
}
int newquestion_single(){
//单模式的newquestion函数
}

//初始化
如果mode == 10
//创建必要的变量对于单模式
while(){
//单模循环
}
else {
//为混合模式创建必要的变量
while {
//混合模式循环
}
}



为什么我会打扰创建2个独立的循环和函数?如果程序在每次循环运行时检查(每次向用户询问一个新问题,例如:'5 * 3 =')用户​​选择哪个模式,那么效率不高。我担心使用此选项的性能。现在我听到你的想法:但为什么你会打扰这样一个简单,小非性能关键应用程序的性能与当今非常强大的处理器和大量的RAM?好吧,正如我前面所说的,这个程序主要是教自己一个好的编码风格和学习如何编程等。所以我想教自己从一开始的好习惯。



2 while循环和函数选项更高效将使用更少的CPU,但更多的空间和包括复制代码。我不知道这是一个好的风格。



所以基本上我问专家什么是最好的风格/方式来处理这种事情。另外,如果你发现我的代码/坏样式的坏东西告诉我,我非常开放反馈,因为我还是一个新手。 ;)

解决方案

首先,编程的一个基本规则是不要过早优化代码在代码工作正常之前,不要搞错细节,写代码尽可能清楚地表达你想要做的。这是好的编码风格。要痴迷更快的细节(在一个循环,花费大部分时间等待用户输入一些数字)是不好的编码风格。



一旦工作正常,分析(使用例如分析器工具)代码花费时间(假设性能是首要因素)。一旦你找到了主要的热点,然后尝试做一些更好的方式 - 你怎么去取决于那个特定的热点代码做什么。



至于哪个执行最好将高度依赖于细节代码和编译器(以及选择哪个编译器优化)。很有可能的是,如果一个while循环中运行得更慢,但现代编译器是相当聪明的,我肯定已经看到编译器提出这样一个选择循环,在情况下,条件不更改。有两个while循环对于编译器更好是更难的,因为它很可能不会看到你在两个循环中做同样的事情[因为编译器从分析树的底部向上工作,它将首先优化while循环的内部,然后出去if-else一侧,并且在这一点上它是每个循环内部发生的丢失的轨道]。



这更清楚,有一个while循环有一个if里面,或if有两个while循环,这是另一个好问题。



当然,面向对象的解决方案是有两个类 - 一个用于混合,另一个用于单个且只运行一个循环,调用相关在循环之前基于if-else语句创建的对象的函数。


First a little introduction:

I'm a novice C++ programmer (I'm new to programming) writing a little multiplication tables practising program. 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. But now it uses vectors, read and writes to files, creates a directory etc.

You can see the code here: Project on 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. Also the while loop includes other mixed mode specific code.

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). 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. 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? 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? 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? 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. 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. 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].

Which is clearer, to have one while loop with an if inside, or an if with two while-loops, that's another good question.

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.

这篇关于2 while循环vs if else语句在1 while循环中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆