代码之家  ›  专栏  ›  技术社区  ›  ybakos

解释C++中声明性谬误的最好方法?

  •  6
  • ybakos  · 技术社区  · 15 年前

    一个人如何解释为什么下面的代码是不正确的,因为作者试图声明性地写C++代码而不是程序性的?

    const double NEWTONS_PER_POUND = 4.448;
    
    int main()
    {
       double pounds, newtons;
       pounds = newtons/NEWTONS_PER_POUND; /* pounds equals 'unassigned variable'/4.448 */
       newtons = 10.0;
       cout << pounds << endl;             /* a big number, not 10.0/4.448 */
       return 0;
    }
    

    作者期望 cout 显示一个正确的计算,但得到一个“疯狂的数字”。

    我将解释为“C++是过程性的,因此在声明时”。

    pounds = newtons/NEWTONS_PER_POUND;
    

    newtons 尚未分配值。

    有更好的建议吗?或者解释为什么C++不“聪明”足以执行用户错误预期的行为?

    9 回复  |  直到 12 年前
        1
  •  21
  •   Richard Corden    15 年前

    告诉作者

    pounds = newtons/NEWTONS_PER_POUND;
    

    命令CPU

    • 取地址处的值称为“牛顿”。
    • 在地址处取“牛顿每磅”
    • 把它们分开
    • 将结果存储在称为“磅”的地址。

    他正在寻找的很可能是一个命令式的功能:

    double newtons_to_pounds(double newtons) {
      return newtons/NEWTONS_PER_POUND;
    }
    
    ...
    
    newtons = 10.0;
    cout << newtons_to_pounds(newtons) << endl;    /* a big number, not 10.0/4.448 */
    return 0;
    
        2
  •  18
  •   Stephen C    15 年前

    C++是一种命令式编程语言,而不是方程求解器。

    C++按照编写的顺序执行语句。除非被告知,否则C++不初始化变量。C++允许使用未初始化值的变量,但当这样做时,结果是 未指定的 . 未指明意味着比任何事情都可能发生,包括坏的事情,如产生“疯狂的数字”。

    详细解释如下:

    double pounds, newtons;
    pounds = newtons/NEWTONS_PER_POUND;
    newtons = 10.0;
    

    第一条语句声明了两个变量,但没有初始化它们。此时,它们的值未指定。

    第二个语句读取 newtons (可以是任何东西)然后除以 NEWTONS_PER_POUND . 结果(可以是任何东西)分配给 pounds .

    第三条语句初始化 牛顿 ,但现在影响我们刚刚执行的计算为时已晚。

        3
  •  8
  •   Konrad Rudolph    15 年前

    好吧,不管学生的背景如何,都不难解释:只需告诉他们C++一次一步地评估程序,后一句话就声明(尽管像重新排序这样的编译器伪像)。

    C++的处理方式并没有什么特别的,它甚至不局限于计算机编程,而是一种处理指令的有序列表的日常方式。

        4
  •  4
  •   Spence    15 年前

    评估牛顿不是懒惰的。

    因此,计算是在申报时进行的,而不是在请求时进行的。他追求的是功能性的代码,而不是C++所能做到的。

        5
  •  4
  •   Ash    15 年前

    如果此人不是技术过硬,您可以尝试:

    “这个C++程序中的语句就像制作蛋糕所需的步骤。您必须一个一个地执行这些步骤,并且必须按照一定的顺序执行这些步骤,才能使其成功。”

        6
  •  1
  •   Mike Hall    15 年前

    解释磅是通过赋值运算符在行上赋值的:

    pounds = newtons/NEWTONS_PER_POUND;
    

    如果情况并非如此,但磅是在使用时进行评估的(就像cout语句),那么如果牛顿的值改变了,那么磅的值也会改变。因为磅不是任何类型的指针,而是一个简单的整数,所以这是不可能的。

        7
  •  1
  •   sbi    15 年前

    在调试器中单步执行代码怎么样?

    IME没有什么能像这样理解用过程语言编写的程序的执行(即,根据CPU实际执行代码的方式建模)。

        8
  •  0
  •   Andrew Shepherd    15 年前

    您试图让监听者经历一个范式转换——改变他/她理解这段代码的整个方法。

    “磅”只是一个数字。它没有 如何创造的概念。你告诉 “磅”怎么创造的,它不会 记得。它只会记住什么 它是,而不是它是如何被创造出来的。

    把记忆块拟人化似乎有点奇怪。-)

        9
  •  0
  •   TheUndeadFish    15 年前

    举一个稍微复杂一点的例子,其中一个变量 newtons 多次重复使用和分配值。例如:

    double pounds, newtons;
    
    newtons = 10.0;
    pounds = newtons/NEWTONS_PER_POUND;
    cout << pounds << endl;
    
    newtons = 15.0;
    pounds = newtons/NEWTONS_PER_POUND;
    cout << pounds << endl;
    
    return 0;
    

    向他显示代码和输出。然后让他解释程序如何为每一行生成不同的数字,以及为什么会生成不同的数字。我认为这将有助于推动他将程序视为一个自上而下的过程。

    推荐文章