When I'm programming the ESP8266 I have to set GPIO2 high and GPIO0 low. But when I want to use the ESP8266 in my project I have to set GPIO2 and GPIO0 to HIGH, but if they are both high I can't use them as inputs or outputs. So my question is how can I use atleast of the GPIO as an output and starting the ESP8266 without reprogramming it.
ESP8266 was developed for 'Serial over WiFi' as system-on-chip based on the Tensilica processor. The GPIO pins of Tensilica where used for different purposes of the system, like antena, flash memory connection, boot setup etc.
The more general use of the ep8266 as micro-controller with WiFi has evolved, but needs to accept the legacy of the original concept. Smart people even found a way how to share SPI with the flash memory of the system.
If you want to use the IO pins of the esp8266 (they are not called GPIO in datasheet), you must accept the required boot state and use only circuit, sensor or actuator that doesn't disturb it and can handle it.
io0 LOW tels the esp8266 to boot into bootloader flashing mode. It is evaluated by ROM software in the boot process. Pull-up circuit is required to achieve normal boot. So if you want to attach something to this pin, it must accept this conditions. For button it is ideal.
If you want to use io 0 or io 2 as output, use logic that is normally HIGH and make sure it is not connected direct or indirect to ground at startup.