6

如何很好地解释为什么以下代码不正确,因为作者试图以声明方式而不是程序方式编写 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++ 不够“聪明”来执行用户错误预期的行为?

4

9 回答 9

21

告诉作者

pounds = newtons/NEWTONS_PER_POUND;

命令 CPU

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

他正在寻找的很可能是命令式的函数:

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;
于 2009-09-01T06:53:42.500 回答
18

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

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

以下是详细解释:

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

第一条语句声明了两个变量而不初始化它们。在这一点上,它们的值是未指定的。

第二条语句读取newtons(可以是任何值)的值并将其除以NEWTONS_PER_POUND. 结果(可以是任何东西)分配给pounds.

第三条语句初始化newtons,但是来不及影响我们刚刚执行的计算。

于 2009-09-01T06:56:03.057 回答
8

嗯,这不应该太难解释,不管学生的背景如何:只是告诉他们 C++ 一次一步地评估程序,一个语句一个语句(尽管编译器工件,如重新排序......)。

C++ 的处理方式绝对没有什么特别之处,它甚至不限于计算机编程——相反,它是处理有序指令列表的日常方式。

于 2009-09-01T06:55:53.230 回答
4

评估牛顿并不懒惰

因此,计算是在声明时执行的,而不是在请求时执行的。他追求的是功能代码,而不是 C++ 会做什么。

于 2009-09-01T06:45:04.530 回答
4

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

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

于 2009-09-01T06:58:40.353 回答
1

解释磅在赋值运算符的行上被赋值:

pounds = newtons/NEWTONS_PER_POUND;

如果不是这种情况,但磅在使用时被评估(与 cout 语句一样),那么如果牛顿的值发生变化,那么磅的值也会发生变化。由于磅不是任何类型的指针,而是一个简单的整数,因此这是不可能的。

于 2009-09-01T06:57:09.513 回答
1

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

IME 没有这样的方式来理解用过程语言编写的程序的执行(即,以 CPU 实际执行代码的方式为模型)。

于 2009-09-01T08:46:41.993 回答
0

你正试图让听众经历范式转变——改变他/她理解这段代码的整个方法。

“磅”只是一个数字。它不知道它是如何创建的。你告诉“磅”它是如何创建的,它不会记得。它只会记住它是什么,而不是它是如何创建的。

将一块记忆拟人化似乎有点奇怪。:-)

于 2009-09-01T06:56:29.187 回答
0

举一个稍微复杂一点的例子,其中一个变量 likenewtons被多次重用和赋值。例如:

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;

向他展示代码和输出。然后请他解释程序如何以及为什么为每一行生成不同的数字。我认为这应该有助于推动他将程序视为从上到下运行的程序。

于 2009-09-02T00:37:35.167 回答