CS/CE 218 Lecture -*- Outline -*- * simplifications and equivalence rules for C ** expressions expression equivalent form i = i + 2 i += 2 i += 1 ++i note: i += 1 is not i++ ~e == f e == ~f !e == f e == !f !(e == f) e != f) !(a && b) !a || !b !(a || b) !a && !b ... ... *** equivalences for increment and decrement operators ++i i+=1 i++ (temp=i, i+=1, temp) note: temp must be fresh note: i++ is not the same as i+=1 *** optimizations of integer arithmetic i / 2 i >> 1 i * 2 i << 1 ... ... ~(a & b) ~a | ~b ~(a | b) ~a & ~b *** expressions in various contexts **** conditionals if (e != 0)... if (e)... if (b) x=3; else x=4 x = b ? 3 : 4 **** result of a function if (b != 0) then return 1; return b != 0; else 0; **** elimination of variables often variables can be eliminated by making expressions more complex. In a pure function this is often justified e.g., long int fact(unsigned int n) { long int res = 1; for ( ; n > 0; --n) { res *= n; } return res; } can be written more functionally as: long int fact(unsigned int n) { if (n == 0) then return 1 else return n * fact(n-1); } or even long int fact(unsigned int n) { return (n == 0) ? 1 : n * fact(n-1); } If you're tempted to write a macro like: #define greater_than_8(n) (n > 8) consider using a function instead int greater_than_8(int n) { return n > 8; } ** statements (eliminating duplication) If you see the same constant used more than once, put it in a #define If you see the same code used more than once, put it in a function. S1; do { while (b) S1; S1; while (b); ...complex_expr(x,y); /* decl of fresh */ /* no change to x, y */ fresh = complex_expr(x,y); ...complex_expr(x,y); ...fresh; /* no change to x, y */ ...fresh; if (b) { if (b) { S1; S1; S2; } } else { S2; } other techniques include introducing paramterization (generalizing funs).