Estamos acostumbrados a hacer los bucles en forma ascendente, lo cual es conveniente en muchos casos.

En otros en cambio, podemos recorrerlos de mayor a menor. Pero, ¿qué ventaja nos daría hacerlo así?

Muy sencillo, de eficiencia. Los bucles descendentes, suelen ser más eficientes que los ascendentes. En particular lo son en estos dos casos:

1) La expresión de inicio es más sencilla que la de fin.
Es el caso más habitual, reescribiéndolo para que vaya de fin hasta inicio, se evita tener que reevaluar una condición complicada en cada iteración.

Es mejor:
for (i=strlen(a); i>0; i–)

que
for (i=0; i<strlen(a); i++)
Ya que nos ahorramos tener que llamar a strlen(a) 100 veces.

2) El comienzo del bucle es 0.
Las arquitecturas x86 y x64, permiten averiguar si un registro vale cero al decrementarlo, sin necesidad de compararlo, ya que se ha activado el flag ZF (zero flag).

El siguiente bucle:
unsigned int i;
for (i=0; i<100; i++)
{
}

Se transformaría a:
xor esi, esi
$L9621:
inc esi
cmp esi, 100
jb SHORT $L9621

En cambio, reescrito descendentemente, el código C:
unsigned int i;
for (i=100; i>0; i–)
{
}

Se compilaría a:
mov esi, 100
$L9621:
dec esi
jne SHORT $L9621

Como podemos ver, hemos evitado tener que ejecutar la instrucción cmp. Por lo que los beneficios crecen en progresión aritmética con el tamaño del bucle.

Estas ventajas son válidas para cualquier lenguaje de programación, siendo más eficaces cuanto más cercano esté el lenguaje a la máquina.