Transformation matrix problem with matrix_world, with different results based on the same values in different form
I think the two answers above pretty much explain what's happening. In case of assignments, we need to understand what's being assigned. Is it value or reference to the memory location (in C, it's called pointer)?

When one does an assignment like:

c1 = bpy.data.objects["Cube.002"].matrix_world

one essentially stores the reference of matrix_world in c1. So if c1 changes, matrix_world would change and vice versa. Since the active object in this case happens to be (I guess) one of the two cubes, let's say Cube.001,  whose matrix world references is held in one of the two references (c2), the assignment to that objects matrix_world with the following line:

bpy.context.active_object.matrix_world = c1 * c2

changes the value referenced by matrix_world. But this is also the value referenced by c2. So when the same statement is executed again c2's value is already changed. This should explain the incremental movement. (I missed this point before since I was thinking the active object is not one of Cube.001 and Cube.002 but the original Cube :).

This does not hold true for h, it's a new memory location, which contains the (static) product of the two matrices. This is static in this particular case since none of the operations are manipulating the value referenced by h. So no matter how many times you assign h to the matrix_world the object is not going to change.