2013-04-27 232 views
3

首先做一简单介绍:2 while循环VS如果else语句在1 while循环

我是一个新手C++程序员(我是新来的节目)写了一点乘法表练习计划。这个项目起初是一个小程序,教给自己编程的基础知识,随着我越来越多地学习编程,我不断添加新的功能。起初它只是基本的要求输入,循环和if-else语句。但现在它使用的载体,读取和写入文件,创建一个目录等

你可以看到这里的代码:Project on 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] << " * " << 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; 
} 

正如你可以看到newquestion功能的混合模式是完全不同的。 while循环还包括其他混合模式特定的代码。

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

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 
} 
} 

现在为什么我会打扰创建2个独立的循环和函数?如果程序检查每次循环运行时(每次向用户提出新问题,例如:'5 * 3 ='),用户选择了哪种模式,那么效率不是很低?我很担心这个选项的表现。现在我听到了你的想法:但是为什么你会因为今天功能非常强大的处理器和大量的RAM而对这样一个简单的,非性能不重要的应用程序的性能感到困扰?那么,正如我早些时候说的那样,这个程序主要是教我自己一个很好的编码风格和学习如何编程等。所以我想从一开始就教好自己的好习惯。

2 while while循环和函数选项更有效率将使用更少的CPU,但更多的空间并包括重复的代码。我不知道这是否是一种很好的风格。

所以基本上我问专家最好的风格/方式来处理这种事情。另外,如果你发现我的代码/不好的风格有问题,请告诉我,我非常乐于反馈,因为我仍然是一名新手。 ;)

回答

5

首先,编程的一个基本规则是“不要过早地优化代码” - 也就是说,在代码正常工作之前,不要少摆弄一些细节,并编写代码尽可能清楚地表达你想做的事情。这是很好的编码风格。为了了解“哪个更快”的细节(在花费大部分时间等待用户输入一些数字的循环中)并不是很好的编码风格。

正确运行后,分析代码花费时间(假设性能是首要考虑的主要因素)(例如使用Profiler工具)。一旦你找到了主要的“热点”,然后尝试在某种程度上做得更好 - 你如何去做,这很大程度上取决于特定的热点代码的功能。

至于哪一个执行得最好将高度依赖于代码和编译器的细节(以及哪个编译器优化被选择)。很有可能在while循环中运行if会运行得更慢,但现代编译器相当聪明,而且我确实看到了编译器将这样的选择提升出循环的情况,在条件不成立的情况下更改。有两个while循环对于编译器来说“变得更好”更困难,因为它很可能不会看到你在两个循环中都做了同样的事情[因为编译器从分析树的底部开始工作,它会首先优化while循环的内部,然后出去if-else,然后在每个循环内部发生什么事情的时候,它会“失去踪迹”。

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

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

+0

我再次阅读了我的代码,但如果我不想创建2个循环,那么我将不得不创建比我想象的更多的if-else。我认为我的代码会变得更不可读。所以我想我会把更多的代码放入函数中,并创建2个循环。这将大大简化事情。 – Superpelican 2013-04-27 13:43:35

+0

我最终创建了2个循环和2个独立的函数。结果是比用if-else语句混淆了代码更可读。结果可以在这里看到:https://bitbucket.org/Superpelican/clamshell_cli/src/c4dc989c1500f6a29981a966404c8cd92d4bc648/clamshell.cpp?at=default – Superpelican 2013-04-28 10:43:40

1

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