... I thought the 'if the attempt to read a valid number fails, clean up and try again' logic bacomes more obvious with recursion. . . ... Performance is irrelevant in this situation; in the time it takes the user to enter one number, a million instructions can be executed. But just for the sake of argument, let us say that performance is absolutely critical. The last line in the function is: ... This is…

... It is the mnemonic form of the low level code generated by the compiler. Don't bother about it right now. What you need to understand is fairly simple: Performance is a design constraint, not a design goal. Programmer time is more expensive than machine time. People who write compilers are experts at low level optimizations; a typical application programmer is not. So concentrate on the high-level data structures and algorithms; write the simplest, most…

If you can't place the supplied code into the one you posted at the start I'm starting to doubt if you've written it yourself. What is unclear about he code(s) provided and what prevents you from changing your own to follow them?

@vijayan121:
Any specific reason why you chose to recurse on Problem 1 - Line 11? If the user enters a wrong input 5 times, then that function will return 6 times. I would suggest a do while to avoid that.

I thought the 'if the attempt to read a valid number fails, clean up and try again' logic bacomes more obvious with recursion.

.
.

If the user enters a wrong input 5 times, then that function will return 6 times. I would suggest a do while to avoid that.

Performance is irrelevant in this situation; in the time it takes the user to enter one number, a million instructions can be executed.

But just for the sake of argument, let us say that performance is absolutely critical.
The last line in the function is: return int_in_range_from_stdin( min, max ) ;
This is classic tail call recursion, and every mainstream compiler knows how to perform TCO.

For example, with gcc, the tail recursive version of a function typically produces slightly tighter code than the iterative version. For instance, 13 instructions vs. 15 for:

It is the mnemonic form of the low level code generated by the compiler.
Don't bother about it right now.

What you need to understand is fairly simple:

Performance is a design constraint, not a design goal.

Programmer time is more expensive than machine time.

People who write compilers are experts at low level optimizations; a typical application programmer is not.

So concentrate on the high-level data structures and algorithms; write the simplest, most transparent kind of code that you can; do your part well, and let the compiler do its part well.

If you want to multiply an unsigned int value by 8, write:value *= 8 ; and not value <<= 3 ;
You may know that strength reduction is possible, that a shift is faster than a multiply on this particular platform; the writer of the compiler will know at least as much as you do.