Postgres: difference between CTE and temporary table
To add to what others have said. Temporary tables can also have primary keys, constraints, indexes, etc. whereas CTEs cannot. 

On the flip side, you can do some pretty neat tricks with CTEs that would be harder, I think, if done with temporary tables-- such as chaining them to perform deletes, inserts, and selects all in one statement. There are some nice examples of "cool-CTE-tricks" here.