Question

À l'origine, j'avais un tableau [1..1000] défini comme une variable globale. Mais maintenant, j'ai besoin que cela soit n, pas 1000 et je ne le découvrirai que plus tard. Je sais ce que n est avant de remplir le tableau, mais j’ai besoin d’être global, il faut donc un moyen de définir la taille d’un tableau global au moment de l’exécution.

Le contexte remplit un tableau avec une transformation linéaire des octets d'un fichier. Je ne sais pas quelle est la taille du fichier tant que personne ne veut l'ouvrir et que les fichiers peuvent être de n'importe quelle taille.

Était-ce utile?

La solution

À partir de Delphi 4, Delphi prend en charge les tableaux dynamiques . Vous pouvez modifier leurs tailles au moment de l'exécution et ils conserveront les données que vous avez stockées dans d'autres éléments à l'ancienne taille. Ils peuvent contenir des éléments de n'importe quel type homogène, y compris des enregistrements et d'autres tableaux. Vous pouvez déclarer un tableau dynamique comme vous déclarez normal, & statique; statique " tableaux, mais omettez simplement les limites du tableau:

var
  ArthurArray: array of TForm;

Bien que les tableaux statiques vous permettent de spécifier la limite inférieure et supérieure, le bas index d'un tableau dynamique est toujours zéro. L'indice haut est donné par la fonction High , qui en renvoie toujours un de moins que la longueur du tableau. Pour tout tableau dynamique x , élevé (x) = longueur (x) -1 .

Vous pouvez accéder à une variable globale à l'aide de n'importe quel code, y compris les procédures locales.

Une variable globale de type tableau dynamique sera initialisée pour devenir un tableau vide . Sa longueur sera zéro et High appelé sur ce tableau sera -1. Low sur ce tableau renverra toujours zéro.

Vous pouvez à tout moment redimensionner un tableau dynamique. Utilisez la fonction SetLength , comme vous pouvez le faire avec des chaînes:

var
  NumElements: Integer;
begin
  NumElements := GetNumberOfArthurForms();
  SetLength(ArthurArray, NumElements);
end;

Si vous avez un tableau multidimensionnel, vous pouvez définir leur longueur dans une boucle:

var
  matrix: array of array of Double;
  i: Integer;
begin
  SetLength(matrix, height);
  for i := 0 to height - 1 do
    SetLength(matrix[i], width);
end;

Il existe un raccourci pour définir les longueurs de tous les tableaux internes en même temps:

begin
  SetLength(matrix, height, width);
end;

Comme je l'ai mentionné, les tableaux dynamiques conservent leurs anciennes valeurs lorsque vous les redimensionnez:

var
  data: array of string;
begin
  SetLength(data, 2);
  data[1] := 'foo';
  SetLength(data, 20);
  Assert(data[1] = 'foo');
end;

Mais si vous raccourcissez le tableau, tous les éléments résidant au-delà du dernier dernier élément disparaîtront à jamais:

begin
  SetLength(data, 20);
  data[15] := 'foo';
  SetLength(data, 2);
  // data[15] does not exist anymore.
  SetLength(data, 16);
  writeln(data[15); // Should print an *empty* line.
end;

Mes démonstrations ci-dessus ont utilisé des chaînes. Les chaînes sont spéciales à Delphes; ils sont gérés par le compilateur via des comptages de références. De ce fait, les nouveaux éléments de tableau dynamique de type chaîne sont initialisés pour être vides. Mais si j'avais utilisé des entiers à la place, il n'y aurait aucune garantie de la valeur des nouveaux éléments. Ils peuvent être zéro, mais ils peuvent être autre chose, tout comme les valeurs initiales des variables locales autonomes.

Les fichiers d’aide de Delphi 7 sont très bons, me dit-on. Lisez-en plus sur les tableaux dynamiques. Vous pouvez trouver des démonstrations de leur utilisation dans les codes sources VCL et RTL fournis dans votre installation Delphi, ainsi que dans presque tous les exemples de code Delphi produits au cours des 10 dernières années.

Autres conseils

Tout d'abord, voici une réponse générale à la première partie de votre question:

Si votre tableau n'est plus statique, vous pouvez envisager d'utiliser une TList, une TStringList ou l'une des nombreuses classes de conteneur de l'unité Contnrs.

Ils peuvent mieux représenter ce que vous faites, fournir des fonctionnalités supplémentaires dont vous pourriez avoir besoin, par exemple. en triant ou en paires nom / valeur, ils se développent de manière dynamique au fur et à mesure de vos besoins et ont été très bien optimisés.

Ensuite, vous avez dit:

  

"Le contexte remplit un tableau avec une transformation linéaire des octets d'un fichier. Je ne sais pas quelle est la taille du fichier tant que personne ne veut l'ouvrir et que les fichiers peuvent être de n'importe quelle taille. "

Pour votre problème spécifique, je chargerais les octets dans un fichier en utilisant:

  MyFileStream := TFileStream.Create(Filename, fmOpenRead or fmShareDenyWrite);
  Size := MyFileStream.Size - MyFileStream.Position;
  SetLength(Buffer, Size);
  MyFileStream.Read(Buffer[0], Size);

Ensuite, vous pouvez facilement utiliser un pointeur PChar pour parcourir chaque caractère ou même chaque octet de la mémoire tampon un par un et les transformer à votre guise.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top