Os subprogramas, denominados funções ou procedimentos na programação estruturada, são trechos de códigos que realizam alguma tarefa específica e podem como resultado retornar um valor.

Parâmetros são canais pelos quais se estabelece uma comunicação entre um subprograma e o seu módulo chamador. Dados são passados pelo módulo chamador ao subprograma chamado por meio de parâmetros.

Tecnicamente os parâmetros são classificados como parâmetros formais e parâmetros reais. Os parâmetros formais são os nomes simbólicos introduzidos nos "cabeçalhos" dos subprogramas. Já os parâmetros reais, ou parâmetros efetivos (ou ainda, argumentos) são aqueles que se associam aos parâmetros formais quando da chamada, ou invocação, de um subprograma.

Em síntese, os argumentos são variáveis especificadas entre parênteses na chamada de um subprograma; e os parâmetros são variáveis declaradas no cabeçalho do subprograma para indicar os valores que o subprograma deve receber quando for chamado.

Open Array

Os parâmetros "open array" são um recurso interessante disponibilizado no Delphi que permite ao programador implementar subprogramas (procedure ou function) que recebem uma quantidade "não" especificada de argumentos (que inclusive podem ser de tipos diferentes). Este recurso é muitas vezes definido como listas de argumentos de comprimento variável.

Veja o código para declarar uma função que aceita um "open array" de inteiros:
function somarValores(param: array of integer): integer;

Para obter as informações sobre o array tem-se:

  1. Low(param): retorna o limite inferior do array (posição do primeiro elemento);
  2. High(param): retorna o limite superior do array (posição do último elemento);
  3. Length(param): retorna o número de elementos do array;
  4. param[i]: faz referência ao i-ésimo elemento do array.

Array of Const

Os parâmetros "array of const" representam um caso especial de "open array" quem permitem que os argumentos utilizados na lista possam ser de tipos diferentes.

Veja a declaração do cabeçalho da função Format no Delphi:

function Format(const Formatting: string; const Data: array of const): string;

Exemplificando a função "Format" com dois especificadores de formato diferentes, moeda (%m) e decimal (%d):

ShowMessage(Format('Salário Mínimo = %m em %d.', [622.00, 2012]));

Neste exemplo a lista de argumentos, que sintaticamente deve ser colocada entre colchetes ([]), é composta na ordem: a) 622.00 que corresponde ao valor do salário mínimo; e, b) 2012 que indica o ano de vigência do salário mínimo.

A Listagem 1 apresenta uma função que aceita uma lista de argumentos de comprimento variável através de um "array of const" percorrendo o array e verificando o tipo dos seus elementos.

function tiposDosArgumentos(param: array of const): string;
var i: Integer;
    TypeStr: String;
begin
  for i:=Low(param) to High(param) do
  begin
    case param[i].VType of
        vtInteger: TypeStr := 'Inteiro';
        vtBoolean: TypeStr := 'Booleano';
           vtChar: TypeStr := 'Char';
       vtExtended: TypeStr := 'Extended';
         vtString: TypeStr := 'String';
        vtPointer: TypeStr := 'Pointer';
          vtPChar: TypeStr := 'PChar';
         vtObject: TypeStr := 'Object';
          vtClass: TypeStr := 'Class';
       vtWideChar: TypeStr := 'WideChar';
      vtPWideChar: TypeStr := 'PWideChar';
     vtAnsiString: TypeStr := 'AnsiString';
       vtCurrency: TypeStr := 'Currency';
        vtVariant: TypeStr := 'Variant';
      vtInterface: TypeStr := 'Interface';
     vtWideString: TypeStr := 'WideString';
          vtInt64: TypeStr := 'Int64';
    end;
    result := result + ' ' +
      Format('%do. argumento é do tipo %s', [(i+1), TypeStr]) + #13;
  end;
end;
Listagem 1. Identificando os tipos dos argumentos (parâmetros) da lista

Para testar a função tiposDosArgumentos, com o resultado apresentado na Figura 1, foi implementada a seguinte instrução:

ShowMessage(tiposDosArgumentos(['Omero', 90, FloatToCurr(4.55), @tiposDosParametros, 3.14159, True, 'M']));
Executando a função
Figura 1. Executando a função "tiposDosArgumentos" na identificação dos tipos dos argumentos

A Listagem 2 apresenta o código completo da unit do formulário principal de uma aplicação Delphi que demonstra a implementação de funções que recebem listas de argumentos (parâmetros) de comprimento variável.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    BitBtn1: TBitBtn;
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function mostrarValores(param: array of const): String;
var i: integer;
    s: String;
begin
  // 1o. argumento enviado identifica a chamada
  s := param[0].VPChar;
  for i:=1 to High(param) do
  begin
    if (i <> 1)
       then s := s + ' + ';
    s := s + IntToStr(param[i].VInteger);
  end;
  mostrarValores := s + ' = ';
end;

function somarValores(param: array of integer): integer;
var i, sm: integer;
begin
  sm := 0;
  for i:=0 to High(param) do
  begin
    sm := sm + param[i];
  end;
  somarValores := sm;
end;

procedure TForm1.FormShow(Sender: TObject);
var nro1, nro2, nro3, nro4: integer;
begin
  nro1 := 10;
  nro2 := 20;
  nro3 := 30;
  nro4 := 40;

  Memo1.Lines.Add(mostrarValores(['1a. Chamada = ', nro1, nro2]) +
    IntToStr(somarValores([nro1, nro2])));

  Memo1.Lines.Add(mostrarValores(['2a. Chamada = ', nro1, nro2, nro3]) +
    IntToStr(somarValores([nro1, nro2, nro3])));

  Memo1.Lines.Add(mostrarValores(['3a. Chamada = ', nro1, nro2, nro3, nro4]) +
    IntToStr(somarValores([nro1, nro2, nro3, nro4])));
end;

end.
Listagem 2. Aplicação usando listas de argumentos (parâmetros) de comprimento variável

No procedimento de evento onShow do formulário da aplicação foram declaradas e inicializadas às variáveis: nro1, nro2, nro3 e nro4. Em seguida, foi implementada um conjunto de três chamadas, usando listas de argumentos de comprimento variável, as funções mostrarValores() e somarValores(). Adicionalmente, na função mostrarValores(), foi enviado um primeiro argumento para identificar a chamada realizada. Os demais argumentos da lista, comum às duas funções, é formada na primeira chamada pelos valores das variáveis nro1 e nro2; já na segunda chamada, os argumentos usados foram os valores das variáveis nro1, nro2 e nro3; e, na terceira e última chamada da sequência, a lista de argumentos foi formada pelos valores das variáveis nro1, nro2, nro3 e nro4.

Inicialmente, na implementação da função mostrarValores(), a variável s recebe o número da chamada enviado no primeiro argumento da lista (s := param[0].VPChar). A seguir, através de uma instrução de repetição for, o valor inteiro do i-ésimo parâmetro da lista (param[i].VInteger) é convertido em uma string usando a função IntToStr é concatenado na variável s juntamente com o símbolo +. A função High, que retorna a posição do último argumento da lista passada, foi utilizada para definir o limite final da repetição. Finalizando, a função define o valor de retorno com a instrução mostrarValores := s + ' = '.

Por último, a função somarValores() foi implementada usando uma estrutura de repetição for para somar os valores da lista de parâmetros (sm := sm + param[i].VInteger). Como resposta, a função retorna o somatório dos valores dos parâmetros através da instrução somarValores := sm.

Na Figura 2 pode-se observar a execução da aplicação na utilização de listas de argumentos (parâmetros) de comprimento variável.

Executando a aplicação na utilização de listas de argumentos de comprimento variável
Figura 2. Executando a aplicação na utilização de listas de argumentos de comprimento variável

Veja também: