属性:estimated-stack-usage
pragma 提供了堆栈大小要求的估计值。
具有递归调用的方法无法通过堆栈检查,因为无法确定堆栈使用情况。结果,发出警告。为防止出现此警告,您可以为该方法提供堆栈大小要求的估计值(以字节为单位)。然后该方法成功通过堆栈检查。
句法
{attribute 'estimated-stack-usage' := ' <estimated stack size in bytes> '}
插入位置:方法声明部分上方的第一行。
例 264. 例子
{attribute 'estimated-stack-usage' := '127'} // 127 bytes METHOD PUBLIC DoIt : BOOL VAR_INPUT END_VAR
有关更多信息,请参阅: 方法调用
递归方法调用
在其实现中,方法可以调用自身,或者直接通过 THIS
指针,或通过分配功能块的局部变量。
提示
使用递归主要用于处理递归数据类型,例如链表。一般来说,我们建议在使用递归时要小心,因为意外的深度递归会导致堆栈溢出和机器停机。
例 265. 阶乘的计算
以下程序 PLC_PRG
计算一个数的阶乘 FB_Factorial
功能块以不同的方式,每个都有自己的方法。
方法
m_Iterative
: 迭代方法
m_Pragmaed
: 带有警告抑制的递归方法
m_Recursive
: 递归方法
m_Temp
: 暂时带有警告抑制
发出警告 m_Recursive
方法而已。

// Contains the data of the factorial calculation of uiNumber TYPE FACTORIAL_RESULT : STRUCT uiNumber : UINT; udiIterative : UDINT; udiRecursive : UDINT; udiPragmaed : UDINT; udiTemp : UDINT; END_STRUCT END_TYPE PROGRAM PLC_PRG VAR fb_Factorial_A : FB_Factorial; factorial_A : FACTORIAL_RESULT := (uiNumber := 9, udiIterative := 0, udiRecursive := 0, udiPragmaed := 0 ); END_VAR fb_Factorial_A.p_Number := factorial_A.uiNumber; factorial_A.udiIterative := fb_Factorial_A.m_Iterative(); factorial_A.udiRecursive := fb_Factorial_A.m_Recursive(uiN := factorial_A.uiNumber); factorial_A.udiPragmaed := fb_Factorial_A.m_Pragmaed(uiN := factorial_A.uiNumber); factorial_A.udiTemp := fb_Factorial_A.m_Temp(uiN := factorial_A.uiNumber); //Factorial calculation in different ways FUNCTION_BLOCK FB_Factorial VAR_INPUT END_VAR VAR_OUTPUT END_VAR VAR uiN : UINT; udiIterative : UDINT; udiPragmaed : UDINT; udiRecursive : UDINT; END_VAR // Iterative calculation METHOD PUBLIC m_Iterative : UDINT VAR uiCnt : UINT; END_VAR m_Iterative := 1; IF uiN > 1 THEN FOR uiCnt := 1 TO uiN DO m_Iterative := m_Iterative * uiCnt; END_FOR; RETURN; ELSE RETURN; END_IF; //Recursive calculation with suppressed warning {attribute 'estimated-stack-usage' := '99'} METHOD PUBLIC m_Pragmaed : UDINT VAR_INPUT uiN : UINT; END_VAR VAR END_VAR m_Pragmaed := 1; IF uiN > 1 THEN m_Pragmaed := uiN * THIS^.m_Pragmaed(uiN := (uiN - 1)); RETURN; ELSE RETURN; END_IF; //Recursive calculation METHOD PUBLIC m_Recursive : UDINT VAR_INPUT uiN : UINT; END_VAR VAR END_VAR m_Recursive := 1; IF uiN > 1 THEN m_Recursive := uiN * THIS^.m_Recursive(uiN := (uiN - 1) ); RETURN; ELSE RETURN; END_IF; // Called by temporary FB instance {attribute 'estimated-stack-usage' := '99'} METHOD PUBLIC m_Temp : UDINT VAR_INPUT uiN : UINT; END_VAR VAR fb_Temp : FB_Factorial; END_VAR m_Temp := 1; IF uiN > 1 THEN m_Temp := uiN * fb_Temp.m_Temp(uiN := (uiN - 1)); RETURN; ELSE RETURN; END_IF; PROPERTY p_Number : UINT uiN := p_Number; //Setter method
只有 m_Recursive
程序执行时发出警告。
