That's only a problem if your language doesn't allow separating computation from executing effects. With monads it's pretty straightforward:
def doD(b: Int, c: Int) = puts(b / c)
def doCD(b: Int) = getInt >>= {c => doD(b, c) >> puts(c)}
def doBCD(a: Int) = getInt >>= {tb => val b = tb+a; doCD(b) >> puts(b)}
getInt >>= {a => doBCD(a) >> puts(a)}