Sobre variables

26/04/2009 - 21:49 por Esteban | Informe spam
Saludandolos muy afectuosamente a todos

Duda de principiante.

Si tengo un ciclo:

for ()
{
int entero=0;
.

}

En cada iteracion del ciclo for se esta creando una NUEVA variable 'entero'
?
O se reutiliza la misma?

No es mejor asi poner la declaracion antes del for ?

Preguntas similare

Leer las respuestas

#1 Alberto Poblacion
27/04/2009 - 07:49 | Informe spam
"Esteban" <ee> wrote in message
news:
Saludandolos muy afectuosamente a todos

Duda de principiante.

Si tengo un ciclo:

for ()
{
int entero=0;
.

}

En cada iteracion del ciclo for se esta creando una NUEVA variable
'entero' ?
O se reutiliza la misma?



Depende de como interpretes "nueva" o "reutilizar". La variable va a ir
a parar al Stack, y lo que hace internamente para reservarle sitio es
"mover" el puntero del Stack para hacer un hueco para la variable. Como el
Stack está en el mismo sitio durante todas las iteracíones del bucle, el
"hueco" para la variable va a ir siempre a parar a la misma posición de
memoria. Desde este punto de vista, podrías considerar que se está
reutilizando la variable. En cualquier caso, es irrelevante, puesto que
siempre la inicializas a cero, con lo que se pierde cualquier valor que
tuviera desde la anterior iteración, y en ese sentido se comporta como si
siempre fuera "nueva".

No es mejor asi poner la declaracion antes del for ?



Desde el punto de vista de la mantenibilidad y fiabilidad del programa,
es conveniente declarar cada variable de forma que su alcance y visibilidad
sea los mínimos posibles. En este sentido, es preferible declarar la
variable dentro del bucle en lugar de fuera (suponiendo, claro está, que su
valor no se necesite fuera, y que no tenga que persistir entre iteraciones
del bucle). Desde el punto de vista del rendimiento te va a dar igual.
Aunque la declarases fuera del bucle, iría igualmente a parar al Stack, y
serían igual de costosos los accesos a la variable.
Respuesta Responder a este mensaje
#2 Anonimo
28/04/2009 - 16:06 | Informe spam
Gracias por responderme.

Cuál es el equivalente a "las llaves" en otros lenguajes ?

Eso quiere decir que las llaves ({}) en C# funcionan parecido a una rutina
interna o una llamada a un metodo aparte o como le llaman ahora un método
anónimo, pero que hereda las variables de su metodo contenedor?

Mi duda viene porque en otros lenguajes, un bloque Begin..End (lo que sería
mas o menos equivalente a las llaves de C#) no funciona igual que las llaves
en C#.

Ejemplo en T-SQL, esto compila y funciona perfectamente:

DECLARE @I INT=1

WHILE @I<3
BEGIN
declare @ENTERO INT=@I
SET @I=@I+1
END
SELECT @ENTERO --compila bien y me devuelve 2

En cambio, en C# el equivalente no compila:

int I=1;
while (I<3)
{
int ENTERO=I;
I++;
}
MessageBox.Show(ENTERO.ToString()); //<-Da error aqui ya que ENTERO no
existe


Se entiende mi duda ?

gracias


"Alberto Poblacion"
escribió en el mensaje news:
"Esteban" <ee> wrote in message
news:
Saludandolos muy afectuosamente a todos

Duda de principiante.

Si tengo un ciclo:

for ()
{
int entero=0;
.

}

En cada iteracion del ciclo for se esta creando una NUEVA variable
'entero' ?
O se reutiliza la misma?



Depende de como interpretes "nueva" o "reutilizar". La variable va a ir
a parar al Stack, y lo que hace internamente para reservarle sitio es
"mover" el puntero del Stack para hacer un hueco para la variable. Como el
Stack está en el mismo sitio durante todas las iteracíones del bucle, el
"hueco" para la variable va a ir siempre a parar a la misma posición de
memoria. Desde este punto de vista, podrías considerar que se está
reutilizando la variable. En cualquier caso, es irrelevante, puesto que
siempre la inicializas a cero, con lo que se pierde cualquier valor que
tuviera desde la anterior iteración, y en ese sentido se comporta como si
siempre fuera "nueva".

No es mejor asi poner la declaracion antes del for ?



Desde el punto de vista de la mantenibilidad y fiabilidad del programa,
es conveniente declarar cada variable de forma que su alcance y
visibilidad sea los mínimos posibles. En este sentido, es preferible
declarar la variable dentro del bucle en lugar de fuera (suponiendo, claro
está, que su valor no se necesite fuera, y que no tenga que persistir
entre iteraciones del bucle). Desde el punto de vista del rendimiento te
va a dar igual. Aunque la declarases fuera del bucle, iría igualmente a
parar al Stack, y serían igual de costosos los accesos a la variable.

Respuesta Responder a este mensaje
#3 Anonimo
28/04/2009 - 16:10 | Informe spam
Perdon, salió como 'e' mi nombre. Soy Esteban.


<e> escribió en el mensaje news:
Gracias por responderme.

Cuál es el equivalente a "las llaves" en otros lenguajes ?

Eso quiere decir que las llaves ({}) en C# funcionan parecido a una rutina
interna o una llamada a un metodo aparte o como le llaman ahora un método
anónimo, pero que hereda las variables de su metodo contenedor?

Mi duda viene porque en otros lenguajes, un bloque Begin..End (lo que
sería mas o menos equivalente a las llaves de C#) no funciona igual que
las llaves en C#.

Ejemplo en T-SQL, esto compila y funciona perfectamente:

DECLARE @I INT=1

WHILE @I<3
BEGIN
declare @ENTERO INT=@I
SET @I=@I+1
END
SELECT @ENTERO --compila bien y me devuelve 2

En cambio, en C# el equivalente no compila:

int I=1;
while (I<3)
{
int ENTERO=I;
I++;
}
MessageBox.Show(ENTERO.ToString()); //<-Da error aqui ya que ENTERO no
existe


Se entiende mi duda ?

gracias


"Alberto Poblacion"
escribió en el mensaje news:
"Esteban" <ee> wrote in message
news:
Saludandolos muy afectuosamente a todos

Duda de principiante.

Si tengo un ciclo:

for ()
{
int entero=0;
.

}

En cada iteracion del ciclo for se esta creando una NUEVA variable
'entero' ?
O se reutiliza la misma?



Depende de como interpretes "nueva" o "reutilizar". La variable va a
ir a parar al Stack, y lo que hace internamente para reservarle sitio es
"mover" el puntero del Stack para hacer un hueco para la variable. Como
el Stack está en el mismo sitio durante todas las iteracíones del bucle,
el "hueco" para la variable va a ir siempre a parar a la misma posición
de memoria. Desde este punto de vista, podrías considerar que se está
reutilizando la variable. En cualquier caso, es irrelevante, puesto que
siempre la inicializas a cero, con lo que se pierde cualquier valor que
tuviera desde la anterior iteración, y en ese sentido se comporta como si
siempre fuera "nueva".

No es mejor asi poner la declaracion antes del for ?



Desde el punto de vista de la mantenibilidad y fiabilidad del
programa, es conveniente declarar cada variable de forma que su alcance y
visibilidad sea los mínimos posibles. En este sentido, es preferible
declarar la variable dentro del bucle en lugar de fuera (suponiendo,
claro está, que su valor no se necesite fuera, y que no tenga que
persistir entre iteraciones del bucle). Desde el punto de vista del
rendimiento te va a dar igual. Aunque la declarases fuera del bucle, iría
igualmente a parar al Stack, y serían igual de costosos los accesos a la
variable.





Respuesta Responder a este mensaje
#4 RFOG
28/04/2009 - 16:36 | Informe spam
El ámbito, duración y visibilidad siguen al de C++ casi a pies juntillas.
Meter un bloque de datos entre llaves es crear un nuevo contexto (para que
te hagas una idea, como si llamaras a una función pero con las variables
externas al bloque visibles).

En C++ es muy habitual hacer cosas así:

//Código
int vi;
//Hacer algo con v1...
{
int contador=fi(v1);
f1(contador);
//etc
}

De este modo contador entra y sale de ámbito y duración entre las llaves,
ahorrando pila.

Respecto a lo que comentas de declarar una variable dentro de un bucle y que
se cree en cada iteración, la teoría dice que sí (lo que te ha dicho
Alberto), un compilador de C++ bueno sacará esa variable fuera por
optimización aunque a nivel sintáctico y semántico sería como si estuviera
dentro, lo que hace el C# no tengo ni idea, pero voy a comprobarlo.

<e> wrote in message news:
Gracias por responderme.

Cuál es el equivalente a "las llaves" en otros lenguajes ?

Eso quiere decir que las llaves ({}) en C# funcionan parecido a una rutina
interna o una llamada a un metodo aparte o como le llaman ahora un método
anónimo, pero que hereda las variables de su metodo contenedor?

Mi duda viene porque en otros lenguajes, un bloque Begin..End (lo que
sería mas o menos equivalente a las llaves de C#) no funciona igual que
las llaves en C#.

Ejemplo en T-SQL, esto compila y funciona perfectamente:

DECLARE @I INT=1

WHILE @I<3
BEGIN
declare @ENTERO INT=@I
SET @I=@I+1
END
SELECT @ENTERO --compila bien y me devuelve 2

En cambio, en C# el equivalente no compila:

int I=1;
while (I<3)
{
int ENTERO=I;
I++;
}
MessageBox.Show(ENTERO.ToString()); //<-Da error aqui ya que ENTERO no
existe


Se entiende mi duda ?

gracias


"Alberto Poblacion"
escribió en el mensaje news:
"Esteban" <ee> wrote in message
news:
Saludandolos muy afectuosamente a todos

Duda de principiante.

Si tengo un ciclo:

for ()
{
int entero=0;
.

}

En cada iteracion del ciclo for se esta creando una NUEVA variable
'entero' ?
O se reutiliza la misma?



Depende de como interpretes "nueva" o "reutilizar". La variable va a
ir a parar al Stack, y lo que hace internamente para reservarle sitio es
"mover" el puntero del Stack para hacer un hueco para la variable. Como
el Stack está en el mismo sitio durante todas las iteracíones del bucle,
el "hueco" para la variable va a ir siempre a parar a la misma posición
de memoria. Desde este punto de vista, podrías considerar que se está
reutilizando la variable. En cualquier caso, es irrelevante, puesto que
siempre la inicializas a cero, con lo que se pierde cualquier valor que
tuviera desde la anterior iteración, y en ese sentido se comporta como si
siempre fuera "nueva".

No es mejor asi poner la declaracion antes del for ?



Desde el punto de vista de la mantenibilidad y fiabilidad del
programa, es conveniente declarar cada variable de forma que su alcance y
visibilidad sea los mínimos posibles. En este sentido, es preferible
declarar la variable dentro del bucle en lugar de fuera (suponiendo,
claro está, que su valor no se necesite fuera, y que no tenga que
persistir entre iteraciones del bucle). Desde el punto de vista del
rendimiento te va a dar igual. Aunque la declarases fuera del bucle, iría
igualmente a parar al Stack, y serían igual de costosos los accesos a la
variable.








Microsoft Visual C++ MVP
==Mi blog sobre programación: http://geeks.ms/blogs/rfog
Momentos Leves: http://momentosleves.blogspot.com/
Cosas mías: http://rfog.blogsome.com/
Libros, ciencia ficción y desarrollo
Los asesores son personas místicas que le piden un numero a una compañía y
luego se lo devuelven.
Respuesta Responder a este mensaje
#5 RFOG
28/04/2009 - 16:51 | Informe spam
Vaya, el compilador de C# va haciéndose mayor poco a poco.

En este caso:

for(;;)
{
int entero = 0;
for(;entero<10;entero++)
{
Console.WriteLine(entero);
}
}

Es completamente equivalente a declarar entero dentro del ámbito del bucle
for.

En este:

class Program
{
static void cuad(int i)
{
Console.WriteLine(i * i);
}
static void Main(string[] args)
{
for(;;)
{
int entero = 0;
cuad(entero);
for(;entero<10;entero++)
{
Console.WriteLine(entero);
}
}
}
}

Ni siquiera usa la pila, carga 0 en un registro y salta.

Y eso sin pasar por el jitter.

Pasando por el jitter genera un código más que aceptable, borrando el
registro del procesador donde va contador mediante un xor sobre sí mismo,
exactamente a como se haría con un buen optimizador de C++.

De hecho podría haber metido inline cuad, por lo demás, casi perfecto:

00000000 push rbx
00000001 sub rsp,20h
00000005 xor ecx,ecx
00000007 call FFFFFFFFF717BED0
0000000c mov ebx,1
00000011 lea ecx,[rbx-1]
{
Console.WriteLine(entero);
00000014 call FFFFFFFFF717BED0
00000019 mov ecx,ebx
0000001b call FFFFFFFFF717BED0
00000020 add ebx,2
for(;entero<10;entero++)
00000023 cmp ebx,0Bh
00000026 jl 0000000000000011
00000028 jmp 0000000000000005
0000002a add rsp,20h
0000002e pop rbx
0000002f rep ret


"RFOG" wrote in message
news:
El ámbito, duración y visibilidad siguen al de C++ casi a pies juntillas.
Meter un bloque de datos entre llaves es crear un nuevo contexto (para que
te hagas una idea, como si llamaras a una función pero con las variables
externas al bloque visibles).

En C++ es muy habitual hacer cosas así:

//Código
int vi;
//Hacer algo con v1...
{
int contador=fi(v1);
f1(contador);
//etc
}

De este modo contador entra y sale de ámbito y duración entre las llaves,
ahorrando pila.

Respecto a lo que comentas de declarar una variable dentro de un bucle y
que se cree en cada iteración, la teoría dice que sí (lo que te ha dicho
Alberto), un compilador de C++ bueno sacará esa variable fuera por
optimización aunque a nivel sintáctico y semántico sería como si estuviera
dentro, lo que hace el C# no tengo ni idea, pero voy a comprobarlo.

<e> wrote in message news:
Gracias por responderme.

Cuál es el equivalente a "las llaves" en otros lenguajes ?

Eso quiere decir que las llaves ({}) en C# funcionan parecido a una
rutina interna o una llamada a un metodo aparte o como le llaman ahora un
método anónimo, pero que hereda las variables de su metodo contenedor?

Mi duda viene porque en otros lenguajes, un bloque Begin..End (lo que
sería mas o menos equivalente a las llaves de C#) no funciona igual que
las llaves en C#.

Ejemplo en T-SQL, esto compila y funciona perfectamente:

DECLARE @I INT=1

WHILE @I<3
BEGIN
declare @ENTERO INT=@I
SET @I=@I+1
END
SELECT @ENTERO --compila bien y me devuelve 2

En cambio, en C# el equivalente no compila:

int I=1;
while (I<3)
{
int ENTERO=I;
I++;
}
MessageBox.Show(ENTERO.ToString()); //<-Da error aqui ya que ENTERO no
existe


Se entiende mi duda ?

gracias


"Alberto Poblacion"
escribió en el mensaje news:
"Esteban" <ee> wrote in message
news:
Saludandolos muy afectuosamente a todos

Duda de principiante.

Si tengo un ciclo:

for ()
{
int entero=0;
.

}

En cada iteracion del ciclo for se esta creando una NUEVA variable
'entero' ?
O se reutiliza la misma?



Depende de como interpretes "nueva" o "reutilizar". La variable va a
ir a parar al Stack, y lo que hace internamente para reservarle sitio es
"mover" el puntero del Stack para hacer un hueco para la variable. Como
el Stack está en el mismo sitio durante todas las iteracíones del bucle,
el "hueco" para la variable va a ir siempre a parar a la misma posición
de memoria. Desde este punto de vista, podrías considerar que se está
reutilizando la variable. En cualquier caso, es irrelevante, puesto que
siempre la inicializas a cero, con lo que se pierde cualquier valor que
tuviera desde la anterior iteración, y en ese sentido se comporta como
si siempre fuera "nueva".

No es mejor asi poner la declaracion antes del for ?



Desde el punto de vista de la mantenibilidad y fiabilidad del
programa, es conveniente declarar cada variable de forma que su alcance
y visibilidad sea los mínimos posibles. En este sentido, es preferible
declarar la variable dentro del bucle en lugar de fuera (suponiendo,
claro está, que su valor no se necesite fuera, y que no tenga que
persistir entre iteraciones del bucle). Desde el punto de vista del
rendimiento te va a dar igual. Aunque la declarases fuera del bucle,
iría igualmente a parar al Stack, y serían igual de costosos los accesos
a la variable.








Microsoft Visual C++ MVP
==> Mi blog sobre programación: http://geeks.ms/blogs/rfog
Momentos Leves: http://momentosleves.blogspot.com/
Cosas mías: http://rfog.blogsome.com/
Libros, ciencia ficción y desarrollo
> Los asesores son personas místicas que le piden un numero a una compañía y
luego se lo devuelven.





Microsoft Visual C++ MVP
==Mi blog sobre programación: http://geeks.ms/blogs/rfog
Momentos Leves: http://momentosleves.blogspot.com/
Cosas mías: http://rfog.blogsome.com/
Libros, ciencia ficción y desarrollo
Los asesores son personas místicas que le piden un numero a una compañía y
luego se lo devuelven.
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida