Autorisation : Membre
Nb de messages : 3767
Inscrit le : Lun 19 Oct 2009, 21:25
Posté le : Ven 10 Jui 2011, 23:36
Dans un language classique comme le C, les arguments du "For" sont des instructions réexcutées à chaque besoin. Ainsi les paramètres sont recalculés à chaque fois. En Ti-Basic, les arguments sont calculés au début puis ne sont plus vérifiés. Ainsi on ne peut pas modifier les paramètres en cours d'execution de la boucle.
Des preuves expérimentales sont données plus tard dans le sujet.
=== Language C
Code
for(c=i ; c<j ; c=c+k)
{
}
i est la valeur de départ, j est la valeur de fin et k est l'incrément. ( Comme c'est du code "C", on peut même choisir des opérations à effectuer dans les arguments et que cela soit un peu différent des habitudes (gare au bug cependant). )
On peut modifier les variables c, j et k pendant l'execution du contenu de la boucle : cela modifie le comportement de la boucle pendant son execution.
=== Language Ti-Basic
Code
For(C,I,J,K)
End
On peut modifier J et K en cours de route mais la boucle n'en tient pas compte : on ne peut pas changer la fin ni l'incrément.
Seul C peut être modifié en plein milieu de la boucle.
---------------------- ti82statfr: 2008, inscrit: 2009, ti84pocketfr: noël2011, ti30xbmultiview: iut 2012-2014
Perfectionniste, manque tact. Pas le temps de tout publier depuis 2011. Répond toujours aux questions. (rédigé juin 2014)
Autorisation : Membre
Nb de messages : 3767
Inscrit le : Lun 19 Oct 2009, 21:25
Posté le : Sam 11 Jui 2011, 18:01
Je n'utilise pas I car cela ne sert à rien de le modifier.
Code
int c;
int j = 14; //on prévoie de s'arrêter à 14
int k = 1; //on prévoie d'incrémenter de 1
for(c=1 ; c<=j ; c=c+k)
{
printf("%d",c); //affiche c
if (c==4)
{ k=2; }
j=10;
}
Affiché successivement : 1,2,3,4,6,8,10
Donc l'incrément final est 2 au lieu de 1 et la fin est 10 au lieu de 14.
Code
14->J
1->K
For(C,1,J,K)
Pause C
If C=4
2->K
10->J
End
Affiché successivement : 1,2,3,4,5,6,7,8,9,10,11,12,13,14
L'incrément et la fin demeurent respectivement 1 et 14 alors qu'on a modifié J et K.
Edit :
Pour palier à ce défaut, il faut employer l'agorithme équivalent.
Code
1->C
14->J
1->K
While C<=J
Pause C // 1,2,3,4,6,8,10
If C=4
2->K
10->J
C+K->C
End
---------------------- ti82statfr: 2008, inscrit: 2009, ti84pocketfr: noël2011, ti30xbmultiview: iut 2012-2014
Perfectionniste, manque tact. Pas le temps de tout publier depuis 2011. Répond toujours aux questions. (rédigé juin 2014)
Autorisation : Membre
Nb de messages : 84
Inscrit le : Dim 15 Mai 2011, 11:33
Posté le : Sam 18 Jui 2011, 21:53
Citer : linkakro
Code
int c;
int j = 14; //on prévoie de s'arrêter à 14
int k = 1; //on prévoie d'incrémenter de 1
for(c=1 ; c<=j ; c=c+k)
{
printf("%d",c); //affiche c
if (c==4)
{ k=2; }
j=10;
}
Visiblement, y'a des fans de l'optimisation en basic mais pas toujours en C.
Code
#include <stdio.h>
int main(int argc, char *argv[])
{
int j = 14;
int k = 1;
for(int c=1; c<= j; c = c+k)
{
printf("%d\n",c);
k=(c>=4)?2:k;
j = 10;
}
return 0;
}
Ce code donnera le même résultat que celui de linkakro, il n'y a que la condition du k qui change, vous pouvez essayer de le compiler
Techniquement, le delta entre le C et le Ti-BASIC s'explique certainement par le fait que la machine à calculer fait une copie de C et K, elle les met dans des registres indépendants de ceux contenant les valeurs C et K.
Une manière d'y pallier reste le While C<J, se terminant par C+K->C:End, là ça fonctionnera. Ou bien, on peut essayer en assembleur de trouver les registres stockant ces valeurs... Bon courage!
Autorisation : Membre
Nb de messages : 3767
Inscrit le : Lun 19 Oct 2009, 21:25
Posté le : Dim 19 Jui 2011, 0:02
Merci.
Ton ensemble est intéressant, en particulier la directive préprocesseur.
Cependant je ne connais pas assez le C pour tout comprendre. C'est pas dit à l'école qu'on peut mettre une condition dans un calcul.
Je pense à la même chose que toi concernant les registres.
Je n'ai pas pensé à mentionner l'équivalent du For sans bug. Je le rajoûte
Mais attention : le For teste C<=J, pas C<J.
---------------------- ti82statfr: 2008, inscrit: 2009, ti84pocketfr: noël2011, ti30xbmultiview: iut 2012-2014
Perfectionniste, manque tact. Pas le temps de tout publier depuis 2011. Répond toujours aux questions. (rédigé juin 2014)
Autorisation : Membre
Nb de messages : 3767
Inscrit le : Lun 19 Oct 2009, 21:25
Posté le : Jeu 02 Fév 2012, 16:39
GROS UP !
J'ai effectué d'autres séries de tests qui mettent en valeur le comportement du For, dont un tellement plus simple que ce que j'ai fait avant !
Code
Prompt W
For(W,1,W+2
Pause W
End
Ou bien plus lourd mais plus complet.
Code
Prompt B,C,D
For(W,B,C,D
Pause W
Prompt B,C,D
End
Après quelques observations des résultats, je trouve que le For ne recalule pas ses argumments.
===
Ceux qui maîtrisent déjà les boucles ne verront certainement pas l'intérêt de ce rappel, mais je me suis déjà disputé avec d'autres programmeurs sur la nuance suivante :
Le For effectue un incrément à la fin puis effectue le test de sortie "inférieur ou égal à la borne de sortie".
J'ai effectué tous les tests qui s'imposaient et j'ai toujours trouvé cette conclusion au bout du compte.
For(A,B,C,D):...:End
se traduit par l'algorithme suivant.
Toutefois le For ne recalcule pas ses argumments contrairement à ce code équivalent.
Code
B->A
While A<=C
...
A+D->A
End
===
Plus tordu maintenant. Et innutile, juste testé par curiosité.
Je me sert du principe d'initialisation des aléatoires pour montrer dans quel ordre sont calculés les argumments.
Code
// pour trouver des séries de valeurs intéressantes
Prompt A // 14 ou 15 conviennent bien
A->rand
For(W,1,3
Pause randInt(1,3
End
// pour tester le For proprement dit
Disp "FOR
A->rand
For(W,randInt(1,3),randInt(1,3),randInt(1,3
Pause W
End
Il n'est pas nécessaire de tester randInt(1,3), c'est même plus facile de conclure plus tard si on a des nombres un peu plus grand comme 6 ou 10.
Comme valeurs à saisir dans A, on peut mettre n'importe quel réel, jusqu'à trouver une série de résultats qui ait un sens. 14 et 15 sont corrects pour randInt(1,3)
En comparant les résultats des deux parties du prog, on peut associer les trois résultats de la première partie aux paramètres du For (valeur de départ, valeur de sortie et pas) par l'expérience.
J'ai conclut que les argumments sont calculés de gauche à droite puis que W est initialisé.
---------------------- ti82statfr: 2008, inscrit: 2009, ti84pocketfr: noël2011, ti30xbmultiview: iut 2012-2014
Perfectionniste, manque tact. Pas le temps de tout publier depuis 2011. Répond toujours aux questions. (rédigé juin 2014)