其实setjmp/longjmp 我也没真正用过,只是看过一点说明而已."如果你真地很清楚,那我对我的怀疑道歉。但我相信C库的设计者的程度要超过相信你无数倍。
C库的设计者不会连栈顶指针这种问题都考虑不到吧?"我这么说也是因为我对C的栈式结构,setjmp/longjmp 的理解,对C库的设计者的相信(实际就是我对自己并不十分肯定
setjmp/longjmp 肯定是有side effect的,如过程中malloc以后有可能没被free掉.
的确它不是完美的.如在实际情况中,我也会同意你的看法."but anyway, I would choose iteration rather than resorting to setjmp/longjmp."
最后,为我在过程中的不好行为致歉!
many sorries to lx_cyh!
My fault.
setjmp/longjmp does not have stack problem. as long as the statements after the recursive call have no side-effect (like destructor, close(), delete etc), setjmp/longjmp should work.
Slap me!
but anyway, I would choose iteration rather than resorting to setjmp/longjmp.
for searching a bst (I think that's more reasonable if we use tree):
Tree* find(Tree* t, int data){
if(t->data==data)return t;
else if(t->data > data)return find(t->getLeft(), data);
else return find(t->getRight(), data);
}
and that is tail recursion.
for searching a non-bst, a typical solution(not too efficient, but clear):
the getLeft(), getRight() may throw exception.
Tree* find(Tree* t, T data){
//throw exception if not found
if(t->data == data)return t;
try{
return find(t->getLeft(), data);
}
catch(char* msg){
return find(t->getRight(), data);
}
}
a C version would be:
Tree* find(Tree* t, int data){
Tree* ret;
if(t==NULL)return NULL;
if(t->data==data)return t;
ret = find(t->left, data);
if(ret != NULL )return ret;
else return find(t->right, data);
}
a finer solution can use continuation to get tail recursion:
Tree* find(Tree* t, int data, List* cont){
if(t==NULL){
if(cont == NULL) return NULL;
else{
Tree* nextTree = cont->tree;
List* nextCont = cont->next;
free(cont);
return find(nextTree, data, nextCont)
}
}
else{
if(t->data==data){
freeList(cont);
return t;
}
else{
return find(t->left, data, consList(cont, t->right));
}
}
}
the two helper functions, consList and freeList would be straight forward.
I did not test it, it may still have bugs in it. But you can see the logic here.