Q: Is it safe to assume that the right-hand side of the && and || operators won't be evaluated if the left-hand side determines the outcome?
A: Yes. Idioms like
if(d != 0 && n / d > 0) { /* average is greater than 0 */ }and
if(p == NULL || *p == '\0') { /* no string */ }are quite common in C, and depend on this so-called short-circuiting behavior. In the first example, in the absence of short-circuiting behavior, the right-hand side would divide by 0--and perhaps crash--if d were equal to 0. In the second example, the right-hand side would attempt to reference nonexistent memory--and perhaps crash--if p were a null pointer.
References:
ISO Sec. 6.3.13, Sec. 6.3.14
H&S Sec. 7.7 pp. 217-8