remix - smart contracts ethereum
¿Cuál es la sintaxis de bucle "para" completa en C(y otras en caso de que sean compatibles)? (6)
He visto algunos bucles muy extraños al leer el código de otras personas. He estado tratando de buscar una explicación de sintaxis completa para el ciclo for
en C
pero es muy difícil porque la palabra " for
" aparece en oraciones no relacionadas que hacen que la búsqueda sea casi imposible para Google de manera efectiva.
Me vino a la mente esta pregunta después de leer este hilo que me volvió curioso de nuevo.
El for
aquí:
for(p=0;p+=(a&1)*b,a!=1;a>>=1,b<<=1);
En el medio, hay una coma que separa los dos códigos, ¿qué hace esta coma? La coma del lado derecho lo entiendo, ya que hace que a>>=1
y b<<=1
.
Pero dentro de una condición de salida de bucle, ¿qué ocurre? ¿Sale cuando p==0
, cuando a==1
o cuando ambos suceden?
Sería genial si alguien pudiera ayudarme a entender esto y tal vez apuntarme en la dirección de una descripción completa for
sintaxis del ciclo.
El estilo C para el bucle consta de tres expresiones:
for (initializer; condition; counter) statement_or_statement_block;
- El inicializador se ejecuta una vez, cuando se inicia el ciclo.
- La condición se comprueba antes de cada iteración. El ciclo se ejecuta siempre que se evalúe como verdadero.
- El contador se ejecuta una vez después de cada iteración.
Cada una de estas partes puede ser una expresión válida en el idioma en que se escribe el ciclo. Eso significa que se pueden usar de forma más creativa. Todo lo que quieras hacer de antemano puede ir al inicializador, cualquier cosa que quieras hacer en el medio puede entrar en la condición o en el contador, hasta el punto donde el bucle ya no tiene cuerpo.
Para lograr eso, el operador de coma es muy útil. Le permite encadenar expresiones para formar una sola nueva expresión. La mayoría de las veces se usa de esa manera en un bucle for, las otras implicaciones del operador de coma (por ejemplo, consideraciones de asignación de valores) desempeñan un papel menor.
Aunque puede hacer cosas inteligentes usando la sintaxis de forma creativa, me mantendría alejado de ella hasta que encuentre una buena razón para hacerlo. Jugar golf de código con bucles for hace que el código sea más difícil de leer y comprender (y mantener).
La wikipedia también tiene un buen artículo en el ciclo for .
Konrad mencionó el punto clave que me gustaría repetir: el valor de la expresión más a la derecha es el valor de la expresión general.
Un compilador Gnu estableció esta advertencia cuando puse dos pruebas en la sección "condición" del ciclo for
warning: left-hand operand of comma expression has no effect
Lo que realmente pretendo para la "condición" fueron dos pruebas con un "&&" entre. Según la declaración de Per Konrad, solo la prueba a la derecha de la coma afectaría la condición.
La coma no es exclusiva de los bucles for; es el operador de coma.
x = (a, b);
hará primero a, luego b, luego establezca x al valor de b.
La sintaxis for es:
for (init; condition; increment)
...
Que es algo (ignorar continue
y break
por ahora) equivalente a:
init;
while (condition) {
...
increment;
}
Entonces su ejemplo de bucle for es (de nuevo ignorando continue
y break
) equivalente a
p=0;
while (p+=(a&1)*b,a!=1) {
...
a>>=1,b<<=1;
}
Que actúa como si fuera (nuevamente ignorando continue
y break
):
p=0;
while (true) {
p+=(a&1)*b;
if (a == 1) break;
...
a>>=1;
b<<=1;
}
Dos detalles adicionales del bucle for que no estaban en la conversión simplificada a un ciclo while anterior:
- Si se omite la condición, siempre es
true
(lo que da como resultado un bucle infinito a menos que unbreak
, ungoto
o algo más rompa el ciclo). - A
continue
actúa como si fuera un goto a una etiqueta justo antes del incremento, a diferencia de uncontinue
en el ciclo while que omitiría el incremento.
Además, un detalle importante sobre el operador de coma: es un punto de secuencia, como &&
y ||
(Por eso puedo dividirlo en declaraciones separadas y mantener su significado intacto).
Cambios en C99
El estándar C99 introduce un par de matices no mencionados anteriormente en esta explicación (que es muy bueno para C89 / C90).
Primero, todos los bucles son bloques por derecho propio. Eficazmente,
for (...) { ... }
está envuelto en un par de llaves
{
for (...) { ... }
}
El estándar dice:
ISO / CEI 9899: 1999 §6.8.5 Declaraciones de iteración
¶5 Una instrucción de iteración es un bloque cuyo alcance es un subconjunto estricto del alcance de su bloque adjunto. El cuerpo del ciclo también es un bloque cuyo alcance es un subconjunto estricto del alcance de la instrucción de iteración.
Esto también se describe en el Fundamento en términos del conjunto adicional de llaves.
En segundo lugar, la porción init
en C99 puede ser una declaración (única), como en
for (int i = 0; i < sizeof(something); i++) { ... }
Ahora el "bloque envuelto alrededor del bucle" entra en sí mismo; explica por qué no se puede acceder a la variable i
fuera del ciclo. Puede declarar más de una variable, pero todas deben ser del mismo tipo:
for (int i = 0, j = sizeof(something); i < j; i++, j--) { ... }
El estándar dice:
ISO / CEI 9899: 1999 §6.8.5.3 El enunciado for
La declaración
for ( clause-1 ; expression-2 ; expression-3 ) statement
se comporta de la siguiente manera: La expresión expresión-2 es la expresión de control que se evalúa antes de cada ejecución del cuerpo del bucle. La expresión expresión-3 se evalúa como una expresión vacía después de cada ejecución del cuerpo del bucle. Si la cláusula-1 es una declaración, el alcance de cualquier variable que declare es el resto de la declaración y todo el ciclo, incluidas las otras dos expresiones; se alcanza en el orden de ejecución antes de la primera evaluación de la expresión de control. Si la cláusula-1 es una expresión, se evalúa como una expresión vacía antes de la primera evaluación de la expresión de control. 133)
Tanto la cláusula-1 como la expresión-3 pueden omitirse. Una expresión-2 omitida se reemplaza por una constante distinta de cero.
133) Por lo tanto, la cláusula-1 especifica la inicialización para el bucle, posiblemente declarando una o más variables para su uso en el bucle; la expresión de control, expresión-2, especifica una evaluación realizada antes de cada iteración, de modo que la ejecución del bucle continúa hasta que la expresión se compare con 0; y expression-3 especifica una operación (como incrementos) que se realiza después de cada iteración.
La coma simplemente separa dos expresiones y es válida en cualquier lugar en C donde se permite una expresión normal. Estos se ejecutan en orden de izquierda a derecha. El valor de la expresión más a la derecha es el valor de la expresión general.
for
bucles constan de tres partes, cualquiera de los cuales también puede estar vacío; uno (el primero) se ejecuta al principio, y uno (el tercero) al final de cada iteración. Estas partes generalmente se inicializan e incrementan un contador, respectivamente; pero pueden hacer cualquier cosa.
La segunda parte es una prueba que se ejecuta al comienzo de cada ejecución. Si la prueba arroja un resultado false
, el ciclo se cancela. Eso es todo al respecto.
Todo es opcional en un bucle for
. Podemos inicializar más de una variable, podemos verificar más de una condición, podemos iterar más de una variable usando el operador de coma.
El siguiente ciclo for
lo llevará a un ciclo infinito. Tenga cuidado al verificar la condición.
for(;;)
el bucle for es ejecución para un tiempo particular para (;;)
el sintex para for loop
para(;;)
O
para (inicializador; condición; contador)
ej. (rmv = 1; rmv <= 15; rmv ++)
ejecución a 15 veces en bloque
1. primero inicializa el valor porque comienza el valor
(por ejemplo) rmv = 1 o rmv = 2
2.segundo enunciado es prueba de que la condición es verdadera o falsa, la condición true no.of time execution the for loop y la condición es false terminate for block,
eg i = 5; i <= 10 la condición es verdadera
i=10;i<10 the condition is false terminate for block,
3.third es incremento o decremento
(por ejemplo) rmv ++ o ++ rmv