sábado, 6 de noviembre de 2021

Arreglos y parámetros por referencia en pseudocódigo con PSeInt

 https://terepebernal.com/blog/pseudocodigo/arreglos-y-parametros-por-referencia/


Arreglos y parámetros por referencia en pseudocódigo con PSeInt


Revisando el pseudocódigo del algoritmo calendario, pensé en almacenar los datos utilizando arreglos, para que así me fuera más fácil manejarlos. Pero encontré algunos problemillas, quise devolver un arreglo en una función y no funcionó lo que quería hacer, así que buscando una solución descubrí algo que desconocía, que se pueden utilizar parámetros por referencia en PSeInt, y así fue como conseguí resolverlo. Utilicé un arreglo de tres dimensiones y pasándolo por referencia pude almancenar un año, y todo fue más fácil a la hora de manejar los datos y mostrarlos pantalla.


En los apartados que siguen muestro varios ejemplos sobre arreglos pasados como parámetros por referencia y parámteros por valor. He utilizado el paso por referencia para cambiar el contenido del arreglo, y para leerlo he utilizado el paso por valor.

Ilustración arreglo tridimensional representando año

Parámetros por valor y parámetros por referencia

Al pasar parámetros a las funciones podemos hacerlo de dos formas, por valor y por referencia. La forma de hacerlo en PSeInt es colocando junto al parámetro las palabras Por Valor o Por Referencia, en el momento de declarar la función. Si no se escribe nada, por defecto se asigna Por Valor.

Valor:

La función recibe una copia del valor de la variable, dentro de la función dicha variable se puede utilizar para operar o lo que haga falta, pero su valor no se modificará, al salir del ámbito de la función tendrá el mismo valor que antes de entrar en ella.

Funcion porValor(a Por Valor)
   // Se le cambia el valor a la variable
   a = 1000;

   Escribir "DENTRO DE porValor SE CAMBIA A: " + ConvertirATexto(a);
   Escribir " ";
FinFuncion

Referencia:

La función recibe la posición de memoria en la cual se guarda el valor de la variable, y si se cambia su valor dentro de la función el cambio permanece, dentro y fuera del ámbito de la función.

Funcion porReferencia(b Por Referencia)
   // Se le cambia el valor a la variable
   b = 500;

   Escribir "DENTRO DE porReferencia SE CAMBIA A:  " + ConvertirATexto(b);
   Escribir " ";
FinFuncion

Ejemplo en PSeInt

// Se pide un número por teclado y después, 
// muestra su valor dentro y fuera de las funciones 
// mostrando que, al pasarlo por valor sólo se modifica dentro de la función 
// y, al pasarlo por referencia el cambio que se realiza dentro de la función se mantiene. 
Algoritmo argumentos
   Definir num Como Entero;

   // Se pide un número por teclado
   Escribir "Introduce un número: " Sin Saltar;
   Leer num;
   Escribir " ";

// Se muestra por pantalla el número introducido
   Escribir "VALOR INTRODUCIDO POR TECLADO: " + ConvertirATexto(num);
   Escribir " ";

   // Se pasa como argumento por valor a una función y se muestra el resultado
   porValor(num);
   Escribir "DESPUÉS DE porValor: " + ConvertirATexto(num);
   Escribir " ";

   // Se pasa como argumento por referencia a una función y se muestra el resultado
   porReferencia(num);
   Escribir "DESPUÉS DE porReferencia: " + ConvertirATexto(num);
   Escribir " ";
FinAlgoritmo

Puedes ver el resultado del ejemplo en la siguiente imagen:

Resultado ejemplo argumentos valor y referencia

 

Declarar e inicializar un arreglo de dos o más dimensiones

En PSeInt para declarar un arreglo o array, hay que declarar, primero su tipo de datos y después sus dimensiones. En el siguiente ejemplo, se declaran dos arreglos para guardar los días de un año, uno de dos dimensiones (semanas, días) y otro de tres dimensiones (meses, semanas, días).

// Se declaran dos arreglos:
// uno de 2 dimensiones, para guardar los días de un mes
// y otro de 3 dimensiones, para guardar todo el año.

Definir monthArray, yearArray Como Entero;
Dimension monthArray(6,7);
Dimension yearArray(12,6,7);

Cada vez que utilicemos los arrays para guardar datos, primero los inicializamos poniendo todos sus valores a cero, para así evitar que se queden restos de otros usos. En el siguiente ejemplo, se muestran las llamadas y declaraciones de dos funciones para inicializar cada uno de los arreglos.

// Llamadas a las funciones
inicializarMA(monthArray);          // Inicializar a 0 el mes
inicializarYA(yearArray);           // Inicializar a 0 el año

Funcion inicializarMA(monthArray Por Referencia)
   // Los enteros i, j se utilizaran de contadores para moverse por los arreglos.
   Definir i, j Como Entero;

   Para i=1 Hasta 6 Con Paso 1 Hacer
      Para j=1 Hasta 7 Con Paso 1 Hacer
         monthArray(i,j)=0;
      FinPara
   FinPara
FinFuncion

Funcion inicializarYA(yearArray Por Referencia)
   // Los enteros k, i, j se utilizaran de contadores.
   Definir k, i, j Como Entero;

   Para k=1 Hasta 12 Con Paso 1 Hacer
      Para i=1 Hasta 6 Con Paso 1 Hacer
         Para j=1 Hasta 7 Con Paso 1 Hacer
            yearArray(k,i,j)=0;
         FinPara
      FinPara
   FinPara
FinFuncion

Mostrar por pantalla arreglos de dos o tres dimensiones

Tras guardar los datos en arreglos es más fácil manejarlos para mostrarlos por pantalla. En el siguiente ejemplo se muestra las llamadas y declaraciones de las funciones para mostrar por pantalla los dos arreglos inicializados en el apartado anterior.

// Llamadas a las funciones
Escribir "ARREGLO DEL MES:";
mostrarMA(monthArray);          // Muestra por pantalla el mes
Escribir "";

Escribir "ARREGLO DEL AÑO:";
mostrarYA(yearArray);           // Muestra por pantalla el año


Funcion mostrarMA(monthArray)
   // Los enteros i, j se utilizaran de contadores para moverse por los arreglos.
   Definir i, j Como Entero;

   Para i=1 Hasta 6 Con Paso 1 Hacer
      Para j=1 Hasta 7 Con Paso 1 Hacer
         Escribir ConvertirATexto(monthArray(i,j)) + "  " Sin Saltar;
      FinPara
      Escribir "";          // Salto de línea al terminar la semana
   FinPara
FinFuncion

Funcion mostrarYA(yearArray)
   // Los enteros k, i, j se utilizaran de contadores.
   Definir k, i, j Como Entero;

   Para k=1 Hasta 12 Con Paso 1 Hacer
      Escribir "MES NÚMERO: " + ConvertirATexto(k);
      Para i=1 Hasta 6 Con Paso 1 Hacer
         Para j=1 Hasta 7 Con Paso 1 Hacer
            Escribir ConvertirATexto(yearArray(k,i,j)) + "  " Sin Saltar;
         FinPara
         Escribir "";          // Salto de línea al terminar la semana
      FinPara
      Escribir "";          // Salto de línea al terminar el mes
   FinPara
FinFuncion

El resultado del ejemplo para los arreglos inicializados del apartado anterior se muestra en la siguiente imagen:

Resultado inicializar arreglos

 

Almacenar un mes en un arreglo de dos dimensiones

Si quiero guardar un mes en el arreglo de dos dimensiones, ¿qué necesito saber?. Necesito saber en que posición empezar a ingresar los días (día de la semana en el que empieza el mes) y cuando terminar (último día del mes). Ya tengo funciones hechas para poder realizarlo, para lo primero firstDayMonth(year, month) y para lo segundo lastDayMonth(year, month).

Para el ejemplo voy a usar diciembre de 2019, que empieza en domingo y tiene 31 días, para poder almacenarlo necesita las seis filas del arreglo.

saveMonth(2019, 12, monthArray);          // Llamada para diciembre de 2019
Escribir "DICIEMBRE - 2019:";
mostrarMA(monthArray);        // Mostrar por pantalla tras guardar el mes en el arreglo

// Almacena un mes en un arreglo de dos dimensiones
// incluye llamadas a las funciones firstDayMonth y lastDayMonth
Funcion saveMonth(year, month, mArray Por Referencia)
   Definir  fDM, lDM, day, i , j  Como Entero ;

   fDM = firstDayMonth(year, month);          // Primer día del mes
   lDM = lastDayMonth(year, month);           // Último día del mes

   day = 1;                     // Variable para ir almacenando el número del día
   i = 1;                         // Contador para las semanas
   Mientras (i<=6) Hacer
      j = 1;                         // Contador para los días de la semana
      Mientras ((j<=7) Y (day<=lDM)) Hacer           // Hacer hasta el último día del mes
         Si ((fDM>j) Y (day==1)) Entonces           // Si el primer día no es lunes
	   mArray(i,j)=0;           // Espacio vacío
           j=j+1;
         SiNo
            mArray(i,j)=day;                   // Escribir número de día
            day=day+1;           // Sumar un día
            j=j+1;
         FinSi
      FinMientras
      i=i+1;
   FinMientras
FinFuncion

El resultado del ejemplo anterior se muestra en la imagen siguiente. Los días no se muestran bien alineados, pero como puedes ver cada día está en su lugar.

Resultado almacenar días mes en arreglo

 

Almacenar un año en un arreglo de tres dimensiones

// Llamada a la función para el año 2019
saveYear(2019, yearArray);
Escribir "ARREGLO DEL AÑO: ";
mostrarYA(yearArray);          // Mostrar por pantalla tras guardar el año en el arreglo


// Almacena un año en un arreglo de tres dimensiones
Funcion saveYear(year, yArray Por Referencia)
   Definir k, i, j mArray Como Entero;
   Dimension mArray(6,7);

   Para k=1 Hasta 12 Con Paso 1 Hacer
      inicializarMA(mArray);          // Inicializar el arreglo para guardar el mes
      saveMonth(year,k,mArray);             // Guardar el mes k en mArray
      Para i=1 Hasta 6 Con Paso 1 Hacer
         Para j=1 Hasta 7 Con Paso 1 Hacer
            yArray(k,i,j)=mArray(i,j);         // Guardar el mes k en yArray
         FinPara
      FinPara
   FinPara
FinFuncion

El resultado del ejemplo anterior se muestra en la imagen siguiente. Igual que antes, los días no se muestran bien alineados, pero están en el lugar que corresponde.

Resultado almacenar año en un arreglo

Aunque no lo muestro aquí, he creado funciones para mostrar todo el calendario, con los datos bien alineados y dispuestos en 4 filas x 3 meses. En la siguiente imagen se muestra como queda el primer trimestre.

Resultado pintar primer trimestre año

Puedes ver más sobre ejercicios básicos de Pseudocódigo y PSeInt en:

No hay comentarios:

Publicar un comentario