在函数getCurrentSize340RecursiveNoHelper()中,我们假设
迭代链表以获取大小。
我知道我可以在 static 或
全球性的,但我的教授说我们应该避免使用它们。
有没有办法做到这一点?
最后一个问题:是的,这是可能的,甚至很容易。软件非常灵活。
没有函数参数的递归(也不是静态变量,也不是全局变量)。
迭代和递归没有参数都很容易做到,一旦你看到了。
通过练习,您可以轻松避免静态变量和全局变量。
另请参阅:https://stackoverflow.com/a/45550373/2785528,它提供了一种简单的机制来“在不使用全局变量的情况下通过系统传递用户输入”。我们可以将其总结为 2 个步骤,a)在 main 早期实例化一个自定义类实例以包含(用于“传输”)任何用户输入/值,否则您将放置在全局变量中以供各种用户获取,然后 b)通过引用需要它们的对象的ctor来传递这些传输对象(类似于旅行箱)。很简单。
感谢教授坚持使用用户定义类型 (UDT)。这是你需要练习的东西。
但是,对于这篇文章,通过忽略您声明没有问题的 UDT 来研究操作方法(没有参数的迭代和递归等)会更简单。这样,我们就可以专注于函数形式。
为了进一步简化,我的示例将是 Functors ... 一种简短而简单的类形式。我推荐 Functor 类既简单又高效。
还有一个简化,我将使用 std::list。有很多关于如何制作、填充和使用这个容器的例子。
一个关键思想(支持无参数函数)是将数据和方法“捆绑”到类中。封装是您的朋友。
想法 1 -- 最小化 main()。保持简短。出去直奔业务。
int main(int, char**)
{
int retVal = 0;
retVal += F820_Iterative_t()();
retVal += F820_Recursive_t()();
return retVal;
}
这里调用了两个函子。我将迭代与递归示例分开。
请注意,这些函子是在 main 的早期调用的。有很多东西在 main 之前被初始化(但请参阅众所周知的初始化惨败)。这简化并控制了这些初始化发生的时间。
第一个函子将实例化、处理、然后析构,在下一个函子开始之前完成其整个生命周期,即它们被序列化。
数据类型:
// examples use std::list
// user typedefs ---------------vvvvvvvvvvv
typedef list<string> StrList_t;
typedef list<string>::iterator StrListIt_t;
数据属性:
// Functor
class F820_Iterative_t
{
// NOTE: class instance data attributes are not global vars
StrList_t m_strList; // std::list<std::string>
StrListIt_t m_it; // std::list<std::string>::iterator
...
// Functor
class F820_Recursive_t
{
StrList_t m_strList; // std::list<std::string>
StrListIt_t m_it; // std::list<std::string>::iterator
...
示例 1 -- 迭代元素计数
// iterate with no parameters, static vars, or global vars
uint F820_Iterative_t::iterateCount( )
{ // --^-- no params
uint lcount = 0;
do // -------------iterative loop
{
if (m_it == m_strList.end()) // detect end of list
break; // kick out
lcount += 1;
m_it++; // step to next element
} while(true);
return(lcount);
}
示例 2 -- 递归元素计数
// recurse with no parameters, static vars, or global vars
uint F820_Recursion_t::recurseCount( )
{ // --^-- no params
if (m_it == m_strList.end()) // RTC (recursion termination clause)
return 0;
m_it++; // step to next element
return (1 + recurseCount()); // tail recursion
} // --^^^^^^^^^^^^-- recursive invocation
在上述两个元素计数函数中,Functor 数据属性在 F820_xxx::xxxCount() 被调用之前被初始化。
此代码不使用函数参数,也不使用全局变量。这些函数(m_it 和 m_strList)中使用的变量是类实例的数据属性。该函数通过隐含的“this”指针直接访问它们。
生活中断。
上面两个 xxxxCount() 用于比较。如果需要,请询问更多,此代码将编译并运行。我打算找时间插入其余部分。