while loop for example c for-loop coding-style expression constantfolding

c - example - for loop java



¿Por qué una expresión en lugar de una constante, en un condicional de C for-loop? (7)

Entonces, ¿por qué la gente usa la versión (1 << 7)?

Es una forma de documentación, no es un número mágico sino 2^7 ( dos para la séptima potencia ) lo que es significativo para quien escribió el código. Un compilador de optimización moderno debería generar exactamente el mismo código para ambos ejemplos, por lo que no hay costo por usar este formulario y hay un beneficio de agregar contexto.

Usando godbolt podemos verificar que este es el caso, al menos para varias versiones de gcc , clang e icc . Usando un ejemplo simple con efectos secundarios para asegurar que el código no esté totalmente optimizado:

#include <stdio.h> void forLoopShift() { for(int i = 0; i < (1 << 7); i++) { printf("%d ", i ) ; } } void forLoopNoShift() { for(int i = 0; i < 128; i++) { printf("%d ", i ) ; } }

Para la parte relevante del código, podemos ver que ambos generan lo siguiente: verlo en vivo :

cmpl $128, %ebx

Lo que tenemos es una expresión constante entera como se define en el borrador del estándar C11 sección 6.6 Expresiones constantes que dice:

Una expresión constante entera117) tendrá un tipo entero y solo tendrá operandos que sean constantes enteras, constantes de enumeración, constantes de caracteres, tamaño de expresiones cuyos resultados son constantes enteras, [...]

y:

Las expresiones constantes no deben contener operadores de asignación, incremento, decremento, llamada de función u coma, excepto cuando están contenidos dentro de una subexpresión que no se evalúa.

y podemos ver que se permite evaluar una expresión constante durante la traducción:

Se puede evaluar una expresión constante durante la traducción en lugar del tiempo de ejecución, y en consecuencia se puede usar en cualquier lugar que pueda ser una constante.

En muchas competencias de programación, he visto a personas escribir este tipo de for -loop

for(i = 0; i < (1 << 7); i++)

A menos que me falte algo, eso es lo mismo que

for(i = 0; i < 128; i++)

¿Por qué usar la versión (1 << 7) ?
¿No está calculando la condición cada vez que una sobrecarga innecesaria?


para (i = 0; i <(1 << 7); i ++)

y

para (i = 0; i <128; i ++)

proporciona el mismo rendimiento, pero el desarrollador puede aprovechar enormemente en caso de que (i = 0; i <(1 << 7); i ++) se use en un bucle como

for(int k = 0; k < 8; k++) { for(int i = 0; i < (1 << k); i++) { //your code } }

Ahora está en el límite superior del bucle interno, es decir (1 << k) cambia con una potencia de 2 tiempos de ejecución. Pero es aplicable si su algoritmo requiere esta lógica.


El compilador genera el mismo código para ambos casos. probablemente quiera usar diferentes formas según el contexto.

  1. Puede usar NUM_STEPS o NUM_ELEMENTS_IN_NETWORK_PACKET cuando es una parte constante o una elección de diseño en su algoritmo que desea dejar en claro.
  2. O puede escribir 128 , para dejar en claro que es 128 , una constante.
  3. O escribe 1 << 7 si estás en una competencia y la prueba dice algo así como "corre 2 ^ 7 veces" .

O bien, puede presumir que conoce operaciones de bits.

En mi humilde opinión, la programación es como escribir una carta para dos personas, el compilador y la persona que tendrá que leerla. Lo que quiere decir debe estar claro para ambos.


Es evaluado por el preprocesador ya que ambos operandos son constantes.

Pero si va a usar el número en lugar del desplazamiento de bits, ¿no debería ser 0x0100?


Sí, son equivalentes en comportamiento.

Entonces, ¿por qué la gente usa la versión (1 << 7)?

Supongo que lo usan para documentar que es una potencia de 2.

¡Calcular la condición cada vez debe ser una sobrecarga! ¡No puedo encontrar la razón detrás de esto!

En realidad no, cualquier compilador normal reemplazará 1 << 7 por 128 y, por lo tanto, ambos bucles tendrán las mismas actuaciones.

(C11, 6.6p2) "Se puede evaluar una expresión constante durante la traducción en lugar del tiempo de ejecución, y en consecuencia se puede usar en cualquier lugar que pueda ser una constante".


1 << 7 es una expresión constante, el compilador lo trata como 128 , no hay sobrecarga en el tiempo de ejecución.

Sin el cuerpo del bucle, es difícil decir por qué el autor lo usa. Posiblemente es un bucle que itera algo asociado con 7 bits, pero eso es solo mi suposición.


Traduzcamos cada una de estas opciones al inglés simple:

for(i = 0; i < (1 << 7); i++) // For every possible combination of 7 bits for(i = 0; i < 128; i++) // For every number between 0 and 127

El comportamiento en tiempo de ejecución debe ser idéntico en ambos casos.

De hecho, suponiendo un compilador decente, incluso el código de ensamblado debería ser idéntico.

Entonces, la primera opción se usa esencialmente para "hacer una declaración".

También podría usar la segunda opción y agregar un comentario arriba.