【问题标题】:Doesn't cout output from left to right?cout 输出不是从左到右吗?
【发布时间】:2020-05-16 02:20:15
【问题描述】:

所以我的教授给了一个作业,他给了main() 函数来跟进。我们将提出类以产生类似的输出。我尝试了很多代码,但我无法得到答案。当教授给我他的答案时,我似乎无法理解。

这是问题,

创建一个程序,用于显示圆形、三角形和正方形三种形状的参数。
该类应该能够请求用户为每个形状插入相关信息,即长度和直径,这些信息将存储在该类的私有成员中。每个形状的参数将存储在一个名为 SParameter 的变量中,该变量被分配为一个私有成员。 main() 将被修复。

这是我教授的,

#include <iostream>

using namespace std;

class shape {
    private:
    string name;
    double length;
    double Tperimeter;

    public:
    void perimeter()
    {
    if (name == "circle")
    {
        cout<<"enter  the diameter:";
        cin>>length;
       Tperimeter = 3.142* length;
    }
    if (name == "triangle")
    {
       cout<<"enter side length:";
        cin>>length;
       Tperimeter = 3*length;
    }
    if (name == "square")
    {
       cout<<"enter side length:";
        cin>>length;
       Tperimeter = 4*length;
    }
    }

    double display(string shapename)
    {
    name=shapename;
    if (name == "circle")
    {
    perimeter();
    return Tperimeter;
    }
    if (name == "triangle")
    {
    perimeter();
    return Tperimeter;
    }
    if (name == "square")
    {
    perimeter();
    return Tperimeter;
    }
    } };

int main() {
    shape S;
    char c;
    string name;
    do
    {
    cout<<"Enter name of shape:";
    cin>>name;
    cout<<"the perimeter of "<<name<<"is:"<< S.display(name)<<endl;
    cout<<"do you wish to continue?";
    cin>    c;
    }while(c!='n');

    return 0; }

这是我的代码,

#include <iostream>

using namespace std;

class shape{ private:
    int Sparameter;
    int perimeter;
    string name; public:
    shape(){

        }
    int display(string name){
          if(name=="circle"){
            cout<<"Enter the diameter of the circle";
            cin>>Sparameter;
            perimeter=3.14*Sparameter/2;
        }
        else if(name=="square"){
            cout<<"Enter the length of the square";
            cin>>Sparameter;
            perimeter=4*Sparameter;
        }
        else if(name=="triangle"){
            cout<<"Enter the length of the triangle";
            cin>>Sparameter;
            perimeter=3*Sparameter;
       return perimeter;
        }

        } };

int main() {
    shape S;
    char c;
    string name;
    do
    {
    cout<<"Enter name of shape:";
    cin>>name;
    cout<<"the perimeter of "<<name<<"is:"<< S.display(name)<<endl;
    cout<<"do you wish to continue?";
    cin>>    c;
    }while(c!='n');

    return 0; }

所以我的问题是关于输出,如果使用 Codeblocks,这是我和我教授的代码的输出。

输入形状名称:圆形
圆的周长:输入直径:10
31.42
你想继续吗?

“圆周长”的计数将出现在“输入直径”之前。但是,如果我使用在线编译器,例如在线 gdb。它的输出与我教授的代码不同。

输入形状名称:圆形
输入直径:30
圆的周长是:94.26
你想继续吗?

“输入直径”部分将出现在“圆的周长”之前,即使在 cout 部分中,“圆的周长”出现在调用 S.display() 函数之前。

cout

那么输入的直径是怎么出现的呢?我问过我的教授,他说关键是在函数中调用函数。但这对我来说并不能解释太多,我错过了什么吗?程序的流程不是从左到右吗?

谢谢。

【问题讨论】:

  • 删除除您需要帮助的代码之外的所有内容。你的教授提供了一些东西来指导你。我们(我)不在乎。问一个具体的问题。你在使用调试器吗?你能走多远?你期望什么输出?你会得到什么?
  • 如果这是你教授的示例代码,那么他们就没有教授 C++ 课程的业务。
  • 我的意思是,我们可以分析这一点,但真正的问题是,在打印操作中将读取操作作为副作用首先不应该成为问题。方法display 应该完全做到这一点,打印信息。您应该将 IO 操作和内部逻辑分开。它应该如下所示: 1. 请求输入并将其存储在变量中的例程。 2.你的类的构造函数接受这些。 3. 访问被调用值的类的方法。 4. 正在打印的检索值。

标签: c++ function codeblocks cout


【解决方案1】:
#include <iostream>

using namespace std;

class shape{ private:
    double Sparameter;
    double perimeter;
    string name; public:
    shape(){

        }
    double display(string name){
          if(name=="circle"){
            cout<<"Enter the diameter of the circle: ";
            cin>>Sparameter;
            perimeter=3.14*Sparameter/2;
        }
        else if(name=="square"){
            cout<<"Enter the length of the square: ";
            cin>>Sparameter;
            perimeter=4*Sparameter;
        }
        else if(name=="triangle"){
            cout<<"Enter the length of the triangle: ";
            cin>>Sparameter;
            perimeter=3*Sparameter;
       return perimeter;
        }

        } };

int main() {
    shape S;
    char c;
    string name;
    do
    {
    cout<<"Enter name of shape:";
    cin>>name;
    cout<<"the perimeter of "<<name<<"is:"<< S.display(name)<<endl;
    cout<<"do you wish to continue?";
    cin>>    c;
    }while(c!='n');

    return 0; }

我想试试这段代码,我在我的编译器/文本编辑器 (Atom) 和在线编译器上试过。我只是将类型更改为 double,因为您将处理浮点数

【讨论】:

    【解决方案2】:

    在 C++17 语言修订版之前,这两个结果实际上都是合法的。在 C++17 之前没有指定运算符操作数的求值顺序。

    让我们分解一下这个表达式:

    cout<<"the perimeter of "<<name<<"is:"<< S.display(name)<<endl;
    //                                     ^
    //                                     |
    //                                     I'm going to focus on this << operator
    

    由于未指定计算操作数的顺序,编译器可以选择先计算标记运算符的左侧或右侧。两个操作数的求值都有副作用(即打印输出),因此这些副作用可以按任意顺序出现。

    • 如果编译器选择先计算左侧 (cout&lt;&lt;"the perimeter of "&lt;&lt;name&lt;&lt;"is:"),则其输出将首先出现,您会看到类似的输出
    Enter name of shape:circle
    the perimeter of circleis:enter the diameter:10
    31.42
    do you wish to continue?
    
    • 如果编译器选择先计算右侧 (S.display(name)),则其输出将首先出现,您会看到类似的输出
    Enter name of shape:circle
    enter the diameter:30
    the perimeter of circleis:94.26
    do you wish to continue?
    

    C++17 纠正了这一切。现在需要从左到右计算操作数,因此如果您使用符合 C++17 的编译器进行编译,您将始终看到类似

    的输出
    Enter name of shape:circle
    the perimeter of circleis:enter the diameter:10
    31.42
    do you wish to continue?
    

    编译器不能选择在cout&lt;&lt;"the perimeter of "&lt;&lt;name&lt;&lt;"is:"之前评估S.display(name)


    这解释了您看到的不同输出。您的本地编译器选择首先评估 &lt;&lt; 运算符的左侧,而在线编译器选择首先评估右侧。

    【讨论】:

    • 谢谢,所以更多的是与编译器有关,与函数中的函数无关吧?
    • 不确定“函数中的函数”是什么意思。由于未指定 &lt;&lt; 运算符的操作数的评估顺序,因此它可能会根据您的编译器、编译器版本、编译器选项、月相等而改变。
    • 我的意思是,就像在我的教授代码中一样,在 S.display() 内部,他有另一个 perimeter(),但是经过您的解释,现在对我来说很有意义,谢谢!
    猜你喜欢
    • 2016-05-02
    • 1970-01-01
    • 2018-04-03
    • 1970-01-01
    • 2022-01-05
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多