在函数后期初始化变量的好处是什么?而不是在函数体的开头?

时间:2016-09-18 15:44:35

标签: c++ variables

我一直在阅读Bjarne Stroustrup写的一本优秀的书,他建议你尽可能晚地声明变量,最好在你使用它之前,但是它没有提到任何好处而不是在变量迟到的时候宣布变量。功能体。

那么像这样迟迟声明变量有什么好处:

int main()
{
  /* some
     code
     here
  */
  int MyVariable1;
  int MyVariable2;
  std::cin >> MyVariable1 >> MyVariable2;
  return(0);
}

而不是像这样的函数体的开头:

int main()
{
  int MyVariable1;
  int MyVariable2;
  /* some 
     code
     here
  */
  std::cin >> MyVariable1 >> MyVariable2;
  return (0);
}

5 个答案:

答案 0 :(得分:5)

它使代码更容易理解。通常,您在需要时声明变量,例如当你想通过该循环找到最少的东西时,在一个循环附近。通过这种方式,当有人读取您的代码时,他不必尝试破译函数开头时25个变量的含义,但变量将解释"通过代码时自己。毕竟,了解变量的含义并不重要,但要了解代码的作用。

请记住,大多数情况下,在代码的一小部分中使用该局部变量,因此在需要它的那一小部分中定义它是有意义的。

答案 1 :(得分:5)

想到的几点

  1. 并非所有对象都是默认的 - 可构造的,因此很多时候在函数开头声明对象不是一个选项,只在赋值时(aka auto myObj = creationalfunction();
  2. 你的函数获得的行数较少,因此更具可读性。在整个代码中,在函数开头声明每个变量确实使它变得更大一些。
  3. 如果你的函数抛出 - 建立一个对象列表是不经济的,只是为了在堆栈展开时销毁它们
  4. 在分配的同一行中声明变量可以让您使用auto,这使代码时间更加灵活。
  5. 这些是C ++的常见惯例,这非常重要。
  6. 创建一个对象+稍后分配它可能比直接初始化一个带有值的对象更慢。

答案 2 :(得分:4)

如果"其他代码"是一个代码页,那么当您读取值时,您实际上无法在屏幕上看到声明。如果您认为您正在阅读两个双打,则无法在屏幕上看到您错了。如果你在一行上声明变量并在下一行使用它,那么任何错误都是显而易见的。

答案 3 :(得分:2)

假设您处理某些对象并构造这些对象是一项昂贵的操作。在这种情况下,为什么在使用它们之前更好地定义变量有几个原因:

1)首先,使用适当的构造函数而不是默认构造和赋值创建对象有时会更快。所以这个:

T obj(/* some arguments here */);

可能比这更快:

T obj;
/* some code here*/
obj = T(/* some arguments here */);

请注意,在第一个示例中,只调用了一个构造函数。但是在第二个示例中,调用了默认构造函数和赋值运算符。

2)如果在对象定义和它的第一次使用之间抛出异常,你只需要做一些不必要的工作来创建和销毁你的对象而不用任何用法。当函数在对象定义和第一次使用之间返回时,这同样适用。

3)是的,可读性在这里也值得一提:)

答案 4 :(得分:1)

当开始擅长编程时,你通常会在同一时间将整个程序放在头脑中。稍后,您将学习如何将此功能简化为一个功能。

这些都限制了您可以使用的程序或功能的大/复杂程度。您可以通过简化正在进行的操作来帮助解决此问题,以便您不再需要考虑它:减少工作内存需求。你也可以将一种复杂性换成另一种; fsncy变量值为一些复杂的高级算法跳舞,或者确定代码的正确性。

有很多方法可以做到这一点。您可以使用可分块模式,并在这些模式中进行思考而不是在较低级别的原语中进行思考(这基本上就是当您从整个程序状态逐渐变为单一功能状态时所执行的操作)。你也可以通过简化你的状态来做到这一点。

每个变量都带有状态。它修改了代码行的含义,以及每个前一行代码的含义,直到它的声明为止。行上存在的变量可以由行修改或由行读取。要理解变量的读取意味着什么,您必须审核其声明与其使用之间的每一行,以便对其进行编辑。

现在,这可能不会发生:但检查都需要时间和工作内存。如果你有10个变量,那么必须记住哪些变量在“上面”被修改过,哪些变量没有,以及它们的值是什么意思可以燃烧很多顶空。

另一方面,创建,使用,或者超出范围或从未再次使用的变量不会导致这种认知负荷。您不必检查隐藏的状态或含义。更重要的是,你不会被诱惑 - 实际上也不能 - 在那条线之前使用它。你肯定不会覆盖以后代码在设置它时依赖的重要状态,并且你不会将它修改为初始化和使用之间令人惊讶的事情。

简而言之,减少使用它的代码行的“状态空间”,甚至不要使用它。

有时这很难实现,有时甚至是不切实际或不可能的。但通常很容易,提高代码质量,使其更易于阅读或理解。最重要的代码是人类,我们不会检查编译器的目标文件输出(或某些中间表示)。

Suc“低状态”代码在事后也更容易修改。在极限中,它成为纯粹的功能代码。