[ Foro de Pascal ]

Procedimiento para dar de baja en Pascal

23-May-2011 13:01
Manuel Molina
3 Respuestas

Con este procedimiento pretendo dar de baja. En principio busca y encuentra el codigo que pretendo cambiar y le digo ' si lo encuentras biblioteca[i].alta:=false ' pues nada que no lo da de baja sabeis que código me falta para conseguir tal fin?

un saludo nacho y muchas gracias por tu ayuda.




(* -- CON ESTE PROCEDIMIENTO PRETENDO BUSCAR Y MODIFICAR SU ESTADO DE ALTA a BAJA --*)
PROCEDURE baja(biblioteca: Tbiblioteca; longitud: integer; buscado: integer);

var

      i  : integer;
encontrado: Boolean;

begin
(* Variable encontrado siempre a false *)
encontrado:= false;

for i:= 1 to longitud do

begin

if biblioteca[i].codigo = buscado then begin (*Si el codigo de la biblioteca es igual al introducido se llama al procedimiento imprime_libro*)
imprime_libro(biblioteca[i]);
end;
if encontrado = true then begin;    
biblioteca[i].alta:=false;
end;

end;

begin

if encontrado = false then begin (* Si  la busqueda anterior no se produce no lee la siguiente línea*)
writeln('Libro no encontrado');
end;

end;


end;


24-May-2011 00:03
Antonio P.G.

Hola, Manuel.

El código que muestras, resumido y corregido en algunos aspectos (sobraban "begin" y "end") es el siguiente:

--------------------------------------------------------------

(* -- CON ESTE PROCEDIMIENTO PRETENDO BUSCAR Y MODIFICAR SU ESTADO DE ALTA a BAJA --*)
PROCEDURE baja(biblioteca: Tbiblioteca; longitud: integer; buscado: integer);
  var
    i          : integer;
    encontrado : Boolean;
  begin
    encontrado:= false;  (* Variable encontrado siempre a false *)
    for i:= 1 to longitud do begin
        if biblioteca[i].codigo = buscado then (*Si el codigo de la biblioteca es igual al introducido se llama *)
                                               (* al procedimiento imprime_libro.                               *)
          imprime_libro(biblioteca[i]);
        if encontrado = true then
          biblioteca[i].alta:=false;
    end;
    if encontrado = false then (* Si  la búsqueda anterior no se produce, no lee la siguiente línea*)
      writeln('Libro no encontrado');
  end;
--------------------------------------------------------------

Dos apuntes:
- Si se busca algo, se busca hasta encontrarse, por tanto no necesitarías aplicar un bucle de recorrido COMPLETO (for), sino un bucle condicional ("busco hasta que lo encuentro o hasta que se me acaba la lista"). De este tipo hay dos bucles: "while" y "repeat...until". Como al menos debe ejecutarse la acción de buscar una vez, entonces se utilizaría "repeat...until".

- Lo segundo va con tu pregunta. Si te fijas, dices "cuando 'encontrado' sea true, entonces lo doy de baja", pero no estás modificando el valor de "encontrado" en ningún momento. Deberías de decir en algún momento algo como "si es éste el libro que busco, 'encontrado' es verdadero.

- Por último decirte que puedes omitir la variable "encontrado", y emplear la condición "biblioteca[i].codigo = buscado" a lo largo del procedimiento, si lo prefieres.

¡Un saludo!


24-May-2011 05:55
Nacho Cabanes (+84)

Efectivamente, Manuel, como te dice Antonio, tu procedimiento de baja "básicamente funciona", pero el aviso que da al final es incorrecto, porque no actualizas la variable "encontrado", de modo que siempre crees que no has encontrado nada.

Algún comentario "estilístico":

Los comentarios superfluos... sobran. Un comentario debería aclarar lo que no es evidente. Me refiero a que sobran cosas como éstas:

encontrado:= false;  (* Variable encontrado siempre a false *)

       if biblioteca[i].codigo = buscado then (*Si el codigo de la biblioteca es igual al introducido se llama *)
                                               (* al procedimiento imprime_libro.                              *)
         imprime_libro(biblioteca[i]);


Lo razonable es comentar la lógica del programa y los fragmentos que (tras mucho intentarlo) no consigas que sean legibles por sí mismos (cosa que no debería ocurrir).


Otra cosa: la forma "natural" de usar los "boolean" no es comparar con true o false, sino hacer que el programa sea más legible:

       if encontrado then
         biblioteca[i].alta:=false;

o bien

   if not encontrado then
     writeln('Libro no encontrado');


Por eso, quizá esa función se debiera escribir como:


--------------------------------------------------------------

(*
Baja: da de baja un libro (cambiando su campo "alta" a "false")
Parámetros:
- Biblioteca en la que se busca
- Longitud (número de registros) de la biblioteca
- Código del registro buscado
*)
PROCEDURE baja(biblioteca: Tbiblioteca; longitud: integer; codigoBuscado: integer);
 var
   i          : integer;
   encontrado : Boolean;
 begin
   encontrado := false;
   for i := 1 to longitud do
       if biblioteca[i].codigo = codigoBuscado then
         begin
         imprime_libro(biblioteca[i]);
         encontrado := true
         biblioteca[i].alta := false;
         end;

   if not encontrado then
     writeln('Libro no encontrado');
 end;
--------------------------------------------------------------

Como te comentaba Antonio, se puede mejorar aun más si interrumpes la búsqueda en cuanto encuentres el libro que buscabas (para lo que tendrás que usar un "while" o un "repeat" en vez de un "for"), porque se supone que no existirán dos libros con el mismo código.


24-May-2011 20:11
Antonio P.G.

¡Ah!

Y además debes poner "var" en la cabecera, justo antes del parámetro "biblioteca", ya que lo estás modificando dentro del procedimiento, y quieres que esos cambios permanezcan tras la ejecución del procedimiento. Es decir, has de pasarlo "por variable", y no "por valor".

Un saludo.






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)