【问题标题】:Elegant C++ Code: How to write more efficient code using while loops and conditional statements优雅的 C++ 代码:如何使用 while 循环和条件语句编写更高效的代码
【发布时间】:2019-06-14 21:53:28
【问题描述】:

您能否就如何简化代码给我一些建议?

#include <iostream> 
#include<fstream>
#include<string>

using namespace std; 



int main() {

    string current_users[5];
    string new_users[5], new_user;
    ifstream read;


    read.open("current.txt");

    for (int index = 0; index < 5; index++) {
        read >> current_users[index];

    }

    read.close();


    cout << "Enter a username: ";
    cin >> new_user;


    char user_choice;
    int index = 0, new_index = 0;
    while (index <= 5) {


        if (new_user == current_users[index]) {
            cout << "That username already exists."
                << " Enter a different username: ";

            cin >> new_user;
            index = 0;
            continue;
        }


        if (index < 5)
            index++;


        else {
            new_users[new_index] = new_user;
            cout << "\nWelcome " << new_user << endl;
            new_index++;


             if (new_index < 5) {
               cout << "Would you like to register another user?:" 
                            <<"'Y' for yes or 'N' for no";
                cin >> user_choice;
            }


            if (user_choice == 'Y' || user_choice == 'y') {
                cout << "\nEnter a new username: ";
                cin >> new_user;
                index = 0;
            }

            else
              break;

        }

    }//end of while 

    system("pause");
    return 0;

}

此程序要求用户输入用户名并检查该用户名是否已存在。如果存在,它会提示用户使用不同的用户名,同时检查该用户名是否已经存在。如果用户名是唯一的,程序会欢迎新用户并询问用户是否想注册另一个新用户(很奇怪,但我想尝试一下)。如果用户想将另一个用户添加到“网站”,那么程序会再次运行,检查冗余。我将此程序限制为 5 个可能的用户名,以便检查和添加以方便测试。没有错误。

代码很粗。我想出了这个问题。我不在学校。负担不起,也没有被我申请的任何学校录取。对提供计算机科学学位的在线学校有何建议?

【问题讨论】:

  • std::vector 可以提供帮助。
  • 这个问题可能更适合codereview.stackexchange.com StackOverflow 更多的是关于您想要修复的损坏代码。 CodeReview 是关于你想要改进的工作代码。
  • 半相关:不要将短而复杂的代码与好的代码混为一谈。很多时候,短而愚蠢是正确的方法。简短是因为不存在的代码没有错误,而愚蠢是因为它易于阅读、调试和维护。缩短的关键之一是利用其他人的代码,尤其是标准库。只有在愚蠢不符合要求时才使事情复杂化。

标签: c++ visual-c++ c++14


【解决方案1】:

以下是一些建议:

结构数组不是并行数组

使用std::vector 结构而不是并行数组:

struct Record
{
    std::string  new_user;
    std::string  current_user;
};
std::vector<Record> database;

使用数据缓存的处理器喜欢将它们的元素放在一起。在这里,new_user[0] 将在缓存中的 current_user[0] 旁边。

对于您的并行数组,new_users[0] 位于 current_user[4] 旁边;所以处理器必须经过 4 个元素才能到达第一个 new_users 元素。

循环展开

您可以消除for 循环以读取您的值:

read >> current_users[0];
read >> current_users[1];
read >> current_users[2];
read >> current_users[3];
read >> current_users[4];

这消除了与for 循环相关的开销。

在比较之前转换为全部小写或全部大写

在比较之前可以通过转换成大写或小写来减少比较次数:

if (std::toupper(user_choice) == 'Y')

【讨论】:

  • 避免手动循环展开。循环更具可读性,避免复制/粘贴代码。无论如何,编译器可能会展开循环(如果更好的话)。
  • 循环可能更具可读性,但 OP 要求效率。手动展开循环不依赖于编译器设置。
  • 编译器也可以做相反的事情(创建一个循环)。所以你总是依赖于编译器(设置)。
【解决方案2】:

你所拥有的大部分都是好的。我会将所有内容包装到一个函数中,并使用标准库中的std::find 来查找重复项。

template<std::size_t N, std::size_t M>
void GetUsers( std::string (&new_users)[N], std::string const (&current_users)[M] ) {
  int idx = 0;
  while (idx < 5) {
    std::cout << "Enter a username: ";
    std::string user; std::cin >> user;
    if (std::find(current_users.begin(), current_users.end(), user) != current_users.end()) {
      std::cout << "That username already exists.\n";
      continue;
    } else {
      new_users[idx++] = user;
      if (idx < 5) {
        std::cout << "Would you like to register another user? [Y/n]: ";
        if (std::tolower(std::cin.get()) == 'y') {
          continue;
        }
      }
      break;
    }
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-13
    • 1970-01-01
    • 2014-01-16
    • 2011-04-04
    • 1970-01-01
    相关资源
    最近更新 更多