cs_kalif
Messages postés362Date d'inscriptionmardi 18 décembre 2001StatutMembreDernière intervention24 août 2012
-
22 févr. 2006 à 09:49
cs_Forman
Messages postés600Date d'inscriptionsamedi 8 juin 2002StatutMembreDernière intervention 6 avril 2010
-
3 août 2006 à 18:40
bonjour a tous
j'aimerai savoir comme remetre a 0 une variable comme
Emandhal
Messages postés194Date d'inscriptiondimanche 2 mars 2003StatutMembreDernière intervention10 octobre 20063 22 févr. 2006 à 18:19
Si, elle fonctionne mais elle demande une sérieuse connaissance de la taille du tableau et de la taille du type de variables du tableau.
- Pour un tableau fixe, c'est facile, un simple SizeOf(MonTableau) et le tour est joué.
- Pour un tableau dynamique, là ca ne marche plus. SizeOf(MonTableau) renvoie la taille du pointeur du tableau, et donc FillChar Initialise le pointeur autrement dit : gare aux plantages dus à un mauvais pointeur. Pour remédier à ca, c'est assez simple : FillChar(MonTableau[0], Length(MonTableau)*SizeOf(TypeElementsTableau), 0{par exemple}): // dans le cas de kalif, TypeElementsTableau c'est Byte
Malheureusement cette méthode est à revoir pour le cas d'un Array of Array of puisque les éléments du 1er array pointent sur d'autres Array lol. Faut donc faire une boucle For z := Low(MonTableau) to High(MonTableau) do FillChar(MonTableau[z][0], Length(MonTableau[z])*SizeOf(TypeElementsTableau), 0); et ainsi de suite suivant les dimentions du tableau...
Pour ce qui est de la valeur d'initialisation, y'a un truc à savoir. Value est un byte. Si Value<>0 et que le type des éléments du tableau est un Integer (4 bytes à la suite) par exemple, va y avoir des surprises :
Si Value=2 (0b0010) par exemple, ca affectera à chaque élément la valeur $2222 (0d8738 ou 0b10001000100010) et non 2 comme voulu.
Tout problème a sa solution... Mais en général, c'est jamais la bonne...
Vous n’avez pas trouvé la réponse que vous recherchez ?
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 22 févr. 2006 à 18:36
Emandhal--> c'est pour cela qu'en premiere solution j'avais donné
une initailisation par boucle qui fonctionne quelque soit le cas (il
sufit d'imbriquer des boucles si besoin est)
Pour remplir un tableau de type byte avec des integer ou même tout
autre chose on peut utiliser des pointeurs et transtyper:
par exemple pour un integer on déclare une variable Valeu:r:
^integer et récupére l'adrresse du tableau qu'on veut remplir par
Valeur:=@tableau [xx]; ensuite on affecte la valeur Valeur^:=YY;
On fait l'opération inverse pour récupérer les valeurs.
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202235 23 févr. 2006 à 12:44
sur un tableau statique, y'a pas 36000 solutions :
type
TA1024Bytes = array [0.1024] of byte;
var
MonTableau : TA1024Bytes;
procedure EmptyTableau(var table : TA1024Bytes);
var x : integer;
begin
for x := low(table) to high(table) do table[x] := 0;
end;
solution qui ne sert pas a grand chose (a part remettre a 0 toutes les valeurs) car que les valeurs soit a 0 ou a un autre chiffre, sa taille en memoire serat toujours la meme (1025 octets).
autre solution, le tableau dynamique :
Type
TBytesArray = array of byte;
Var
MonTableau = TBytesArray;
// permet de definir la taille du tableau
procedure SetArraySize(var table : TBytesArray);
begin
SetLength(table,1024);
end;
{ utilisation :
SetArraySize(MonTableau);
}
// "detruit" le tableau
procedure FlashArray(var table : TBytesArray);
begin
SetLength(table,0);
end;
{ utilisation :
FlashArray(MonTableau);
}
// recupere une valeur du tableau
function GetByteFrom(var table : TBytesArray; const index : integer) : byte;
begin
if (index >= low(table)) and (index <= high(table)) then result := table[index];
end;
{ utilisation :
N := GetByteFrom(MonTableau,128);
}
// recupere plusieurs valeurs du tableau dans un autre tableau dynamique
procedure GetMultiBytesFrom(out aTo : TBytesArray; var aFrom : TBytesArray; const index : array of byte);
var x : integer;
begin
setlength(aTo,high(index));
for x := 0 to high(index) do begin
if (index[x] >= low(aFrom)) and (index[x] <= high(aFrom)) then
aTo[x] := aFrom[index[x]];
// place une valeur dans le tableau
function SetByteTo(var table : TBytesArray; const index : integer; const value : byte = 0) : boolean;
begin
if (index >= low(table)) and ( index <= high(table)) then begin
table[index] := value;
result := true;
end else begin
result := false;
end;
end;
{ utilisation :
if not SetByteTo(MonTableau,954,25) then showmessage('Erreur dans les limites d''etendues');
ou :
SetByteTo(MonTableau,812,128);
}
voila...
<hr size="2" width="100%">La theorie c'est quand on sait tout, mais que rien ne fonctionne.
La pratique c'est quand tout fonctionne, mais que personne ne sait pourquoi.
<hr>
procedure RemplirDeZeros;
begin
Variable:=VariableNull;
end;
Cette méthode est garantie la plus rapide! (et la plus simple, hormis la déclaration de la constante VariableNull qui est assez longue ;-) ). En effet, pour remplir Variable de zéros, il suffit d'écrire la ligne:
Variable:=VariableNull;
Delphi génère le code correspondant à cette affectation SANS UTILISER DE BOUCLES si mes souvenirs sont bons, c'est à dire que le code machine généré équivalent à cette instruction est à peu de choses près:
(en fait, c'est plus compliqué car plutôt que de remplir Byte par Byte, le compilateur génère un code qui travaille sur 32 bits pour que ça aille encore plus vite)
La procédure FillChar est programmée avec une boucle, comme on peut le constater dans System.pas:
procedure _FillChar(var Dest; count: Integer; Value: Char);
{$IFDEF PUREPASCAL}
var
I: Integer;
P: PChar;
begin
P := PChar(@Dest);
for I := count-1 downto 0 do
P[I] := Value;
end;
{$ELSE}
asm
{ ->EAX Pointer to destination }
{ EDX count }
{ CL value }
PUSH EDI
MOV EDI,EAX { Point EDI to destination }
MOV CH,CL { Fill EAX with value repeated 4 times }
MOV EAX,ECX
SHL EAX,16
MOV AX,CX
MOV ECX,EDX
SAR ECX,2
JS @@exit
REP STOSD { Fill count DIV 4 dwords }
MOV ECX,EDX
AND ECX,3
REP STOSB { Fill count MOD 4 bytes }
@@exit:
POP EDI
end;
{$ENDIF}
La partie en assembleur travaille aussi sur 32 bits pour otpimiser le transfert.
De la même façon, il y a aussi l'API ZeroMemory mais il faut passer l'adresse de la variable:
ZeroMemory(@Variable,SizeOf(Variable));
Cette écriture a l'avantage de s'adapter si l'on décide de changer la taille du tableau dans sa déclaration a posteriori.