我遇到了一些这些问题,从来没有真正知道处理它的最佳方法。如果我正在编写递归函数并建立答案,但发现当前答案不起作用,我该返回什么。
如果答案应该是一个ArrayList,例如,我不能返回false来说它不起作用。 - 我应该返回一个像null或-1的sentinel值并在递归调用中检查它吗? - 或者该函数应该返回void并且只有在我确定答案时才添加到函数外部的变量 - 或者我应该存储一个保存值的额外参数,如果它不起作用就忽略它(我不知道如何在我当前的例子中这样做) - 或者我应该首先使用检查其是否有效的功能然后执行操作
我目前想要解决的问题类似于计算字符串中的所有排列。不同之处在于,在排列中具有两个连续字符的排列在字母表中不能是连续的,并且顺序相同。例如,不允许“bc”。 “cb”没关系。 不确定这是否是我的问题的一个很好的例子,但如果没有,我的问题仍然存在,因为我总是感到不舒服处理回溯递归。
答案 0 :(得分:1)
是的,通常的方法是返回一个预定义的值(例如-1,或者某些常量,否则你无法从函数的正常操作中获得)。或者,您可以引发异常,然后在递归调用中捕获它。
答案 1 :(得分:0)
从你的问题来看,我认为你的行为是这样的:
struct my_object *rec_foo(int param /* ... */)
{
my_object *tmp = NULL;
int x;
/*
* Do something
*/
/*
* Here you don't know how to handle
* the case where rec_foo() fails
*/
tmp = rec_foo(x /* ... */);
/*
* Other work
*/
return tmp;
}
一种常见的模式是使用返回指针来携带错误代码。这是在Linux内核中进行的,其中-1到-1000之间的所有数字都可以作为错误转换为指针。您可以定义自己的代码并检查返回的指针。
另一个是返回包含错误的枚举值,而函数更新参数指针指向的数据。因此,你的函数的原型将成为
enum rec_foo_error {
REC_FOO_NO_ERROR,
REC_FOO_ERROR_1,
REF_FOO_ERROR_LAST /* Just to retrieve quickly
the number of available errors */
};
// You could simply use an int instead, but this is elegant
enum rec_foo_error rec_foo(struct my_object *obj, int x /*, ... */);