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.