Domanda

I stava guardando Delfi: matrice di Char e TCharArray "Tipi incompatibili" e iniziato a sperimentare. Quello che ho scoperto è piuttosto interessante.

procedure Clear(AArray: array of Integer);
var
  I: Integer;
begin
  for I := Low(AArray) to High(AArray) do
    AArray[I] := 0;
end;

var
  MyArray: array of Integer;
begin
  Clear(MyArray);
end.

Questo semplice piccolo esempio mostra come è possibile passare un array dinamico a una procedura utilizzando un parametro aperto di allineamento. Esso viene compilato ed eseguito esattamente come previsto.

procedure Clear(AArray: array of Char);
var
  I: Integer;
begin
  for I := Low(AArray) to High(AArray) do
    AArray[I] := #0;
end;

var
  MyArray: array of Char;
begin
  Clear(MyArray);
end.

Ecco codice quasi identico con la sola differenza che utilizza una matrice di Char anziché Integer. Esso non può essere compilato. Invece il compilatore sputa fuori:

 E2010 Incompatible types: 'Array' and 'Dynamic array'

Perché questo sarebbe?

Dopo aver cercato per un po 'ho scoperto questo rapporto QC . Io corro Delphi 2009 e la sua ancora accadendo.

È stato utile?

Soluzione

Poiché la documentazione menziona specificamente parametri array aperti di tipo char per essere compatibile con gli array dinamici, questo dovrebbe essere un problema. Da 'Open Array Parametri' :

  

function Find(A: array of Char):   Numero intero;
[...]
Nota: [...] Il   Nell'esempio precedente crea una funzione   che prende qualsiasi array di elementi Char,   compresi (ma non limitati a) dinamica   array. [...]

Altri suggerimenti

Si può lavorare con questo tipo di matrice, che definisce il proprio tipo:

type
  TCharDynArray = array of char;

procedure Clear(AArray: TCharDynArray);
var
  I: Integer;
begin
  for I := Low(AArray) to High(AArray) do
    AArray[I] := #0;
end;

procedure test;
var
  MyArray: TCharDynArray;
begin
  Clear(MyArray);
end;

Questo codice verrà compilato bene. Non fa nulla di utile, naturalmente (il parametro AArray non è impostato come "var", quindi è copiato sullo stack prima di assegnare un # 0 per ogni articolo). Ma almeno, si compila.

In pratica, ho scoperto più facile definire o uso di alto livello di tipi di matrici dinamiche (come TIntegerDynArray), perché almeno consente di passare la matrice come riferimento, utilizzando una var, evitando così di effettuare una copiare sulla pila, e rendere il vostro codice più veloce.

A proposito della mappatura a un PChar, è usuale per tutti gli array dinamici: è possibile associare un TIntegerDynArray a un puntatore, quindi utilizzarlo come un PInteger o un PIntegerArray:

procedure AddInteger(var Values: TIntegerDynArray; Value: integer);
var n: integer;
begin
  n := Length(Values);
  SetLength(Values,n+1);
  Values[n] := Value;
end;

procedure Loop(V: PInteger);
begin
  if V<>nil then
    while V^<>0 do begin
      write(V^,' ');
      inc(V); // go to next integer in array
    end;
end;

var IntArray: TIntegerDynArray;
begin
  Loop(pointer(IntArray)); // will display nothing, since pointer(IntArray)=nil for IntArray=[]
  AddInteger(IntArray,2);
  AddInteger(IntArray,3);
  AddInteger(IntArray,0);
  Loop(pointer(IntArray)); // will display '2 3 '  
end.

Il problema è il codice "vettore di char" beeing incompatibile con "matrice di integer" è certamente in intrinseci compilatore, e il fatto che una PChar può essere di tipo pressofuso in una stringa.

Credo che il motivo è che array of Char è compatibile con PChar, come fa questo codice di compilazione:

procedure Clear(AArray: array of Char);
var
  I: Integer;
begin
  for I := Low(AArray) to High(AArray) do
    AArray[I] := #0;
end;

var
  MyArray: array of Char;
  P: PChar;
begin
  Clear(P^);
end.

Questo è probabilmente per ragioni storiche.
Speriamo Barry Kelly o Danny Thorpe entreranno in gioco e fornire un po 'di feedback su questo.

- Jeroen

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top