domingo, 29 de agosto de 2021

El bucle for in do.

La sentencia for in do (for in do loop) está disponible desde la versión 2.4.2 del compilador Free Pascal, es decir, es relativamente nueva y no existe ni en Pascal ni en Turbo Pascal, sí en Object Pascal de Delphi, aunque hay algunas "cosillas" que se pueden hacer con Free Pascal y no con Delphi, respecto de esta sentencia de iteración.

Seguramente para los nuevos (y no tan nuevos) programadores no hay ninguna novedad con este bucle, pero los que nos iniciamos mucho antes, dejamos la profesión unos años y retomamos en estos tiempos, hay cosas que cuestan un poco, no tenemos el concepto, nacimos con el for to do, while do, repeat until y de ser necesario, punteros, y con eso se hacía (y hace) de todo.

Las cosas cambian, los lenguajes evolucionan o mueren, aunque no siempre incorporar nuevas sentencias o lo que sea, signifique evolución, pero es preferible eso al estancamiento. Y la verdad que tanto Free Pascal y Delphi (ambos Object Pascal) conservan la belleza del lenguaje, esa sintaxis única.

Creo que lo mejor es empezar por responder ¿qué lo diferencia del for to do?:

En el for to se usa un índice, generalmente "i", entero, para recorrer los elemento de un vector (array) y acceder a ellos utilizando el valor de i, es decir obtenemos un valor de unarray[i]. En cambio en el for in para hacer lo mismo, usando una variable i y un array con índices enteros, la variable i va tomando los valores del array, los valores se obtienen de i. no de unarray[i].

Otra diferencia es que mediante el empleo de un for to se puede recorrer solo una parte, por ejemplo un array de 500 elementos con un for i:=1 to 10 do... solo accedemos a los 10 primeros, en cambio con el uso de for i in ... se recorre todo.

La variable de control debe ser del mismo tipo que los elementos del conjunto a recorrer.

El conjunto a iterar debe ser de un número fijo de elementos.

La variable es una copia temporal del elemento del bucle.

Ejemplos:

program pruebaforin;
{$mode objfpc}{$H+}
uses Classes;

type
  TSemana=(domingo, lunes, martes, miercoles, jueves, viernes, sabado);


var
  entero:Integer;
  arrEntero:array[1..12] of Integer=(1,2,4,8,5,6,7,8,9,27,11,12);
  cadena:String;
  arrCadena:array[1..5] of String =('Lunes','Martes','Miércoles','Jueves','Viernes');
  dia:TSemana;
  diaslaborables:set of TSemana =[lunes, martes, miercoles, jueves, viernes];
  caracter:Char;
  meses:TStringList;

begin
  WriteLn('Vector de eneteros');
  WriteLn('entero:Integer;');
  WriteLn('arrarrEntero:array[1..12] of Integer=(1,2,4,8,5,6,7,8,9,27,11,12);');
  WriteLn('for entero in arrEntero do WriteLn(''entero =  '',entero,''  arrEneter['',entero,'']='',arrEntero[entero]);');
  for entero in arrEntero do WriteLn('entero =  ',entero,'  arrEneter[',entero,']=',arrEntero[entero]);
  ReadLn;
  WriteLn('Vector de cadena de caracteres.');
  WriteLn('cadena:String;');
  WriteLn('arrCadena:array[1..5] of String =(''Lunes'',''Martes'',''Miércoles'',''Jueves'',''Viernes'');');
  WriteLn('for cadena in arrCadena do WriteLn(''Cadena = '',cadena);');
  for cadena in arrCadena do WriteLn('Cadena = ',cadena);
  ReadLn;
  WriteLn('Enumerados.');
  WriteLn('TSemana=(domingo, lunes, martes, miercoles, jueves, viernes, sabado); ');
  WriteLn('dia:TSemana;');
  WriteLn('for dia in Tsemana do WriteLn(''dia = '',dia);');
  for dia in Tsemana do WriteLn('dia = ',dia);
  ReadLn;
  WriteLn('Conjuntos.');
  WriteLn('TSemana=(domingo, lunes, martes, miercoles, jueves, viernes, sabado); ');
  WriteLn('diaslaborables:set of TSemana =[lunes, martes, miercoles, jueves, viernes];');
  WriteLn('dia:TSemana;');
  WriteLn('for dia in diaslaborables do WriteLn(''dia = '',dia);');
  for dia in diaslaborables do WriteLn('dia = ',dia);
  ReadLn;
  WriteLn('Caracteres.');
  WriteLn('caracter:Char;');
  WriteLn('for caracter in ''abcdefg'' do WriteLn(''caracter = '',caracter);');
  for caracter in 'abcdefg' do WriteLn('caracter = ',caracter);
  ReadLn;
  WriteLn('Classes.');
  WriteLn('cadena:String;');
  WriteLn('meses:TStringList;');
  WriteLn('for cadena in meses do WriteLn(''cadena = '',cadena);');
  meses:=TStringList.Create;
  meses.Add('Enero');
  meses.Add('Febrero');
  meses.Add('Marzo');
  meses.Add('Abril');
  meses.Add('Mayo');
  for cadena in meses do WriteLn('cadena = ',cadena);
  meses.Free;
  ReadLn;
end.      

Resultado del programa (salida por consola):

Vector de eneteros
entero:Integer;
arrarrEntero:array[1..12] of Integer=(1,2,4,8,5,6,7,8,9,27,11,12);
for entero in arrEntero do WriteLn('entero =  ',entero,'  arrEneter[',entero,']=',arrEntero[entero]);
entero =  1  arrEneter[1]=1
entero =  2  arrEneter[2]=2
entero =  4  arrEneter[4]=8
entero =  8  arrEneter[8]=8
entero =  5  arrEneter[5]=5
entero =  6  arrEneter[6]=6
entero =  7  arrEneter[7]=7
entero =  8  arrEneter[8]=8
entero =  9  arrEneter[9]=9
entero =  27  arrEneter[27]=0
entero =  11  arrEneter[11]=11
entero =  12  arrEneter[12]=12

Vector de cadena de caracteres.
cadena:String;
arrCadena:array[1..5] of String =('Lunes','Martes','Miércoles','Jueves','Viernes');
for cadena in arrCadena do WriteLn('Cadena = ',cadena);
Cadena = Lunes
Cadena = Martes
Cadena = Miércoles
Cadena = Jueves
Cadena = Viernes

Enumerados.
TSemana=(domingo, lunes, martes, miercoles, jueves, viernes, sabado);
dia:TSemana;
for dia in Tsemana do WriteLn('dia = ',dia);
dia = domingo
dia = lunes
dia = martes
dia = miercoles
dia = jueves
dia = viernes
dia = sabado

Conjuntos.
TSemana=(domingo, lunes, martes, miercoles, jueves, viernes, sabado);
diaslaborables:set of TSemana =[lunes, martes, miercoles, jueves, viernes];
dia:TSemana;
for dia in diaslaborables do WriteLn('dia = ',dia);
dia = lunes
dia = martes
dia = miercoles
dia = jueves
dia = viernes

Caracteres.
caracter:Char;
for caracter in 'abcdefg' do WriteLn('caracter = ',caracter);
caracter = a
caracter = b
caracter = c
caracter = d
caracter = e
caracter = f
caracter = g

Classes.
cadena:String;
meses:TStringList;
for cadena in meses do WriteLn('cadena = ',cadena);
cadena = Enero
cadena = Febrero
cadena = Marzo
cadena = Abril
cadena = Mayo

Para ejemplos más avanzados y documentación oficial:

Documentación: https://www.freepascal.org/docs-html/ref/refsu59.html

Wiki (Siempre y cuando algún iluminado no haya eliminado o movido la página): https://wiki.lazarus.freepascal.org/for-in_loop

Código fuente del ejemplo.

No hay comentarios:

Publicar un comentario