Il existe de bonnes explications ailleurs, mais laissez-moi essayer. (C'est beaucoup plus facile sur un tableau blanc!) Voici l'exemple de Wikipédia avec quelques notations.
Disons que vous copiez 20 octets. Le contrôle de flux du programme pour le premier passage est :
int count; // Défini à 20
{
int n = (count + 7) / 8; // n est maintenant 3. (Le "while" va être exécuté trois fois.)
switch (count % 8) { // Le reste est de 4 (20 modulo 8) donc
// sauter au cas 4
case 0: // [saute]
do { // [saute]
*to = *from++; // [saute]
case 7: *to = *from++; // [saute]
case 6: *to = *from++; // [saute]
case 5: *to = *from++; // [saute]
case 4: *to = *from++; // Commencez ici. Copier 1 octet (total 1)
case 3: *to = *from++; // Copier 1 octet (total 2)
case 2: *to = *from++; // Copier 1 octet (total 3)
case 1: *to = *from++; // Copier 1 octet (total 4)
} while (--n > 0); // N = 3 Réduire N de 1, puis sauter en haut
// à "do" s'il est toujours
} // supérieur à 0 (et c'est le cas)
}
Maintenant, commencez le deuxième passage, nous exécutons juste le code indiqué :
int count; //
{
int n = (count + 7) / 8; //
//
switch (count % 8) { //
//
case 0: //
do { // Le while saute ici.
*to = *from++; // Copier 1 octet (total 5)
case 7: *to = *from++; // Copier 1 octet (total 6)
case 6: *to = *from++; // Copier 1 octet (total 7)
case 5: *to = *from++; // Copier 1 octet (total 8)
case 4: *to = *from++; // Copier 1 octet (total 9)
case 3: *to = *from++; // Copier 1 octet (total 10)
case 2: *to = *from++; // Copier 1 octet (total 11)
case 1: *to = *from++; // Copier 1 octet (total 12)
} while (--n > 0); // N = 2 Réduire N de 1, puis sauter en haut
// à "do" s'il est toujours
} // supérieur à 0 (et c'est le cas)
}
Maintenant, commencez le troisième passage :
int count; //
{
int n = (count + 7) / 8; //
//
switch (count % 8) { //
//
case 0: //
do { // Le while saute ici.
*to = *from++; // Copier 1 octet (total 13)
case 7: *to = *from++; // Copier 1 octet (total 14)
case 6: *to = *from++; // Copier 1 octet (total 15)
case 5: *to = *from++; // Copier 1 octet (total 16)
case 4: *to = *from++; // Copier 1 octet (total 17)
case 3: *to = *from++; // Copier 1 octet (total 18)
case 2: *to = *from++; // Copier 1 octet (total 19)
case 1: *to = *from++; // Copier 1 octet (total 20)
} while (--n > 0); // N = 1 Réduire N de 1, puis sauter en haut
// à "do" s'il est toujours
} // supérieur à 0 (et ce n'est pas le cas, donc abandon)
} // continuer ici...
20 octets sont maintenant copiés.
Note : Le Duff's Device original (montré ci-dessus) copiait vers un périphérique d'E/S à l'adresse to
. Ainsi, il n'était pas nécessaire d'incrémenter le pointeur *to
. Lors de la copie entre deux tampons mémoire, vous auriez besoin d'utiliser *to++
.
0 votes
Beaucoup de gens lisent des articles sur Wikipedia et finissent plus confus qu'avant. Parfois cependant, les articles de Wikipedia ont de bonnes citations. Je trouve l'article cité Dr. Dobb's beaucoup plus clair...