Estaba convirtiendo un algoritmo de C ++ a C #. Encontré esto para el bucle:
for (u = b.size(), v = b.back(); u--; v = p[v])
b[u] = v;
No da ningún error en C ++, pero sí en C # (no puede convertir int a bool). Realmente no puedo entender esto para el bucle, ¿dónde está la condición?
¿Alguien puede explicar?
PD. Solo para verificar, para adaptar un VECTOR a una LISTA, ¿corresponde b.back () a b [b.Count-1]?
u--
. Los punto y coma se utilizan para delimitar las diversas partes de lafor
declaración.; u-- != 0;
b
,u
,v
, etc. La única razón por la que fueron nombrados de esta manera es porque alguien quería mirar inteligente al hacer su código ilegible.do
significa en C ++"? Obtendrá miles de visitas de principiantes que buscan un tutorial.Respuestas:
La condición del
for
bucle está en el medio, entre los dos puntos;
y comas .En C ++ está bien poner casi cualquier expresión como condición: cualquier cosa que se evalúe como cero significa
false
; medios distintos de cerotrue
.En su caso, la condición es
u--
: cuando convierta a C #, simplemente agregue!= 0
:fuente
u = b.size() - 1
lugar.Muchas respuestas precisas, pero creo que vale la pena escribir el bucle while equivalente.
Es equivalente a:
Puede considerar refactorizar al formato while () a medida que traduce a C #. En mi opinión, es más claro, menos trampa para los nuevos programadores e igualmente eficiente.
Como otros han señalado - pero para que mi respuesta completa - para que funcione en C # que se necesita para el cambio
while(u--)
awhile(u-- != 0)
.... o
while(u-- >0)
solo en caso de que comience negativo. (OK,b.size()
nunca será negativo, pero considere un caso general donde quizás algo más lo inicializó).O, para hacerlo aún más claro:
Es mejor ser claro que ser conciso.
fuente
while (u-- >0)
forma. Si el espacio se desordena, puede terminar con un bucle "a cero"while (u --> 0)
, que tiende a confundir a todos a primera vista. ( No estoy seguro de si es válido C #, pero está en C, y creo que podría estarlo también en C ++ ).for
lugar de,while
es precisamente que pones la inicialización y el incremento / decremento en una declaración, y eso no necesariamente hace que el código sea más difícil de entender. De lo contrario, no deberíamos estar usandofor
en absoluto.--
token seguido de un>
token. Dos operadores separados. Un ciclo de "bajar a cero" es solo una combinación directa de post-decremento y mayor que. La sobrecarga de operadores de C ++ no crea nuevos operadores, solo reutiliza los existentes.La condición es
u--;
, porque está en la segunda posición de la de la instrucción.Si el valor de
u--;
es diferente de 0, se interpretará comotrue
(es decir, se convierte implícitamente en el valor booleanotrue
). Si, en cambio, su valor es 0, se convertirá enfalse
.Este es un código muy malo .
Actualización: Discutí la escritura de bucles "for" en esta publicación de blog . Sus recomendaciones se pueden resumir en los siguientes párrafos:
Este ejemplo viola claramente estas recomendaciones.
fuente
Esta será la forma C # de su ciclo.
Simplemente reemplace el equivalente para size () y back ().
Lo que hace es invertir la lista y almacenar en una matriz. Pero en C # tenemos directamente una función definida por el sistema para esto. Por lo tanto, no necesita escribir este bucle también.
fuente
v = b.back();
de la intializer para no acabas de cambiar la forma en que funciona, ya que elv = p[v]
que se sustituye conv = b.back();
se ejecutó una vez antes de que comenzaran las iteraciones yv = p[v]
se ejecutó al comienzo de cada iteración. En esa versión de C #v = p[v]
todavía se ejecuta al comienzo de cada iteración, perov = b.back();
se ejecuta inmediatamente después, cambiando el valor dev
la siguiente instrucciónb[u] = v;
. (tal vez la pregunta fue editada después de leerla)v = b.back()
. Lo tiene ejecutándose en cada iteración del bucle en lugar de solo la primera: no sabemos québack()
hace (¿hay algún efecto secundario? ¿Cambia la representación interna deb
?), Por lo que este bucle no es equivalente al de la pregunta.v = b.back()
se moviera fuera del bucle, por encima de él. (Además, si está tratando de responder a alguien,@
Es la inicialización.
Es la condición.
es la iteración
fuente
La condición es el resultado de
u--
, que es el valor deu
antes de que fuera decrementado.En C y C ++, an
int
es convertible a bool haciendo una!= 0
comparación implícita (0 esfalse
, todo lo demás estrue
).b.back()
es el último elemento en un contenedor, que esb[b.size() - 1]
cuándosize() != 0
.fuente
En C, todo lo que no sea cero está
true
en contextos "booleanos", como la condición de finalización del ciclo o una declaración condicional. En C # que tiene que hacer esa comprobación explícita:u-- != 0
.fuente
Como han dicho otros, el hecho de que C ++ tenga conversión implícita a booleana significa que el condicional es
u--
, lo que será cierto si el valor no es cero.Vale la pena agregar, que tienes una suposición falsa al preguntar "dónde está el condicional". En C ++ y C # (y otros lenguajes sintaxis similares) puede tener un condicional vacío. En este caso siempre se evalúa como verdadera, por lo que el bucle continúa para siempre, o hasta que alguna otra condición que las salidas (a través de
return
,break
othrow
).De hecho, cualquier parte de la declaración for puede omitirse, en cuyo caso simplemente no se realiza.
En general,
for(A; B; C){D}
o sefor(A; B; C)D;
convierte en:Cualquiera o más de A, B, C o D pueden quedar fuera.
Como resultado de esto, algunos favorecen los
for(;;)
bucles infinitos. Lo hago porque, aunquewhile(true)
es más popular, lo leí como "hasta que la verdad deje de ser verdad", lo que suena algo apocalíptico en comparación con mi lecturafor(;;)
como "para siempre".Es una cuestión de gustos, pero como no soy la única persona en el mundo a la que le gusta
for(;;)
, vale la pena saber lo que significa.fuente
todas las respuestas son correctas:
for loop se puede usar de varias maneras de la siguiente manera:
fuente
En el código anterior,
u
yv
se inicializan conb.size()
yb.back()
.Cada vez que se verifica la condición, también se ejecuta la declaración de decremento, es decir
u--
.El
for
bucle saldrá cuandou
se convierta0
.fuente
El error encontrado en C # en sí borra la duda. El bucle for busca un
condición para terminar. Y como sabemos
pero C # no puede procesar esto por sí solo a diferencia de C ++. Entonces, la condición que estás buscando es
pero tienes que dar explícitamente la condición en C # como
o
Pero aún así trate de evitar este tipo de práctica de codificación. los
mencionado anteriormente en la respuesta es una de las versiones más simplificadas de su
fuente
Si está acostumbrado a C / C ++, este código no es tan difícil de leer, aunque es bastante conciso y no es tan bueno de código. Permítanme explicar las partes que son más Cism que cualquier otra cosa. Primero, la sintaxis general de un bucle C for se ve así:
El código de inicialización se ejecuta una vez. Luego, la condición se prueba antes de cada ciclo y, finalmente, se llama al incremento después de cada ciclo. Entonces, en su ejemplo, encontrará que la condición es
u--
¿Por qué
u--
funciona como una condición en C y no en C #? Debido a que C convierte implícitamente muchas cosas demasiado, esto puede causar problemas. Para un número, todo lo que no sea cero es verdadero y cero es falso. Por lo tanto, contará desde b.size () - 1 a 0. Tener el efecto secundario en la condición es un poco molesto y sería preferible colocarlo en la parte de incremento del ciclo for, aunque mucha C El código hace esto. Si lo estuviera escribiendo lo haría más así:La razón de esto es, al menos para mí, es más claro. Cada parte del bucle for hace su trabajo y nada más. En el código original, la condición estaba modificando la variable. La parte de incremento estaba haciendo algo que debería estar en el bloque de código, etc.
El operador de coma también puede estar lanzándole un bucle. En C, algo así
x=1,y=2
parece una declaración en lo que respecta al compilador y se ajusta al código de inicialización. Simplemente evalúa cada una de las partes y devuelve el valor de la última. Así por ejemplo:imprimiría 2.
fuente