Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中局部静态变量到公共Lisp的转换_C_Opencv_Static_Common Lisp - Fatal编程技术网

C语言中局部静态变量到公共Lisp的转换

C语言中局部静态变量到公共Lisp的转换,c,opencv,static,common-lisp,C,Opencv,Static,Common Lisp,请考虑下面的C代码 //了解更多帧的背景统计信息 无效累积背景(IplImage*I){ 静态int first=1; cvtscale(I,Iscratch,1,0); 如果(!第一个){ cvAcc(Iscratch、IavgF); cvAbsDiff(Iscratch、IprevF、Iscratch2); cvAcc(Iscratch2,IdiffF); i计数+=1.0; } 第一个=0; cvCopy(Iscratch,IprevF); } 代码的设计方式似乎是因为 if(!firs

请考虑下面的C代码

//了解更多帧的背景统计信息
无效累积背景(IplImage*I){
静态int first=1;
cvtscale(I,Iscratch,1,0);
如果(!第一个){
cvAcc(Iscratch、IavgF);
cvAbsDiff(Iscratch、IprevF、Iscratch2);
cvAcc(Iscratch2,IdiffF);
i计数+=1.0;
}
第一个=0;
cvCopy(Iscratch,IprevF);
}
代码的设计方式似乎是因为

if(!first)
该程序将永远不会执行:

cvAcc(Iscratch,IavgF);
cvAbsDiff(Iscratch、IprevF、Iscratch2);
cvAcc(Iscratch2,IdiffF);
i计数+=1.0;
在Lisp中,我试图将其翻译为:

(取消累积背景(i)
(setf第1组1)
(cvt刻度i-scratch-10);;浮动
(如果(不是第一个)
(程序(附件i-scratch-1 i-avg-f)
(abs差异i-scratch-1 i-prev-f i-scratch-2)
(附件i-scratch-2 i-diff-f)
(setf i计数(+i计数1.0)))
(setf第1组0)
(副本i-scratch-1 i-prev-f))
对于等效函数,使用
(不是第一个)
表示
!首先,我认为这是正确的。
在C++中我做的是:

static int first=1;
如果(第一){

cout我不知道你的Lisp怎么了,甚至不知道你的问题是什么,但是原始代码将跳过
!first
中的代码,在第一次调用函数时阻止,并且在以后每次调用函数时执行


我认为您缺少的是
static int first=1;
,因为变量first是静态的(即未存储在堆栈上),它将在函数调用期间保留其值。因此first将是0(即不是first)对于第一次调用之后的所有调用。

这可能是一个意见问题,但我不喜欢C代码的原始方法。我更希望函数的状态取决于它收到的参数,然后取决于一些全局修改的状态

因此,在我看来,重写此函数的好方法(无论使用何种语言)如下所示:

(取消累积背景(impl image&key firstp)…)
或者,如果可能:

(取消累积背景(impl图像)
(标签((%累积背景(第一页)…)
(%累积背景t)))
还有另一种方法可以避免这样的全局变量:

(let(firstp)
(取消累积背景(impl图像)…)
最后,如果由于某种原因两者都不实用,那么状态可以通过使用结构或类来持久化,在这里编写一个完整的示例可能太多了,但是您可以阅读相关内容

最后,有时你会发现包级的特殊变量是需要的,尽管许多人认为最好将宏中的代码隐藏在用户隐藏的变量中,例如:

(定义参数*firstp*t)
(带第一个主体的defmacro(&body)
`(let(*firstp*),@body))

C代码中的变量
first
static
,这意味着它只有一个实例,并且它在对函数的所有调用之间共享。(有关C中的
static
的更多信息,请参阅已接受的答案。)这有点像拥有一个全局变量,只是其他函数无权访问它(因为它不在它们的范围内)。您可以在Common Lisp中使用用
defvar
defparameter
定义的全局变量来模拟这一点,但我认为更简单的转换方法是将整个
defun
包装在
let
中,从而使其保持在已翻译函数的局部

首先,让我们看一看具有类似结构的代码。此代码在第一次执行某些操作,但在后续调用中不执行这些操作:

(let((firstp t))
(大巴)
(当第一次
(打印“已初始化”)
(setf firstp无)
(打印(列表中的“折叠条”))
零)
现在,当我们第一次运行它时,
firstp
为true,因此我们将在输出中看到
initialized
,但在后续运行中,我们不会:

CL-USER>(frob'bar3)
已初始化;打印输出
(泡沫棒3);打印输出
;=>零
CL-USER>(frob’bar5)
(折叠条5);打印输出
;=>零
你得到的C代码实际上在每个调用中都做了一些事情,除了第一次。你也可以用“除非这是第一次,做点什么”来表达这意味着暗示
除非
,你可以用它来清理你的代码。除了
-包装-
取消
和适当的缩进外,我们还有:

(let((第一个t))
(一)
(cvt刻度i-scratch-10);;浮动
(除非先
(附件i-SCRACH-1 i-avg-f)
(abs差异i-scratch-1 i-prev-f i-scratch-2)
(附件i-scratch-2 i-diff-f)
(setf i计数(+i计数1.0)))
(setf首次为零)
(复制i-scratch-1 i-prev-f)))

有关
静态
的更多信息,请参见“否”,不能将
(setf first nil)
移动到
除非
块中,因为这样将永远不会执行
除非
块。此外,“它只需要执行一次”除非
块,否则这不是将任何内容移动到
块的好理由,因为该块将在除一个调用之外的每个调用上执行。@Rörd是的,我确实把它搞砸了!我试图从我给出的第一个示例中保留太多内容。我删除了最后一个错误的代码块和段落。@Joshua Taylor谢谢Joshua Taylor和everyone……还有什么可以帮我的吗……如果我弄明白了,我应该包括我的工作代码吗?@user2735131如果你想将它作为一种附录添加到你的问题的更新中(但保留原始代码)