24 - Procedimientos: parámetros de tipo vector y matriz

Vimos en conceptos anteriores la sintaxis para plantear procedimientos en Delphi/Pascal y la forma de que lleguen y salgan datos mediante parámetros.

Los parámetros de un procedimiento pueden ser de tipo de dato primitivo: Integer, Double, String etc o inclusive estructuras de datos: Vectores, Matrices etc.

Los parámetros de tipo Vector o Matriz pueden ser tanto por valor como por referencia.

Problema 1

Cargar un vector con 5 elementos de tipo Integer y posteriormente imprimir su contenido. Implementar dos procedimientos uno de carga y otro de impresión.

Proyecto96

program Proyecto96;

{$APPTYPE CONSOLE}

type
  TVector = array[1..5] of Integer;

procedure Cargar(var Vec: TVector);
var
  f: Integer;
begin
  for f:=1 to 5 do
  begin
    Write('Ingrese elemento:');
    ReadLn(Vec[f]);
  end;
end;

procedure Imprimir(Vec: TVector);
var
  f: Integer;
begin
  WriteLn('Listado completo del vector');
  for f:=1 to 5 do
  begin
    Write(Vec[f], ' ');
  end;
end;


var
  Vector: TVector;

begin
  Cargar(Vector);
  Imprimir(Vector);
  ReadLn;
end.

Este problema lo vimos anteriormente codificando todo el algoritmo en el bloque principal del programa. Ahora podemos ver como se codifica empleando programación estructurada.

El bloque principal de nuestro programa ahora queda reducido a la llamada a los procedimientos:

var
  Vector: TVector;

begin
  Cargar(Vector);
  Imprimir(Vector);
  ReadLn;
end.

La variable Vector se la pasamos en forma sucesiva primero al procedimiento Cargar y luego al procedimiento Imprimir.

El procedimiento Cargar recibe como parámetro por referencia el Vector y procede a su carga (al cargar el parámetro Vec se está cargando la variable global Vector):

procedure Cargar(var Vec: TVector);
var
  f: Integer;
begin
  for f:=1 to 5 do
  begin
    Write('Ingrese elemento:');
    ReadLn(Vec[f]);
  end;
end;

Es importante notar que la sección de la type se hace previo a los procedimientos, esto debido a que el parámetro Vec es de tipo TVector:

type
  TVector = array[1..5] of Integer;

El segundo procedimiento recibe un parámetro por valor ya que no debe modificar el vector:

procedure Imprimir(Vec: TVector);
var
  f: Integer;
begin
  WriteLn('Listado completo del vector');
  for f:=1 to 5 do
  begin
    Write(Vec[f], ' ');
  end;
end;

Problema 2

Definir 2 vectores de 7 componentes de tipo Integer. Implementar un procedimiento para realizar la carga de un vector y otro procedimiento que imprima la suma de sus 7 elementos.

Proyecto97

program Proyecto97;

{$APPTYPE CONSOLE}

type
  TVector = array[1..7] of Integer;

procedure Cargar(var Vec: TVector);
var
  f: Integer;
begin
  for f:=1 to 7 do
  begin
    Write('Ingrese elemento:');
    ReadLn(Vec[f]);
  end;
end;

procedure SumarElementos(Vec: TVector);
var
  f: Integer;
  suma: Integer;
begin
  suma := 0;
  for f:=1 to 7 do
  begin
    suma := suma + Vec[f];
  end;
  WriteLn('La suma de todos sus componentes es:', suma);
end;


var
  Vector1: TVector;
  Vector2: TVector;

begin
  Cargar(Vector1);
  SumarElementos(Vector1);
  Cargar(Vector2);
  SumarElementos(Vector2);
  ReadLn;
end.

Este problema nos presenta la ventaja de definir un procedimiento que realiza la carga de vectores de tipo Integer de 7 elementos, como vemos podemos utilizarlo para cargar diferentes vectores:

var
  Vector1: TVector;
  Vector2: Tvector;

begin
  Cargar(Vector1);
  SumarElementos(Vector1);
  Cargar(Vector2);
  SumarElementos(Vector2);
  ReadLn;
end.

El procedimiento Cargar lo utilizamos tanto para cargar el Vector1 como el Vector2. De forma similar reutilizamos el procedimiento SumarElementos tanto para el Vector1 como el Vector2.

Problema 3

Crear y cargar una matriz de 4 filas por 4 columnas. Imprimir la diagonal principal.
Definir dos procedimientos para implementar el algoritmo.

              x    -    -    -
              -    x    -    -
              -    -    x    -
              -    -    -    x

Proyecto98

program Proyecto98;

{$APPTYPE CONSOLE}

type
  TMatriz = array[1..4,1..4] of Integer;

procedure Cargar(var Matriz: TMatriz);
var
  f, c: Integer;
begin
  for f:= 1 to 4 do
  begin
    for c:=1 to 4 do
    begin
      Write('Ingrese elemento de la matriz de la fila ', f, ' y la columna ', c, ':');
      ReadLn(Matriz[f,c]);
    end;
  end;
end;

procedure Imprimir(Matriz: TMatriz);
var
  k: Integer;
begin
  WriteLn('Elementos de la diagonal principal');
  for k:=1 to 4 do
  begin
    Write(Matriz[k,k], '-');
  end;
end;


var
  Matriz: TMatriz;

begin
  Cargar(Matriz);
  Imprimir(Matriz);
  ReadLn;
end.

Como podemos analizar la sintaxis de los parámetros es similar a trabajar con vectores, debemos indicar si el parámetro es por referencia agregando la palabra clave var:

procedure Cargar(var Matriz: TMatriz);
O si es por valor:

procedure Imprimir(Matriz: TMatriz);

Problema 4

Una empresa de viajes registra la siguiente información de las excursiones que organiza:

 				
Nombre del Cliente	1ra Cuota	2da Cuota	3ra Cuota

Rodríguez Pablo		200		200		200	
Lopez Daniel		500		0		0
Marcos Esteban		350		300		0

Desarrollar un programa que permita:

- Cargar los nombres de los clientes y el importe de cada cuota.
Los nombres de los clientes y las cuotas a pagar se ingresan por teclado.
- Generar un vector con el costo total del viaje para cada cliente (Imprimir el nombre y el costo del viaje de ese cliente).
- Imprimir la cantidad de clientes que abonan el viaje al contado (Tener en cuenta que un cliente paga al contado si la segunda y tercer cuota son iguales a cero).
- Importe total recaudado por la empresa en concepto de cuotas.

Proyecto99

program Proyecto99;

{$APPTYPE CONSOLE}

type
  TClientes = array[1..3] of String;
  TCuotas = array[1..3,1..3] of Double;
  TTotal = array[1..3] of Double;

procedure Cargar(Var Clientes: TClientes; var Cuotas: TCuotas);
var
  f, c: Integer;
begin
  for f:=1 to 3 do
  begin
    Write('Ingrese el nombre del cliente:');
    ReadLn(Clientes[f]);
    for c:=1 to 3 do
    begin
      Write('Ingrese cuota número ', c, ':');
      ReadLn(Cuotas[f,c]);
    end;
  end;
end;

procedure CalcularTotal(Cuotas: TCuotas; var Total: TTotal);
var
  f, c: Integer;
  suma: Double;
begin
  for f:=1 to 3 do
  begin
    suma := 0;
    for c:=1 to 3 do
    begin
      suma := suma + Cuotas[f,c];
    end;
    Total[f] := suma;
  end;
end;

procedure ListadoTotales(Clientes: TClientes; Total: TTotal);
var
  f: Integer;
begin
  WriteLn('Listado de Cliente y el costo total');
  for f:=1 to 3 do
  begin
    WriteLn(Clientes[f],' ',Total[f]:0:2);
  end;
end;

procedure PagoContado(Cuotas: TCuotas);
var
  f: Integer;
  cant: Integer;
begin
  cant := 0;
  for f:=1 to 3 do
  begin
    if (Cuotas[f,2] = 0) and (Cuotas[f,3] = 0) then
    begin
      cant := cant + 1;
    end;
  end;
  WriteLn('La cantidad de clientes que pagaron al contado es:', cant);
end;

procedure RecaudacionEmpresa(Total: TTotal);
var
  f: Integer;
  suma: Double;
begin
  suma := 0;
  for f:=1 to 3 do
  begin
    suma := suma + Total[f];
  end;
  WriteLn('Total recaudado:', suma:0:2);
end;

var
  Clientes: TClientes;
  Cuotas: Tcuotas;
  Total: TTotal;

begin
  Cargar(Clientes, Cuotas);
  CalcularTotal(Cuotas, Total);
  ListadoTotales(Clientes, Total);
  PagoContado(Cuotas);
  RecaudacionEmpresa(Total);
  ReadLn;
end.

El resultado de ejecutar la aplicación será similar a esta:

parametros de tipo vector y matriz

Cuando resolvemos con procedimientos un algoritmo el bloque principal requiere que llamamos a cada uno de los procedimientos que resuelven una parte del mismo:

var
  Clientes: TClientes;
  Cuotas: Tcuotas;
  Total: TTotal;

begin
  Cargar(Clientes, Cuotas);
  CalcularTotal(Cuotas, Total);
  ListadoTotales(Clientes, Total);
  PagoContado(Cuotas);
  RecaudacionEmpresa(Total);
  ReadLn;
end.

Es importante concentrarse en cada procedimiento y pensar que datos deben llegar, que datos debe devolver y el algoritmo en si mismo.
En la carga debemos hacer que llegue el vector de los clientes y la matriz donde almacenar las cuotas (los dos por referencia ya que se carga su contenido):

procedure Cargar(Var Clientes: TClientes; var Cuotas: TCuotas);
var
  f, c: Integer;
begin
  for f:=1 to 3 do
  begin
    Write('Ingrese el nombre del cliente:');
    ReadLn(Clientes[f]);
    for c:=1 to 3 do
    begin
      Write('Ingrese cuota número ', c, ':');
      ReadLn(Cuotas[f,c]);
    end;
  end;
end;

Problema propuesto

  • Desarrollar un programa que permita ingresar un vector de 8 elementos de tipo Integer, e implemente los siguientes procedimientos:
    La carga del vector.
    El valor acumulado de todos los elementos del vector.
    El valor acumulado de los elementos del vector que sean mayores a 36.
    Cantidad de valores mayores a 50.
Solución
program Proyecto100;

{$APPTYPE CONSOLE}

type
  TVector = array[1..8] of Integer;

procedure Cargar(var Vector: TVector);
var
  f: Integer;
begin
  for f:=1 to 8 do
  begin
    Write('Ingrese elemento:');
    ReadLn(Vector[f]);
  end;
end;

procedure SumaTotal(Vector: TVector);
var
  f: Integer;
  suma: Integer;
begin
  suma := 0;
  for f:=1 to 8 do
  begin
    suma := suma + Vector[f];
  end;
  WriteLn('La suma de los 8 elementos es:', suma);
end;

procedure SumaMayor16(Vector: TVector);
var
  f: Integer;
  suma: Integer;
begin
  suma := 0;
  for f:=1 to 8 do
  begin
    if Vector[f] > 36 then
    begin
      suma := suma + Vector[f];
    end;
  end;
  WriteLn('La suma de valores mayores a 36 es:', suma);
end;

procedure CantidadMayores50(Vector: TVector);
var
  f: Integer;
  cant: Integer;
begin
  cant := 0;
  for f:=1 to 8 do
  begin
    if Vector[f] > 50 then
    begin
      cant := cant + 1;
    end;
  end;
  WriteLn('La cantidad de valores mayores a 50 es:', cant);
end;

var
  Vector: TVector;

begin
  Cargar(Vector);
  SumaTotal(Vector);
  SumaMayor16(Vector);
  CantidadMayores50(Vector);
  ReadLn;
end.