Вони обидва однакові, і ось як ви можете це дізнатись, подивившись, що робить компілятор (навіть без оптимізації, встановленої на високу):
Подивіться, що робить компілятор (gcc 4.0) на ваших простих прикладах:
1.c:
main(){ int var; while(int i < 100) { var = 4; } }
gcc -S 1.c
1.s:
_main:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $0, -16(%ebp)
jmp L2
L3:
movl $4, -12(%ebp)
L2:
cmpl $99, -16(%ebp)
jle L3
leave
ret
2.c
main() { while(int i < 100) { int var = 4; } }
gcc -S 2.c
2.s:
_main:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $0, -16(%ebp)
jmp L2
L3:
movl $4, -12(%ebp)
L2:
cmpl $99, -16(%ebp)
jle L3
leave
ret
З них видно дві речі: по-перше, код однаковий в обох.
По-друге, сховище для var виділяється поза циклом:
subl $24, %esp
І нарешті, єдине, що є у циклі, - це призначення та перевірка стану:
L3:
movl $4, -12(%ebp)
L2:
cmpl $99, -16(%ebp)
jle L3
Що приблизно настільки ефективно, наскільки ви можете бути, не видаляючи цикл повністю.