1

Euh non rien de particulier, mais je m'emmerde. En fait il faudrait une rubrique "JRAD C/C++", mais à défaut je poste ici gni
En plus plus c'est souvent du réchauffé, vu que j'ai évoqué la chose sur irc une fois ou deux il y a quelques mois (années?).

Code à présenter aux débutants en C pour leur faire comprendre ce qu'est la programmation (nan j'déconne)

  register n = (count + 7) / 8;      /* count > 0 assumed */

   switch (count % 8)
   {
   case 0:        do {  *to = *from++;
   case 7:              *to = *from++;
   case 6:              *to = *from++;
   case 5:              *to = *from++;
   case 4:              *to = *from++;
   case 3:              *to = *from++;
   case 2:              *to = *from++;
   case 1:              *to = *from++;
                      } while (--n > 0);
   }
Ce code porte le doux nom de Duff's device. Il est parfaitement valide et défini.
Son auteur est Tom Duff

2

ca tombe bien, j'avais pas grand chose à faire. cheeky

sympa ce bout de code !

3

humm c'est bien superbe tout ça cheeky
(ceci dit, j'ai cherché sur le net pourquoi le *to et pas *to++, c'est parce qu'il s'agit d'une écriture sur un périphérique mappé sur un seul mot (écriture séquentielle donc))
avatar
fabetal_ > Hier, je me suis fait monter par un pote
redangel > et en chevals, ça donne quoi?
Nil> OMG I think I'm gay

4

Et euh, il fait quoi ce code o_O ?

5

ca répète 'count' fois '*to = *from++'

6

Oui, c'est une boucle dépliée 8 fois. Elle copie une donnée dans un port d'entrées/sorties.

7

OK, merci smile

8

Dépliée 8 fois ou 3 fois ?
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

9

ben 8. Pourquoi 3 ?

10

2^3 : Si chaque dépliage divise le nombre d'itérations par deux, il faut déplier trois fois pour diviser le nombre d'itératiosn par 8 smile
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

11

Le dépliage n'est pas une opération récursive. Déplier N fois = recopier N fois le corps de la boucle ^^ wink

12

qqun pourrait decortiquer/expliciter un peu plus ce code pour ceux qui sont à la rue en c++ ?

13

 register n = (count + 7) / 8;      /* count > 0 assumed */ // Déclaration d'une variable n de type int

   switch (count % 8) // On prend le reste de la division par 8, parce que la boucle en-dessous a été déroulée 8 fois
   {  // On saute au milieu de la boucle, parce que la taille des données à copier n'est pas forcément un multiple de 8
   case 0:        do {  *to = *from++; // Là, c'est vrai que c'est marrant, la boucle est emmêlée avec les "case :".
   case 7:              *to = *from++; // On remarque qu'il n'y a pas de mot-clé break qui nous ferait sortir du bloc switch
   case 6:              *to = *from++; // Donc la copie continue
   case 5:              *to = *from++;
   case 4:              *to = *from++;
   case 3:              *to = *from++; // Jusqu'à la fin de la boucle while...
   case 2:              *to = *from++;
   case 1:              *to = *from++;
                      } while (--n > 0); // On boucle autant de fois que nécessaire pour copier toutes les données
   }
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

14

Euh, la position du do{ me semble bizarre, est-ce qu'il est vraiment pris en compte meme si (count % 8) n'es pas egal a 0?
N/A

15

Oui.

Les "case :" ne servent qu'à indiquer où sauter dans la boucle en fonction de la valeur de count%8.
On aurait pu écrire :
switch(count % 8)
{
  do {
  case 0: *to = *from++;
  case 7: *to = *from++;
  case 6: *to = *from++;
  ... 
  }while(--n > 0);
}
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

16

hum j'ai du mal là ... il se passe quoi par exemple si count vaut 1 ?

17

ça saute à la fin de la boucle dans le "case 1:", et puis ça continue la boucle, si n > 1.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

18

spectras :
Le dépliage n'est pas une opération récursive. Déplier N fois = recopier N fois le corps de la boucle ^^ wink

Donc elle n'a été dépliée que 7 fois, car sinon déplier 1 fois ne voudrait rien dire (à moins que ce ne soit déjà le cas?) confus
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

19

Sasume :
ça saute à la fin de la boucle dans le "case 1:", et puis ça continue la boucle, si n > 1.

ouais mais si ca saute ca arrive en plein milieu d'un bloc c'est bizarre, ca donne l'impression que ca ne "lira" jamais le "do {" ... enfin bon, c'est cheum, je comprend pas comment ca tourne cette boucle :/

20

ben en fait le switch case c'est juste un goto avec des conditions, c'est-à-dire que dans switch (condition) {code}, "code" est compilé en entier avec des labels qui sont placés aux endroits où on a les "case n :", et switch (condition) évalue la condition et saute au bon label.
Le truc c'est que généralement les switch case sont utilisés proprement, avec une sémantique équivalente à un enchaînement de if then else, mais vu qu'en réalité c'est une sorte de goto multiple, ça permet de faire des trucs crades dans ce genre sick (ie sauter en plein milieu d'un bloc).
Si ça a l'air bizarre c'est parce que le goto, ben il a pas vraiment de sémantique en soi : c'est « continue l'exécution à tel endroit » ; et il est indépendant de la structure du C, donc en fait tu peux faire absolument n'importe quoi (enfin je ne crois pas que tu aies le droit de sauter carrément hors de la fonction, mais à part ça...) Dès que tu utilises des goto, le C cesse complètement d'être un langage structuré, en fait, mais il garde la même syntaxe que d'habitude quand même donc c'est perturbant cheeky

Si tu veux, le code compilé ressemblera à ça :
goto count % 8
0 : *to = *from++
...
1 : *to = *from++; n = n -1; if n > 0 goto 0
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

21

bon je regarderais quand je serais moins a la masse parce que là je capte pas comment ca peut marcher ...

22

regarde mon edit si tu veux ^^. Le truc c'est qu'il faut savoir qu'une boucle do while, une fois compilée, c'est un bloc de code avec un goto conditionnel à la fin ; si tu ne sais pas ça tu ne peux pas comprendre comment ça marche happy. Il ne faut pas essayer de penser programmation structurée, ça ne peut pas marcher ^^ : il faut oublier qu'on a écrit ça comme une boucle et considérer que c'est une suite d'instructions, c'est le seul moyen de comprendre ce que fait un saut qui va directement à l'une de ces instructions sans passer par l'« entrée » de la boucle.
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

23

ah ok je vois le truc, merci. bah ... c'est bien cheum ^^