%
%     This file is part of the Code_Saturne Preprocessor, element of the
%     Code_Saturne CFD tool.
%
%     Copyright (C) 1998-2007 EDF S.A., France
%
%     contact: saturne-support@edf.fr
%
%     The Code_Saturne Preprocessor is free software; you can redistribute it
%     and/or modify it under the terms of the GNU General Public License
%     as published by the Free Software Foundation; either version 2 of
%     the License, or (at your option) any later version.
%
%     The Code_Saturne Preprocessor is distributed in the hope that it will be
%     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
%     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%     GNU General Public License for more details.
%
%     You should have received a copy of the GNU General Public License
%     along with the Code_Saturne Preprocessor; if not, write to the
%     Free Software Foundation, Inc.,
%     51 Franklin St, Fifth Floor,
%     Boston, MA  02110-1301  USA
%

\section{Utilisation de la structure objet\label{cha:util}}


Les grandes lignes de la structure objet du \pcs ont été exposées
dans le chapitre précédent.

Dans le présent chapitre, on donne
des informations utiles à la programmation dans le \pcs, notamment~:
\begin{liste}
\item sur la manière d'utiliser la structure objet~;
\item sur l'emploi des fonctions disponibles pour utiliser au mieux
  la structure objet.
\end{liste}

Les informations contenues dans ce chapitre sont très techniques
et pour mieux les illustrer,
des exemples seront directement sortis des sources du \pcs\footnote{%
Les morceaux de programme qui servent d'exemple,
sont retranscrits tels qu'ils existent, moyennant un reformatage
pour les besoins de mise en page,
consistant à la suppression de lignes blanches et d'espaces.}.


\subsection{Mise en place des relations de visibilité\label{sec:visibilite}}


La compilation est configurée de telle manière qu'il est toujours
possible, a priori, d'inclure n'importe quel fichier en-tête \og .h \fg
dans un fichier source.

Afin de respecter l'architecture du \pcs, on appliquera systématiquement
les règles de visibilité exposées à la section~\ref{sec:config}.\\

On reprend le cas générique décrit à la section~\ref{sec:config.visibilite},
où un \paquet \Classe accède à un \paquet \Classeacc.

Supposons qu'on veuille renseigner la rubrique du fichier \classesuffc
\begin{quote}
\begin{alltt}
  *  Fichiers `include' visibles des paquetages visibles
\end{alltt}
\end{quote}

Cette rubrique propose d'inclure, si nécessaire, les fichiers en-tête \og .h \fg
visibles du \paquet \Classeacc~:

\begin{liste}
\item \classeaccpubl
\item \classeaccsuffh
\end{liste}

Si le \paquet \Classe correspond en fait au \paquet \Entite
\reffig{fig:config.sssys.base},
les seuls \paquets visibles sont \Famille et \Champ.


\subsection{Utilisation des relations entre paquetages\label{sec:util.paquet}}


\subsubsection{Fonctions liées à une structure~C\label{sec:util.paquet.fonc}}

Les noms des fonctions liées à une structure~C \classet, afin de rappeler
qu'elles sont les implémentations des \methodes de la \classe \Classe,
sont préfixées par
\begin{quote}
\begin{alltt}
ecs_classe__
\end{alltt}
\end{quote}
et leur nom complet est de la forme
\begin{quote}
\begin{alltt}
ecs_classe__\textit{xyz}()
\end{alltt}
\end{quote}

Ces fonctions sont contenues dans les fichiers \classesuffc.

Une sous-\classe de la \classe \Classe, \SousClasse,
n'est jamais implémentée en tant que structure~C~:
elle est directement définie par la structure \classet.

Les \methodes de la sous-\classe sont regroupées, quant à elles,
dans un fichier dédié à la sous-\classe et les fonctions mentionnent
la sous-\classe dans leur nom.

Par exemple, la sous-\classe \ChampAtt de la \classe \Champ
est définie directement par la structure \champt~;
les fonctions qui implémentent ses \methodes sont contenues
dans le fichier \fc{ecs\_champ\_att.c}
et ont un nom de la forme \fc{ecs\_champ\_att\_\_\textit{xyz}()}.


\subsubsection{Appel d'une fonction sur une structure visible
               \label{sec:util.paquet.appel}}

Comme conséquence des relations de visibilité,
une fonction liée à une structure ne peut appeler que deux types
de fonction~:
\begin{liste}
\item soit une fonction du même \paquet~;
\item soit une fonction d'un \paquet visible.
\end{liste}

Considérons le cas du traitement du tri des \elems suivant leur
\typgeo.\\
Au niveau de l'\entite, la fonction {\tt ecs\_entmail\_pcp\_\_trie\_typ\_geo()}
retranscrite ci-dessous, réalise tous
les traitements relatifs à la structure \entmailt
et délègue la suite des traitements aux fonctions s'appliquant
sur les \champs.

\begin{exemple}{Appel d'une fonction sur une structure visible (1)\label{ex:struct.1}}

void
ecs_entmail_pcp__trie_typ_geo(ecs_entmail_t  *entmail,
                              ECS_ENTMAIL_E   typ_entmail)
\{
  int            dim_elt;
  ecs_tab_int_t  vect_renum;

  dim_elt = (int)typ_entmail;

  /* Tri des types géométriques des éléments (si nécessaire) */
  /*---------------------------------------------------------*/

  vect_renum.nbr = 0;
  vect_renum.val = NULL;

  if (entmail->champ[ECS_CHAMP_DEF] != NULL) 
    vect_renum = ecs_champ_def__trie_typ(entmail->champ[ECS_CHAMP_DEF],
                                         dim_elt);

  /* Application du vecteur de renumérotation sur les autres champs */
  /*----------------------------------------------------------------*/

  if (vect_renum.val != NULL) \{

    ecs_tab__int__inverse(&vect_renum);

    /* Traitement du champ représentant les définitions */

    ecs_champ_chaine__transforme(entmail->champ[ECS_CHAMP_DEF],
                                 vect_renum.nbr,
                                 vect_renum,
                                 ecs_champ__transforme_pos);

    /* Traitement des champs "attribut" */

    ecs_champ_chaine__transforme(entmail->champ[ECS_CHAMP_ATT],
                                 vect_renum.nbr,
                                 vect_renum,
                                 ecs_champ__transforme_pos);

    BFT_FREE(vect_renum.val) ;

  \} /* Fin : si le vecteur de renumérotation n'est pas NULL */

\}
\end{exemple}


On ne s'étonnera pas qu'à un niveau de structure donné,
aucun traitement ne soit nécessaire~:
la fonction liée à la structure se contente alors de transférer
le traitement à effectuer sur une structure visible de plus bas niveau.

Dans l'exemple ci-dessous, aucun traitement au niveau de la structure
\maillaget n'est nécessaire~:la fonction {\tt ecs\_maillage\_\_calc\_coo\_ext()}
se contente d'afficher les coordonnées minimales et maximales du domaine.


\begin{exemple}{Appel d'une fonction sur une structure visible (2)\label{ex:struct.2}}

void
ecs_maillage__calc_coo_ext(ecs_maillage_t  *const maillage)
\{
  assert(maillage != NULL);

  if (maillage->dim_e == 3) \{

    assert(maillage->entmail != NULL);
    assert(maillage->entmail[ECS_ENTMAIL_SOM] != NULL);

    ecs_entmail_pcp__calc_coo_ext(maillage->entmail[ECS_ENTMAIL_SOM]);

  \}
\}
\end{exemple}


\subsection{Utilisation de la structure \champ\label{sec:util.champ}}


La structure relative à un \champ jouant un rôle central
dans le \pcs et ayant une constitution assez complexe,
son utilisation est décrite en détail dans ce chapitre.

Bien que le contenu d'un champ puisse être utilisé ou rempli indifféremment
soit directement soit à partir des structures \vect,
pour l'implémentation des algorithmes
on utilisera la structure \vect \refpar{sec:structure.vec}.\\

Un ensemble de fonctions disponibles permettent de passer
directement d'une structure \champ à la structure \vect associée,
et inversement.

Ces fonctions appellent des fonctions de plus bas niveau, qui
construisent un \vect à partir du \champ, en réalisant les actions
suivantes~:
\begin{liste}
\item si le tableau des positions suit une \regl, un tableau alloué est
  construit, et la structure \vect référence le pointeur sur ce tableau~;
\item si le tableau des positions n'est pas une \regl, la structure \vect
  référence directement le pointeur sur le tableau des positions du \champ.
\item la structure \vect référence directement le pointeur sur le tableau des
  valeurs du \champ, moyennant la conversion de type qui convient.
\end{liste}

Les fonctions dédiées à la transformation inverse commencent par
vérifier si les valeurs du tableau des positions du \vect peuvent
constituer une suite arithmétique (commencant à 1)~: si c'est le cas,
le tableau des positions du \champ est défini par la \regl correspondante,
et dans le cas contraire, le tableau du \vect sera directement référencé
dans le \champ. Le tableau de valeurs du \vect sera directement
référencé dans le \champ.

On voit donc qu'un \champ et le \vect associé sont intimement liés,
puisqu'ils peuvent référencer le même pointeur sur un tableau.
Cela évite d'avoir à allouer un nouveau tableau et d'effectuer une
copie pour le remplir.  La contrepartie de cette façon de procéder,
c'est qu'un même pointeur sur un tableau est référencé dans deux
structures différentes.  Pour éviter les problèmes de pointeur
\og perdu \fg, on utilisera toujours utiliser les fonctions de passage
du \champ au \vect (qui effectuent ces conversions et éventuelles
libérations de manière fiable).

On décrit dans les sections suivantes les fonctions permettant de créer,
modifier et utiliser la structure \champ,
en insistant particulièrement sur les fonctions de passage
d'un \champ à son \vect associé.

L'utilisation de ces fonctions est illustrée dans des cas concrets,
directement tirés des sources du \pcs.

Parmi les exemples suivants, ceux qui mettent en jeu un \vect
concernent un \vectint, mais toutes les fonctions
mentionnées dans ce cas ont leur équivalent pour un \vectreal.


\subsubsection{Utilisation d'un \champ existant non modifié\label{sec:champ.nonmod}}

Le passage d'un \champ, dont le contenu ne sera pas modifié,
au \vect correspondant
repose sur l'utilisation de deux fonctions~:
\begin{itemize}
\item la fonction qui retourne la structure \vect, remplie à partir
  du \champ~:
  \begin{center}
    \index{ecs_champ__initialise_vec_int@\verb=ecs_champ__initialise_vec_int=}
    \begin{alltt}
ecs_vec_int_t * ecs_champ__initialise_vec_int(ecs_champ_t  *this_champ)
    \end{alltt}
  \end{center}
\item la fonction qui libère la structure \vect et les éventuels
  tableaux règlés associés au \champ~:
  \begin{center}
    \index{ecs_champ__libere_vec_int@\verb=ecs_champ__libere_vec_int=}
    \begin{alltt}
void ecs_champ__libere_vec_int(ecs_champ_t    *this_champ,
                               ecs_vec_int_t  *vec_int)
    \end{alltt}
  \end{center}
\end{itemize}

Dans l'exemple qui suit, le \tableau \verb=tab_ref= est construit
à partir du \vect \verb=vec_int= correspondant au
\champ \verb=this_champ=. Le \champ n'étant pas modifié,
les 2 fonctions précitées sont utilisées pour passer
du \vect au \champ et inversement.


\begin{exemple}{Utilisation d'un \champ existant non modifié\label{ex:champ.nonmod}}
ecs_tab_int_t
ecs_champ__ret_reference(ecs_champ_t  *this_champ,
                         size_t        nbr_ref)
\{
  ecs_tab_int_t  tab_ref;
  ecs_vec_int_t *vec_int;

  vec_int = ecs_champ__initialise_vec_int(this_champ);

  tab_ref = ecs_vec_int__ret_reference(vec_int, nbr_ref);

  ecs_champ__libere_vec_int(this_champ, vec_int);

  return tab_ref;
\}
\end{exemple}


\subsubsection{Utilisation d'un \champ existant à modifier\label{sec:champ.mod}}

Pour répercuter les modifications d'un \vect au \champ
qui lui est associé, on utilisera la fonction~:
\begin{center}
  \index{ecs_champ__transfere_vec_int@\verb=ecs_champ__transfere_vec_int=}
  \begin{alltt}
void
ecs_champ__transfere_vec_int(ecs_champ_t    *this_champ,
                             ecs_vec_int_t  *vec_int)
  \end{alltt}
\end{center}

où \verb=this_champ= est le \champ dans lequel le \vect sera transféré,
et \verb=vec_int= est le \vect à transférer.

Dans l'exemple ci-dessous,
le \vect initial correspondant au \champ \verb=this_champ=
est construit de la même manière que
précédemment avec la fonction \verb=ecs_champ__initialise_vec_int=\index{ecs_champ__initialise_vec_int@\verb=ecs_champ__initialise_vec_int=}.
Mais cette fois, il s'agit de répercuter
les modifications du contenu du \vect {\tt=vec\_int}
au \champ qui lui est associé.

\begin{exemple}{Utilisation d'un \champ existant à modifier\label{ex:champ.mod}}

void
ecs_champ__incremente_val(ecs_champ_t  *this_champ,
                          ecs_int_t     increment)
\{
  ecs_vec_int_t *vec_int;

  vec_int = ecs_champ__initialise_vec_int(this_champ);

  ecs_vec_int__incremente_val_sgn(vec_int, increment);

  ecs_champ__transfere_vec_int(this_champ, vec_int);
\}
\end{exemple}


\subsubsection{Création d'un champ\label{sec:champ.cree}}


\paragraph{Création d'un \champ à partir d'un \vect\label{sec:champ.cree.vect}}


On se place dans la situation où un nouveau \champ doit être créé
à partir d'un \vect.

Construire un \champ à partir d'un \vect nécessite d'utiliser la fonction~:
\begin{center}
  \index{ecs_champ__init_avec_vec_int@\verb=ecs_champ__init_avec_vec_int=}
  \begin{alltt}
ecs_champ_t * ecs_champ__init_avec_vec_int(ecs_vec_int_t  *vec_int,
                                           const char     *nom)
  \end{alltt}
\end{center}

qui retourne un \champ et prend pour arguments son nom et le \vect à partir
duquel il sera construit.

Une structure \champ contient plus d'informations
qu'une structure \vect, et cette dernière ne suffit donc pas à en
renseigner tous les membres.
La fonction \verb=ecs_champ__init_avec_vec_int= impose déjà de fournir
en supplément du \vect, le nom du champ. Les autres membres du \champ
sont initialisés à des valeurs indéfinies (les pointeurs sont à NULL).
Ces autres membres pourront être renseignés ultérieurement.

Dans l'exemple ci-dessous, le \fenv{statut} du \champ est renseigné
explicitement après la création du \champ.
Le \champ \verb=champ_connect_fac_som= ne sera pas rattaché à la structure
\maillage (ce qui nécessiterait un appel de fonction approprié),
les autres membres de la structure gardent
leur valeur d'initialisation donnée par
la fonction \verb=ecs_champ__init_avec_vec_int=.


\begin{exemple}{Création d'un \champ à partir d'un \vect\label{ex:champ.cree.vect}}
void
ecs_champ_def__decompose_cel(ecs_champ_t  *vect_champ_fac[],
                             ecs_champ_t  *champ_def_cel)
\{
  ecs_vec_int_t *vec_def_cel;
  ecs_vec_int_t *vec_def_fac;
  ecs_vec_int_t *vec_cel_def_fac;

  size_t nbr_fac;

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/

  /* Construction, pour les cellules,                             */
  /*  des vecteurs `ecs_vec_int_t' associés aux champs principaux */
  /*--------------------------------------------------------------*/

  vec_def_cel = ecs_champ__initialise_vec_int(champ_def_cel);

  ecs_vec_def__decompose_cel(&vec_def_fac,
                             &vec_cel_def_fac,
                             vec_def_cel);

  ecs_vec_int__detruit(vec_def_cel);

  ecs_champ__transfere_vec_int(champ_def_cel, vec_cel_def_fac);

  nbr_fac = ecs_vec_int__ret_pos_nbr(vec_def_fac) - 1;

  vect_champ_fac[ECS_CHAMP_DEF]
    = ecs_champ__init_avec_vec_int(vec_def_fac, ECS_CHAMP_NOM_DEFINIT);

  vect_champ_fac[ECS_CHAMP_DEF]->statut_e = ECS_CHAMP_STATUT_INDEFINI;
\}

\end{exemple}

%\vspace{2cm}

\paragraph{Création complète d'un \champ\label{sec:champ.cree.complet}}


Un \champ peut être aussi construit directement en renseignant
en argument les valeurs qui lui seront attribuées (la phase de
lecture d'un \maillage procède de cette façon)~:

\begin{center}
  \index{ecs_champ__cree@\verb=ecs_champ__cree=}
  \small
  \begin{alltt}
ecs_champ_t *
ecs_champ__cree(size_t               nbr_elt,
                const ecs_size_t     pas_pos,
                const ecs_size_t    *tab_pos,
                const void          *tab_val,
                ecs_type_t           typ_val_e,
                const char          *nom,
                ecs_descr_t         *descr,
                ECS_CHAMP_STATUT_E   statut_e)
  \end{alltt}
\end{center}

Dans l'exemple suivant, cette fonction est appelée pour construire
le \champdef des \soms après lecture d'un fichier de maillage.
les \tablposval sont des suites arithmétiques et
il est possible de renseigner directement les valeurs qui
seront attribuées au \champ~:

\begin{exemple}{Création complète d'un \champ\label{ex:champ.cree.complet}}

ecs_entmail_t *
ecs_entmail_pre__cree__som(size_t       nbr_som,
                           ecs_real_t  *som_val_coord)
\{
\(  /* Debut du corps de la fonction */\)

  champ_definit = ecs_champ__cree(nbr_som,
                                  3,
                                  NULL,
                                  som_val_coord,
                                  ECS_TYPE_ecs_real_t,
                                  ECS_CHAMP_NOM_DEFINIT,
                                  NULL,
                                  ECS_CHAMP_STATUT_HERITABLE);

\(  /* Suite du corps de la fonction */\)
\}
\end{exemple}


\subsubsection{Rattachement d'un champ à une \entite\label{sec:champ.rattache}}


Une fois le \champ créé, si c'est un champ qui doit appartenir
à la structure \maillage de base,
il doit être rattaché au pointeur sur le type de \champ correspondant
(\champdef ou listes chaînées \champatt).

On utilisera pour cela la fonction~:

\begin{center}
  \index{ecs_champ_chaine__ajoute@\verb=ecs_champ_chaine__ajoute=}
  \begin{alltt}
void
ecs_champ_chaine__ajoute(ecs_champ_t  **this_champ_tete,
                         ecs_champ_t   *champ_concat_tete)
  \end{alltt}
\end{center}

qui rajoute la liste chaînée à concaténer
(dont la tête de liste est \verb=champ_concat_tete=)
à la fin de la liste chaînée réceptrice (dont la tête de liste
est \verb=this_champ_tete=).


Dans l'exemple qui suit,
les \champs \couleur et \groupe sont construits à partir du \champfam.
Une fois construits, ils sont rattachés à la liste chaînée
des \champatts de l'\entite \verb=this_entmail=.

Cet exemple montre aussi comment rechercher un \champ particulier
dans une liste chaînée de \champs, à partir de son nom~:
le \champfam (de nom \verb=ECS_CHAMP_NOM_FAMILLE=)
est recherché parmi les \champatts grâce à la fonction~:

\begin{center}
  \index{ecs_champ_chaine__trouve_nom@\verb=ecs_champ_chaine__trouve_nom=}
  \begin{alltt}
ecs_champ_t *
ecs_champ_chaine__trouve_nom(ecs_champ_t  *this_champ_tete,
                             const char   *nom_champ)
  \end{alltt}
\end{center}

qui prend comme 1er argument la tête de la liste chaînée des \champs
dans laquelle est faite la recherche, et comme second argument,
le nom du champ à rechercher.
La fonction retourne le pointeur sur le \champ trouvé s'il existe
sinon elle retourne le pointeur NULL.

La fonction de suppression d'un champ d'une liste chaînée de \champs
est utilisée dans cet exemple, afin de supprimer parmi les \champatts,
le \champfam, une fois les \champs \couleur et \groupe construits.
Cette fonction a pour 1er argument le \champ à supprimer,
et pour second argument, la tête de la liste chaînée dans laquelle
le champ doit être supprimé~:

\begin{center}
  \index{ecs_champ_chaine__supprime@\verb=ecs_champ_chaine__supprime=}
  \begin{alltt}
void
ecs_champ_chaine__supprime(ecs_champ_t  **this_champ_noeud,
                           ecs_champ_t  **champ_tete)
  \end{alltt}
\end{center}

Le \champ ainsi supprimé
perd bien entendu son lien sur le \champ suivant qu'il avait
lorsqu'il appartenait à la liste chaînée (le lien sur le \champ
suivant est à mis à NULL, et l'ancienne valeur est affectée au \champ
suivant du \champ précédent celui qui est supprimé, afin de recomposer la liste).

Cette fonction se contente de retirer le \champ de la liste chaînée,
mais ne le détruit pas. Dans cet exemple,
le \champfam est détruit explicitement après avoir été
supprimé de la liste chaînée.



\begin{exemple}{Rattachement d'un \champ à une \entite\label{ex:champ.rattache}}

void
ecs_entmail_pcp__cree_attribut(ecs_entmail_t  *this_entmail,
                               ecs_famille_t  *famille)
\{
  ecs_champ_t *champ_couleur;
  ecs_champ_t *champ_famille;
  ecs_champ_t *champ_groupe;

  if (this_entmail->champ[ECS_CHAMP_ATT] != NULL)
    champ_famille = ecs_champ_chaine__trouve_nom
                      (this_entmail->champ[ECS_CHAMP_ATT],
                       ECS_CHAMP_NOM_FAMILLE);
  else
    champ_famille = NULL;

  if (champ_famille != NULL) \{

    /* Création des champs "couleur" et "groupe" */
    ecs_champ_att__cree_att_fam(champ_famille,
                                famille,
                                &champ_couleur,
                                &champ_groupe);

    /* Suppression de "famille" de la liste des champs "attribut" */
    ecs_champ_chaine__supprime(&champ_famille,
                               &this_entmail->champ[ECS_CHAMP_ATT]);

    /* Libération du champ "famille" */
    ecs_champ__detruit(champ_famille);

    /* Ajout de "couleur" et "groupe" à la liste des champs "attribut" */
    ecs_champ_chaine__ajoute(&this_entmail->champ[ECS_CHAMP_ATT],
                             champ_couleur) ;
    ecs_champ_chaine__ajoute(&this_entmail->champ[ECS_CHAMP_ATT],
                             champ_groupe) ;
  \}
\}
\end{exemple}


\subsection{Utilisation de la structure \vect\label{sec:util.vect}}


Dans la section précédente on a vu comment créer ou utiliser
un \vect à partir d'un \champ. Un cas d'utilisation de la structure
\vect n'a pas encore été décrit, qui ne met pas en jeu un \champ,
lorsqu'un \vect est utilisé simplement comme structure
de travail.
Deux fonctions seront utiles dans ce cas~:

\begin{itemize}
\item la fonction qui retourne un \vect en ayant alloué ses tableaux
  à partir des dimensions des tableaux des positions et des valeurs,
  données en argument~:
  \begin{center}
    \index{ecs_vec_int__alloue@\verb=ecs_vec_int__alloue=}
    \begin{alltt}
ecs_vec_int_t *
ecs_vec_int__alloue(size_t  pos_nbr,
                    size_t  val_nbr)
    \end{alltt}
  \end{center}
\item la fonction qui détruit un \vect (en ayant préalablement
  dés-alloué les tableaux des positions et des valeurs) et qui retourne
  un pointeur NULL~:
  \begin{center}
    \index{ecs_vec_int__detruit@\verb=ecs_vec_int__detruit=}
    \begin{alltt}
ecs_vec_int_t *
ecs_vec_int__detruit(ecs_vec_int_t  *this_vec_int)
    \end{alltt}
  \end{center}
\end{itemize}


\begin{exemple}{Utilisation d'un \vect de travail\label{ex:vect.trav}}
void
ecs_vec_int__transforme_pos(ecs_vec_int_t        *this_vec_int,
                            size_t                nbr_elt_ref,
                            const ecs_tab_int_t   vect_transf)
\{
  ecs_vec_int_t *vec_int_ref;
  size_t         nbr_val_ref;

  nbr_val_ref = ecs_vec_int__ret_val_nbr(this_vec_int);

  vec_int_ref = ecs_vec_int__alloue(nbr_elt_ref + 1,
                                    nbr_val_ref);

  \( /* Suite du corps de la fonction */ \)

  ecs_vec_int__detruit(vec_int_ref);
\}
\end{exemple}


De nombreuses fonctions de bas niveau permettent d'effectuer
des transformations sur une structure \vect (tri, renumérotation, etc.).
Les déclarations de ces fonctions sont rassemblées dans le fichier
\verb=ecs_vec_int.h= pour un \vectint et dans le fichier
\verb=ecs_vec_real.h= pour un \vectreal.


\passepage

