考虑来自 OpenCV Tutorial 8 - Chapter 9 的这段 C 代码
// Learn the background statistics for one more frame
void accumulateBackground( IplImage *I ){
static int first = 1;
cvCvtScale( I, Iscratch, 1, 0 );
if( !first ){
cvAcc( Iscratch, IavgF );
cvAbsDiff( Iscratch, IprevF, Iscratch2 );
cvAcc( Iscratch2, IdiffF );
Icount += 1.0;
}
first = 0;
cvCopy( Iscratch, IprevF );
}
看起来代码的设计方式是因为
if( !first )
程序永远不会执行:
cvAcc( Iscratch, IavgF );
cvAbsDiff( Iscratch, IprevF, Iscratch2 );
cvAcc( Iscratch2, IdiffF );
Icount += 1.0;
在 Lisp 中,我试图将其翻译为:
(defun accumulate-background (i)
(setf 1st 1)
(cvt-scale i i-scratch-1 1 0) ;; To float
(if (not 1st)
(progn (acc i-scratch-1 i-avg-f)
(abs-diff i-scratch-1 i-prev-f i-scratch-2)
(acc i-scratch-2 i-diff-f)
(setf i-count (+ i-count 1.0))))
(setf 1st 0)
(copy i-scratch-1 i-prev-f))
对于等效函数,(not 1st)
用于 !first
,我认为这是正确的。
在 C++ 中,我这样做:
static int first = 1;
if( first ){
cout << "reached this part of code " << endl << " " << first << endl << endl;
}
但由于代码设计的原因,似乎永远不会产生任何输出。为什么教程代码的设计者会这样?他正在从学习 OpenCV 中复制。
最佳答案
C 代码中的变量first
是static
,这意味着它只有一个实例,并且在所有实例之间共享对函数的调用。 (有关 C 中的 static
的更多信息,请参阅 What does "static" mean? 的已接受答案。)这有点像拥有一个全局变量,只是其他函数无法访问它(因为它不是在他们的范围内)。您可以使用用 defvar
或 defparameter
定义的全局变量在 Common Lisp 中对此进行模拟,但我认为更直接的翻译将通过包装整个defun
在 let
中。
首先,让我们看一下具有相似结构的东西。此代码在第一次 时执行某些操作,但不会在后续调用中执行:
(let ((firstp t))
(defun frob (bar)
(when firstp
(print 'initialized)
(setf firstp nil))
(print (list 'frobbed bar)))
nil)
现在,当我们第一次运行它时,firstp
为真,所以我们将在输出中看到initialized
,但是后续运行,我们不会:
CL-USER> (frob 'bar3)
INITIALIZED ; printed output
(FROBBED BAR3) ; printed output
;=> NIL
CL-USER> (frob 'bar5)
(FROBBED BAR5) ; printed output
;=> NIL
您获得的 C 代码实际上在每次调用时都执行某些操作, 第一次调用除外。您也可以将其表述为“除非是第一次,否则请做某事”。那里的“除非”意味着暗示unless
,你可以用它来稍微清理一下你的代码。除了 let
-wrapping-defun
和适当的缩进,我们还有:
(let ((first t))
(defun accumulate-background (i)
(cvt-scale i i-scratch-1 1 0) ;; To float
(unless first
(acc i-scratch-1 i-avg-f)
(abs-diff i-scratch-1 i-prev-f i-scratch-2)
(acc i-scratch-2 i-diff-f)
(setf i-count (+ i-count 1.0)))
(setf first nil)
(copy i-scratch-1 i-prev-f)))
关于c - 将 C 中的局部静态变量翻译成 Common Lisp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19062562/