II. c_memset▲
II-A. Prototype▲
void * c_memset (void * s, int c, c_size_t n);II-B. Description et comportement▲
La fonction c_memset copie l'octet c (par conversion
de type unsigned char) sur une longueur n à partir
de l'adresse s.
La fonction retourne l'adresse s.
II-C. Algorithme▲
Voici un algorithme possible pour la fonction c_memset:
algorithme
fonction c_memset (s:générique, c:entier, n:entier):générique
début
i <- 0
tant que n <- n - 1 faire
s[i] <- c
i <- i + 1
ftant
retourne s
fin
lexique
s : générique : Zone mémoire d'un type quelconque.
c : entier : Octet à copier.
n : entier : Longueur de la copie.
i : entier : Variable d'incrémentation.
L'algorithme est des plus basiques...
Nous ne disposons que d'une boucle qui part de l'adresse s,
et avance de n cases en mémoire. Les instructions de la boucle copient
l'octet c à l'emplacement courant de s et incrémentent
i respectivement.
Nous sortons de la fonction en retournant l'adresse s.
| Complexité temporelle dans le pire des cas: |
|---|
| Parcours simple de la boucle n fois: complexité en O(n) |
II-D. Implémentation▲
void * c_memset (void * s, int c, c_size_t n)
{
unsigned char * p_s = s;
while (n--)
{
*p_s++ = c;
}
return s;
}
L'implémentation change quelque peu par rapport à l'algorithme décrit
ci-dessus car nous utilisons des pointeurs (je rappelle que les algorithmes
présentés dans cet article sont génériques et peuvent convenir à tout
type de langage).
Nous commençons par déclarer un pointeur sur unsigned char
que nous faisons pointer à l'adresse s.
La norme spécifie en effet que l'octet c (ici de type int)
est copié par conversion en type unsigned char ce qui est fait
implicitement ici étant donné le type de notre pointeur p_s !
Une chose pratique mais pas trop courante, c'est l'utilisation de l'argument
n que l'on décrémente directement, cela permet en effet de ne
pas avoir à déclarer une variable pour le parcours. Nous décrémentons
donc directement la valeur de n dans la condition de la boucle.
On termine par copier simplement l'octet c à l'emplacement
désigné par *p_s puis nous nous déplaçons dans l'adresse
en incrémentant directement notre pointeur !
II-E. Tests▲
#include "c_string.h"
#include <stdio.h>
int main (void)
{
char tab [20] = { 0 };
int i = 0;
c_memset (tab, 1, 10);
for (i = 0; i < 20; i++)
{
printf ("%d ", tab[i]);
}
printf ("\n");
return 0;
}Le test est des plus simples : on copie l'octet, ici de valeur 1 sur la première moitié du tableau puis nous l'affichons, voici ce que cela doit donner sur la console :
1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
Process returned 0 (0x0) execution time : 0.015 s
Press any key to continue.

