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.

