Tail call refers to the return value of the called function as the return value of the called function. If this call calls the function itself (Recursion
Call). This is called tail recursive ). One advantage of using the end call is that it does not consume additional call stack space and can replace the current stack frame. Therefore
Replacing standard calls with end calls is called tail call elimination or tail call optimization ).
Example of the End call:
FunctionFoo (data)
A (data );
ReturnB (data );
B (data) is a tail call.
Here are several examples:
FunctionFoo1 (data)
ReturnA (data) + 1;
FunctionFoo2 (data)
VaR ret = a (data );
ReturnRET;
FunctionFoo3 (data)
VaR ret = a (data );
Return(Ret = 0 )? 1: ret;
Here, only foo2 uses the final call. After foo1 and foo3 call a (data), they also need to return the main control right to call the function. Therefore, they are not the final call.
About tail recursion
We should be familiar with recursive operations. For example, we can use recursion to calculate the length of a one-way linked list:
Int getlenrecursively (node * head)
{
If (Head = NULL)
Return 0;
Return getlenrecursively (Head-> next) + 1;
}
If the single-chain table is very long, the above method may encounter stack overflow, because each thread will allocate a certain size of stack space when executing code (Windows System)
The value is 1 MB or 2 MB. Some information (such as parameters, return addresses, and local variables) will be stored in the stack during each function call. In this way, if the number of calls is too large, it will naturally exceed
The stack space of the thread is now available. Therefore, we can change recursion to the following form:
Int getlentailrecursively (node * head, int ACC)
{
If (Head = NULL)
Return ACC;
Return getlentailrecursively (Head-> next, ACC + 1 );
}
The getlentailrecursively function has an ACC parameter while the ACC parameter is the abbreviation of accumulator. Its function is called before "accumulation" in recursive calls, and pass it into the next recursive call -- this is the biggest difference between the getlentailrecursively function and the getlenrecursively function in recursion mode: the getlenrecursively function requires a "+ 1" call after recursion, while the getlentailrecursively recursive call is the last operation of the function. This is the so-called "tail recursion ". Compared with normal recursion, Because tail recursion is called at the end of the function, the various States accumulated before the function have no significance for recursive call results, therefore, we can completely clear the data left in the stack of this function and give the space to the final recursive call. This optimization prevents recursion from accumulating on the call stack, which means that the real-time "infinite" recursion will not cause stack overflow. This is the advantage of tail recursion.