7

我正在阅读 Gilles Dowek 的《语言编程原理》

他说,也可以声明一个变量而不给它一个初始值,而且我们必须小心不要使用一个没有初始值声明的变量并且没有被赋值。这会产生错误。

注意:本书的作者提到了在 Java 上声明没有初始值的变量的可能性。

那么,为什么这个变量声明是有效的呢?我什么时候使用它?

4

8 回答 8

8

例如,你可以有这样的东西:

int i;
if (first_condition)
    i = 1;
elseif (second_condition)
    i = 2;
else
    i = 0;

您的变量需要在外部声明if以供以后使用,但其值在if条件内是固定的。

于 2012-12-09T14:01:50.267 回答
8

许多不同的语言有许多不同的原因。

内存
当您声明一个变量时,您需要一些内存来保存该变量。这涉及向操作系统的内核请求内存,或某种跟踪内存的监视程序。简而言之,这可能是一项昂贵的操作。因此,在许多情况下,希望同时分配对象所需的所有内存,然后再分配以后必须分配给它的任何值。这样,您可以提高程序在关键部分的性能。这个用例很常见,以至于允许在没有初始化的情况下声明的特性是允许的。然而,良好的实践断言,在所有其他情况下,您应该在分配时初始化变量。

将内存分配视为官僚机构。文书工作太多了。因此,如果您知道稍后将使用大量内存,您可以在单个事务中预先请求大量内存,而不是每次都请求内核。

昂贵的初始化
这一点与上面的一点非常相似。假设您有一个 100 万乘以 100 万的数组。初始化这样一个数组是一个昂贵的过程。使用默认值这样做是愚蠢的,因此,这样的功能是分配内存然后根据需要使用。

在这里,就像您购买大量乐高积木来构建某些东西,但您想以默认蜘蛛侠的形状购买它们。无论如何,当您以后要重塑它们时,店主或您将不得不更加努力地将它们制成蜘蛛侠的形状。

于 2012-12-09T15:22:45.950 回答
3

如果你真的看看当你声明一个变量并初始化它(分配一个初始值)时会发生什么,你会发现在机器指令级别或 Java 的字节码中,这两者都使用了大量的计算能力脚步。

  1. 声明变量意味着分配内存、创建请求类型的实例等
  2. 然后初始化该内存位置,再次需要更多处理以将默认值移动到分配的内存位置,例如如果默认值为 0,则用 0 填充它。(注意:当随机内存位置分配给内存可能包含的变量时任何模式,由前一个值留在那里)

因此,如果用户在没有首先为其类型提供可接受的值的情况下使用变量,那么如果存在的值不正确,则可能会出现错误。

因此,如果一种语言强制你在声明时初始化一个变量(或自己这样做),那么它会减少出错的机会,但它可能会浪费处理能力来处理你并不真正想要的东西。

另一方面,如果它允许您在不初始化变量的情况下声明变量,它会给您控制权,并且可能会为您节省一些计算能力,但会增加出错的机会。(假设您有一个场景,变量的初始值取决于其他一些条件,这些条件将相应地考虑并分配变量。在这种情况下,在声明时初始化 var 可能只是浪费处理能力)。

语言决定他们想走哪条路,主要取决于他们认为自己的力量是什么。

如果它是为了让程序员有机会控制并制作高度优化的程序,那么除了更多的东西之外,他们通常会允许在不初始化的情况下声明变量。

但是,如果该语言是关于强迫程序员编写更多无错误的程序,那么它将采用另一条路径。

于 2012-12-09T14:23:52.793 回答
2

如果 Java 要求类对象的字段必须始终在读取之前写入,这将要求要么

  • 类对象的构造函数必须写入该对象的所有字段,包括那些在以后没有第二次编写的情况下编码永远不会读取的字段;这既丑陋又低效。

  • 每个字段都必须能够保存一个never been written不同于可以写入它的任何其他值的值。

  • 编译器必须解决停止问题以确定是否可以在未写入的情况下读取字段。

  • 语言必须接受在没有用户代码编写的情况下读取字段的可能性。

在这些可能的选择中,#4 是最不邪恶的。为了避免未定义的行为,Java 定义了读取从未写入的字段的行为:它将包含其类型的默认值。

于 2013-12-06T00:34:26.850 回答
1

例如,您可以在验证脚本中声明一个空 var,

$error='';
if(empty($_POST['first_name']{
$error=$error."You did not enter a name";

}

像这样,但我只会在代码重新声明它之后立即使用它,如上所述,这样它就不会被“放错”。

于 2012-12-09T14:07:53.953 回答
1

好的,这是一个例子。我目前正在设置在 PDF 论坛上设置为持久的全局值。对于这个应用程序,我想将这些值用作数据存储,就像文本字段一样。不是最好的方法,但它适用于这个例子。我可以将值设置为持久的全局变量,而不是用数百个隐藏的文本字段填充我的论坛。

如果我的初始减速度设置为0“”作为变量的值,它将不会在会话之间保留数据。论坛的初始化会将值重置为空。就像 Scrips 一样,论坛按顺序运作。在分配值以传递变量之前,它将首先识别文档中的所有脚本。因此有必要声明没有值的变量,以便初始化不会替换值。

一般来说,在顶部声明所有变量也是很好的内务管理。可以随时声明它们,但我发现当向脚本添加新元素时,我必须上下移动行以保持代码干净。如果变量在使用时就声明了,那么在声明之前使用变量也变得非常容易,这是行不通的。

此外

在声明时分配值是有效的,但不是通用的占位符值。在大多数脚本中,int 并不像说int x = 5 那样简单; 更多时候我们调用诸如this.getField("TextBox3").value;这样的数据。或其他一些行代码。通过分配诸如“”0true之类的通用值,即使您未能正确使用某个值,您的函数也可以工作。通过不分配值,如果您未能利用变量,那么您的函数将失败,从而允许您在解决问题时缩小可能性。如果int x; 在您使用x时仍然是NaN而您的数据收集和验证可能是问题的根源。

一般来说,在顶部声明所有值并避免设置通用值,除非你必须这样做。如果您要稍后定义x的值,请不要将其设置为int x = 0; .

于 2017-04-01T12:57:08.450 回答
1

我是 C++ 新手,但我认为这些信息也可能会有所帮助。

来自:编程:使用 C++ 的原则和实践

为什么 C++ 同时提供声明和定义?声明/定义的区别反映了我们需要使用什么(接口)和我们需要什么来做它应该做的事情(一个实现)之间的根本区别。对于变量,声明提供类型,但只有定义提供对象(内存)。对于函数,声明再次提供类型(参数类型加上返回类型),但只有定义提供函数体(可执行语句)。请注意,函数体作为程序的一部分存储在内存中,因此可以公平地说函数和变量定义会消耗内存,而声明则不会。

于 2020-05-02T00:35:27.703 回答
0

就像是:

//declare without giving value.
int i;

//set value
i=9;
于 2012-12-09T14:02:17.217 回答