Most programming languages use a software structure called a stack for calculations. When you write something like a + b, the value of a is pushed onto the top of the stack, then the value of b is pushed onto the stack (so that stack has b then a on it). Then when the computer processes the +, it pops (removes) the values of a and b, adds them, and pushes the answer on the stack.
When you say a = c * d; the following steps occur:
1. the address of a is pushed onto the stack
2. The value of c is pushed on the stack
3. The value of d is pushed on the stack
4. they're both popped, multiplied and the product pushed on the stack
5. the result is popped off the stack, the address is popped off the stack, and the result copied to the location specified by the address. Once this happens, the stack is now empty and ready to use for the next statement.
So what happens when we say a = 5.0 * sin (b+c)?
1. The address of a is pushed
2. The value 5.0 is pushed
3. The value of b is pushed
4. The value of c is pushed
5. b and c are popped, added, and the sum pushed
6. The sin() function is called
And what happens inside sin()?
6.1 The value of b+c is popped off the stack
6.2 The sine of b+c is calculated (probably using the stack)
6.3 The result of sin(b+c) is pushed onto the stack.
6.4 The sin() function finishes
7. The result of sin(b+c) is popped off the stack, 5.0 is popped off the stack, they're multiplied together and the product pushed on the stack.
7. The result of sin() is popped from the stack, 5.0 is popped from the stack, they're multiplied together and the product pushed onto the stack. [The stack now has the result of 5*sin(b+c) at the top, followed by the address of a]
8. The top two values are popped from the stack and the assignment to a is completed.
All functions put their calculated answers on the top of the stack, and the "return" statement is simply what the programmer writes to make this happen. So when you say "return 10;" the value 10 is simply pushed on the top of the stack. There it waits until the next part of the program makes use of it in some way.
What happens if you don't return a value? If you don't return a value then you'll screw up the stack! For this reason, a good compiler always insists that you have a return statement for every function, and will flag an error if you don't.
Stacks are a basic feature in computing and there's stacks of information about them available on the web.