IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Étude détaillée du module String de la libc


précédentsommairesuivant

II. c_memset

II-A. Prototype

 
Sélectionnez
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 :

 
Sélectionnez
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

 
Sélectionnez
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

 
Sélectionnez
#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 :

 
Sélectionnez
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.

précédentsommairesuivant

Copyright © 2007 Franck Hecht. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.