C ++ |为了提高循环效率?

时间:2018-08-18 17:13:58

标签: c++ visual-c++

我一直在学习C ++,显然在进入循环之前,我正在阅读的教学手册为我提供了这种情况:

  

扩展本章前面的密码检查程序,并使其采用多个用户名,每个用户名都有自己的密码,并确保将正确的用户名用于正确的密码。如果首次登录尝试失败,则提供再次提示用户的功能。考虑一下对许多用户名和密码执行此操作有多容易(或很难)。

在没有循环知识的前提下,它将重复任何不正确的值,提示用户输入正确的信息,直到他们输入正确的信息为止,我试图完成任务,并在此处获得以下代码:

#include < iostream >

using namespace std;

int main()
{

    int inputCodeOne, inputCodeTwo = 0;

    bool correctPassOne=false,correctPassTwo;

    cout << "Please enter your first Code: ";
    cin >> inputCodeOne;

    if(inputCodeOne==1111||inputCodeOne==2222||inputCodeOne==3333)
    {
        correctPassOne = true;
    }
    if (correctPassOne)
    {
        cout << "Please enter your second Code: ";
        cin >> inputCodeTwo;

        if (inputCodeOne == 1111 && inputCodeTwo == 100)
        {
            cout << "Password Correct! Welcome back David";
            return 0;
        }
        else if (inputCodeOne == 2222 && inputCodeTwo == 200)
        {
            cout << "Password Correct! Welcome back Darren";
            return 0;
        }
        else if (inputCodeOne == 3333 && inputCodeTwo == 300)
        {
            cout << "Password Correct! Welcome back Jake";
            return 0;
        }
        correctPassTwo = false;
        if(!correctPassTwo)
        {
            cout << "Please re-enter your second Code: ";
            cin >> inputCodeTwo;
            if (inputCodeOne == 1111 && inputCodeTwo == 100)
            {
                cout << "Password Correct! Welcome back David";
                return 0;
            }
            else if (inputCodeOne == 2222 && inputCodeTwo == 200)
            {
                cout << "Password Correct! Welcome back Darren";
                return 0;
            }
            else if (inputCodeOne == 3333 && inputCodeTwo == 300)
            {
                cout << "Password Correct! Welcome back Jake";
                return 0;
            }
            cout << "ACCESS DENIED";
            return 0;
        }
    }
    else
    {
        cout << "Please re-enter your first Code: ";
        cin >> inputCodeOne;

        if (inputCodeOne == 1111 && inputCodeTwo == 100)
        {
            cout << "Password Correct! Welcome back David";
            return 0;
        }
        else if (inputCodeOne == 2222 && inputCodeTwo == 200)
        {
            cout << "Password Correct! Welcome back Darren";
            return 0;
        }
        else if (inputCodeOne == 3333 && inputCodeTwo == 300)
        {
            cout << "Password Correct! Welcome back Jake";
            return 0;
        }
        else
        {
            cout << "Please enter your second Code: ";
            cin >> inputCodeTwo;

            if (inputCodeOne == 1111 && inputCodeTwo == 100)
            {
                cout << "Password Correct! Welcome back David";
                return 0;
            }
            else if (inputCodeOne == 2222 && inputCodeTwo == 200)
            {
                cout << "Password Correct! Welcome back Darren";
                return 0;
            }
            else if (inputCodeOne == 3333 && inputCodeTwo == 300)
            {
                cout << "Password Correct! Welcome back Jake";
                return 0;
            }
            correctPassTwo = false;
            if (!correctPassTwo)
            {
                cout << "Please re-enter your second Code: ";
                cin >> inputCodeTwo;
                if (inputCodeOne == 1111 && inputCodeTwo == 100)
                {
                    cout << "Password Correct! Welcome back David";
                    return 0;
                }
                else if (inputCodeOne == 2222 && inputCodeTwo == 200)
                {
                    cout << "Password Correct! Welcome back Darren";
                    return 0;
                }
                else if (inputCodeOne == 3333 && inputCodeTwo == 300)
                {
                    cout << "Password Correct! Welcome back Jake";
                    return 0;
                }
                else
                {
                    cout << "ACCESS DENIED";
                    return 0;
                }
            }
        }
    }   
}

很抱歉代码可能有多混乱,但我想知道是否有任何方法可以在提供相同结果的同时提高空间效率。

2 个答案:

答案 0 :(得分:1)

优化-首次通过

创建标识符或命名常量

这可以避免重复和输入错误。还允许编译器进行更多优化。

const int PASSWORD1a = 1111;
const int PASSWORD2a = 2222;
const int PASSWORD3a = 3333;
const int PASSWORD1b = 100;
const int PASSWORD2b = 200;
const int PASSWORD3b = 300;

将密码分组在一起。

将密码配对保持在一起将使该过程更加通用。
您可以使用现有的std::pair或创建自己的:

struct Password_Entry
{
    int first;
    int second;
};

接下来,创建一个有效密码对表:

const Password_Entry  valid_passwords[] =
{
    {PASSWORD1a, PASSWORD1b},
    {PASSWORD2a, PASSWORD2b},
    {PASSWORD3a, PASSWORD3b},
};
const size_t quantity_valid_passwords =
    sizeof(valid_passwords) / sizeof(valid_passwords[0]);

在表格中搜索有效密码

int inputCode1;
int inputCode2;
bool passwords_are_valid = false;
std::cout << "Enter first password: ";
std::cin >> inputCode1;
for (unsigned int index = 0; index < quantity_valid_passwords; ++index)
{
    if (inputCode1 == valid_passwords[i].first)
    {
        std::cout << "Enter second password: ";
        std::cin >> inputCode2;
        if (inputCode2 == valid_passwords[i].second)
        {
            passwords_are_valid = true;
        }
    }
}

摘要

上面的代码是表驱动的。搜索表的代码是通用的,并且取决于表中的数据。条目数量可以更改,而无需修改其余代码。

在结构上将第一个密码与第二个密码配对,可以提供更好的数据存储和代码空间。

使用命名常量只能将值指定一次。如果您需要更改值,则只需进行一次更改。进行更改时,您不会冒跳过一个或多个以上的风险。

优化-第二次通过

人名

可以通过在结构中添加另一个字段或成员来优化人名的打印:

struct Password_Entry
{
    int first;
    int second;
    char * name;
};

该表现在变为:

const Password_Entry  valid_passwords[] =
{
    {PASSWORD1a, PASSWORD1b, "David"},
    {PASSWORD2a, PASSWORD2b, "Darren"},
    {PASSWORD3a, PASSWORD3b, "Jake"},
};
const size_t quantity_valid_passwords =
    sizeof(valid_passwords) / sizeof(valid_passwords[0]);

搜索/验证代码更改为:

    std::cout << "Enter second password: ";
    std::cin >> inputCode2;
    if (inputCode2 == valid_passwords[i].second)
    {
        passwords_are_valid = true;
        std::cout << "Password Correct! Welcome Back "
                  << valid_passwords[i].name
                  << "!\n";
    }

优化-第三遍

合并重复文本

有重复的文本,这意味着可以挤出更多空间:

char const * const text_enter[] = "Enter ";
char const * const text_password[] = "password";

代码可以更改为:

std::cout << text_enter << "first " << text_password << ": ";
//...
std::cout << text_enter << "second " << text_password << ": ";
//...
std::cout << "Correct " << text_password << "! Welcome Back "
          << valid_passwords[index].name << "\n";

块编写

也许可以通过块写入而不是使用格式化写入来压缩一些代码空间。所有输出均为文本,因此无需格式化;文本可以直接输出。在优化之前和之后,您必须比较的汇编语言列表,以测量空间差异。

此技术可能还会显示出一些速度上的改进。

使用以下内容:

std::cout.write(text_enter, sizeof(text_enter) - 1U); // -1 so the terminating nul is not output.
std::cout.write(text_password, sizeof(text_password) - 1U);
std::cout.write(": ", 2);

同样,将其他std::cout <<替换为std::cout.write,就像上面的代码一样。

优化-第四遍

请勿使用std::cout

std::cout可能会带来额外的负担。您可以使用替代方法来节省一些代码空间。

std::cout替换为fwrite(stdout, /*...*/)fwrite函数包含用于写入给定流的最少代码。无需格式化或转换额外的代码。简单明了,将数据写入流。
一些编译器可能比较懒惰,并且会插入“ one-size-fits-all”库,而不是仅插入fwrite的代码。

通过直接访问操作系统的低级驱动程序,您可以挤出更多的代码空间。您的程序足够小,不需要缓冲,也不需要C ++和OS流中的其他开销。在这一点上,节省的空间对于实现此目标所花费的开发时间可以忽略不计。取决于您的平台。在内存受限的系统上,这可能是值得的。在大多数桌面系统上,这不值得您花时间开发,因为它们比受约束的系统拥有更多的内存。

答案 1 :(得分:0)

正如Jesper所说,是的,有很多方法。我鼓励您先了解循环,然后再进行研究。

循环只允许您再次执行相同的操作,从根本没有时间(循环不运行)到永远(无限循环)。

每当您发现自己再次键入相同的内容或粘贴粘贴时,使用循环(或将代码移入函数,类等)的可能性就会非常大一个更好的选择。

此外,您的代码似乎没有达到预期的性能。如果最初输入的输入不正确,则correctPassOne为false,然后进入第一个,并提示“重新输入您的第一个代码:”。

  1. 第一组if else语句将永远不会通过。它正在检查inputCodeTwo是否正确,但此时用户尚未提供它。

您似乎已经意识到这一点,并将else语句放在该语句之后,然后提示输入inputTwo。

  1. 现在的问题是,如果第二次inputCodeOne不正确,则inputCodeTwo无关紧要。因此,您将提示输入inputCodeTwo而没有成功的机会。

  2. 在第103、104行中键入

correctPassTwo = false; if(!correctPassTwo) { } 如果达到104,则也将达到103,因此不需要分配false和条件。

  1. 再次,如果inputCodeOne错误两次,则此代码块是不必要的。您现在正在提示用户两次输入第二个代码,而不会成功。因为inputCodeOne还是错误的。

使用循环,您可以执行以下操作:

根据需要多次询问inputCodeOne,直到它正确或达到限制为止。

如果达到限制,则打印“ ACCESS DENIED”并结束程序。 如果密码正确,则可以进入inputCodeTwo。

同样,请输入inputCode两次。 如果两个代码匹配,请打印您的密码正确消息。 否则,经过一定次数的尝试后,您可以终止程序。

您可以使用25%的初始代码来做到这一点。