Answers:
不变量比变量更“概念上”。通常,它是程序状态的始终为真的属性。可以确保保持不变的函数或方法被称为保持不变。
例如,二叉搜索树可能具有不变性,即对于每个节点,节点左孩子的关键字小于节点自己的关键字。为该树正确编写的插入函数将保持不变。
如您所知,这不是可以存储在变量中的东西:它更多是关于程序的语句。通过确定程序应维护哪种不变量,然后查看代码以确保其实际维护那些不变量,可以避免代码中的逻辑错误。
维基百科的魔力:不变式(计算机科学)
在计算机科学中,一个谓词(如果为真)将在整个特定操作序列中保持为真,称为该序列的不变式。
如该行所述:
在计算机科学中,一个谓词(如果为真)将在整个特定操作序列中保持为真,称为该序列的不变式。
为了更好地理解这一希望,C ++中的此示例将有所帮助。
考虑一个场景,您必须获取一些值并在名为as的变量中获取它们的总数,count
然后将其添加到称为as的变量中sum
// invariant:
// we have read count grades so far, and
// sum is the sum of the first count grades
上面的代码是这样的,
int count=0;
double sum=0,x=0;
while (cin >> x) {
++count;
sum+=x;
}
上面的代码做什么?
1)从中读取输入cin
并将其放入x
2)成功读取一次后,递增count
并sum = sum + x
3)重复1-2,直到读取停止(即ctrl + D)
不变量必须为True ALWAYS。因此,最初,您仅以此开始代码
while(cin>>x){
}
该循环从标准输入读取数据并存储在x中。好,好。但是因为我们的不变式的第一部分没有被跟随(或保持为真),所以不变式变为假。
// we have read count grades so far, and
简单!增量计数。
这样++count;
会很好!现在我们的代码变成这样,
while(cin>>x){
++count;
}
即使是现在我们不变的(必须是TRUE一个概念)是假的,因为现在我们没有满足的第二部分我们不变的。
// sum is the sum of the first count grades
那么现在该怎么办?
添加x
到sum
并将其存储在sum
(sum+=x
),下一次
cin>>x
将读取一个新值X。
现在我们的代码变成这样,
while(cin>>x){
++count;
sum+=x;
}
// invariant:
// we have read count grades so far, and
// sum is the sum of the first count grades
码:
while(cin>>x){
++count;
sum+=x;
}
啊!。现在,循环不变式始终为True ,代码可以正常工作。
上面的示例取材于Andrew-koening和Barbara-E 的《Accelerated C ++》一书
这里的所有答案都很好,但我觉得我可以进一步阐明这件事:
从语言的角度来看,不变是指永远不变的东西。尽管该概念实际上来自数学,但与归纳相结合时,它是最受欢迎的证明技术之一。
这就是证明的方式,如果您可以找到处于初始状态的不变量,并且该不变量持续存在,而不管对该状态进行任何[合法]转换,那么您就可以证明,如果某个状态不具有此状态,不变,则无论将什么转换顺序应用于初始状态,它都永远不会发生。
现在,以前的思维方式(再次与归纳相结合)使得判断计算机软件的逻辑成为可能。当执行进入循环时,这一点尤其重要,在循环中可以使用不变式来证明某个循环将产生某种结果,或者它永远不会以某种方式改变程序的状态。
当使用不变式作为循环逻辑的谓词时,称为循环不变式。可以在循环外使用它,但是对于循环来说,它确实很重要,因为您经常有很多可能性,或者无限多种可能性。
请注意,我使用“谓词”一词是计算机软件的逻辑,而不是证明。那是因为尽管在数学中不变性可以用作证明,但它永远无法证明计算机软件在执行时会产生预期的效果,这是因为该软件是在许多抽象之上执行的,这是无法证明的他们将产生预期的结果(例如,考虑硬件抽象)。
最后,虽然理论上和严格地预测软件逻辑仅对医疗和军事应用等高关键应用很重要。在调试时,仍然可以使用不变式来帮助典型的程序员。它可以用来知道某个位置的程序失败,因为该程序无法维护某个不变式-无论如何,我们中的许多人在使用它时都没有考虑到它。