IDRIS - CNRS Cours IDRIS : langage C
Support de cours

20 janvier 1998 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Patrick Corde
Version PostScript disponible

Document réalisé à partir des transparents du cours "Langage C" de l'IDRIS.
Pour une impression correcte, utilisez la version PostScript.
TOC cours IDRIS F90


.

1 - Présentation du langage C

Retour début .

1.1 - Historique

Langage de programmation développé en 1970 par Dennie Ritchie aux Laboratoires Bell d'AT&T. Il est l'aboutissement de deux langages :

Il fut limité à l'usage interne de Bell jusqu'en 1978 date à laquelle Brian Kernighan et Dennie Ritchie publièrent les spécifications définitives du langage : << The C programming Language >>.

Au milieu des années 1980 la popularité du langage était établie. De nombreux compilateurs ont été écrits, mais comportant quelques incompatibilités portant atteinte à l'objectif de portabilité. Il s'est ensuivi un travail de normalisation effectué par le comité de normalisation X3J11 de l'ANSI qui a abouti en 1988 avec la parution par la suite du manuel : << The C programming Language - 2ème édition >>.

Retour début .

1.2 - Intérêts du langage

Retour début .

1.3 - Qualités attendues d'un programme

Retour début


.

2 - Généralités

Retour début .

2.1 - Jeu de caractères

Retour début .

2.2 - Identificateurs et mots-clés

Exemples

Retour début .

2.3 - Structure d'un programme C

Exemple :

#include 
#define  PI 3.14159
/*  calcul de la surface d'un cercle */
main()
{
  float rayon, surface;
  float calcul(float rayon);

  printf("Rayon = ? ");
  scanf("%f", &rayon);
  surface = calcul(rayon);
  printf("Surface = %f\n", surface);
}
/* définition de fonction */
float calcul(float r)
{
/* définition de la variable locale */
  float a;

  a = PI * r * r;
  return(a);
}

Retour début .

2.4 - Compilation et édition des liens

Le source d'une application écrite en langage C peut être stocké dans un ou plusieurs fichiers dont le suffixe est << .c >>
La compilation de ce source s'effectue à l'aide de la commande cc. Sans autre spécification, cette commande enchaîne 3 étapes :
  1. appel au pré-processeur (cpp),
  2. appel au compilateur,
  3. appel à l'éditeur de liens.

Cette commande admet plusieurs options telles :

Retour début


.

3 - Les déclarations

Retour début .

3.1 - Les types de base

Le langage contient des types de base qui sont les entiers, les réels simple et double précision et les caractères que l'on identifie à l'aide des mots-clés int, float, double et char respectivement.

De plus il existe un type ensemble vide : le type void.

Les mots-clés short et long permettent d'influer sur la taille mémoire des entiers et des réels.


Liste des différents types de base


SyntaxeType
voidensemble vide
charcaractère
short intentier court
intentier par défaut
long intentier long
floatréel simple précision
doubleréel double précision
long doubleréel précision étendue

Remarques

Les deux mots-clés unsigned et signed peuvent s'appliquer aux types caractère et entier pour indiquer si le bit de poids fort doit être considéré ou non comme un bit de signe. Les entiers sont signés par défaut, tandis que les caractères peuvent l'être ou pas suivant le compilateur utilisé.
Une déclaration telle que unsigned char permettra de désigner une quantité comprise entre 0 et 255, tandis que signed char désignera une quantité comprise entre -128 et +127.
De même unsigned long permettra de désigner une quantité comprise entre 0 et 232-1, et long une quantité comprise entre -231 et 231-1.

Exemple

#include <stdio.h>
unsigned char mask;
long          val;
main()
{
  unsigned int indice;
  float        x;
  double       y;
  char         c;
        ...
  return;
}
double f(double x)
{
  unsigned short taille;
  int            i;
  unsigned long  temps;
  double         y;
       ...
  return y;
}

Retour début .

3.2 - Les énumérations de constantes

Les énumérations sont des types définissant un ensemble de constantes qui portent un nom que l'on appelle énumérateur. Elles servent à rajouter du sens à de simples numéros, à définir des variables qui ne peuvent prendre leur valeur que dans un ensemble fini de valeurs possibles identifiées par un nom symbolique.

Syntaxe

enum [nom] {
   énumérateur1,
   énumérateur2,
   énumérateur3,
       ...
   énumérateurn
};

Les constantes figurant dans les énumérations ont une valeur entière affectée de façon automatique par le compilateur en partant de 0 par défaut et avec une progression de 1. Les valeurs initiales peuvent être forcées lors de la définition.

enum couleurs {noir, bleu, vert, rouge, blanc,
               jaune};
enum couleurs {
   noir = -1,
   bleu,
   vert,
   rouge = 5,
   blanc,
   jaune
};

Dans le 1er exemple, les valeurs générées par le compilateur seront :

noir0vert2blanc4
bleu1rouge3jaune5

et dans le 2e :

noir-1vert1blanc6
bleu0rouge5jaune7

Retour début .

3.3 - Les pointeurs

Un pointeur est une variable ou une constante dont la valeur est une adresse.

L'adresse d'un objet est indissociable de son type. On pourra se définir par exemple des pointeurs de caractères, des pointeurs d'entiers voire des pointeurs d'objets plus complexes.

L'opération fondamentale effectuée sur les pointeurs est l'indirection, c'est-à-dire l'évaluation de l'objet pointé. Le résultat de cette indirection dépend du type de l'objet pointé.

Par exemple si p_car et p_reel sont respectivement un pointeur de caractères et un pointeur de réel simple précision référençant la même adresse µ, une indirection effectuée sur p_car désignera le caractère situé à l'adresse µ, tandis qu'une indirection effectuée sur p_reel désignera le réel simple précision située à la même adresse.

Bien qu'ayant le même contenu (l'adresse µ), ces deux pointeurs ne sont pas identiques !

Retour début .

3.4 - Forme générale d'une déclaration

La forme générale d'une déclaration est la suivante :
< type >  < construction > [,< construction >,...];

où type est un type élémentaire (type de base, énumération de constantes) ou un type que l'on s'est défini, et construction est soit un identificateur soit un objet plus complexe construit à l'aide de constructeurs homogènes.

Retour début .

3.5 - Constructeurs homogènes

Des objets plus complexes peuvent être formés à l'aide des constructeurs homogènes :

Symboles associés aux constructeurs homogènes

SymboleObjet construit
*pointeur
[ ]vecteur
( )fonction

Exemple

   char     lignes[100];
   int     *p_entier;
   double   fonc();

Les déclarations précédentes permettent de définir respectivement :

Ces constructeurs peuvent se combiner entre eux, permettant ainsi de définir des objets encore plus complexes.

Exemple

   char    *chaines[100];
   int      mat[100][40];
   char   **argv;
Le constructeur homogène * est moins prioritaire que les deux autres. De ce fait, les déclarations précédentes permettent de définir respectivement :

L'utilisation de parenthèses permet de modifier la priorité et donc l'ordre d'évaluation.

Exemple

   int    (*tab)[10];
   char   (*f)();
   char   *(*g)();
   float  *(*tabf[20])();
Cet exemple permet de définir respectivement :

Retour début .

3.6 - Constructeurs hétérogènes

Les constructeurs hétérogènes permettent de définir des objets renfermant des entités de nature différente.

Il en existe 3 :

Les structures permettent de regrouper des objets dont les types peuvent être différents.

Syntaxe

     struct [ nom ] {
        < liste de déclarations >
     };
     
Les objets regroupés sont les membres ou composantes de la structure les contenant.

Remarques

Exemple

     struct {
         char         c;
         unsigned int i;
         float        tab[10];
         char        *p;
MMΰ
==ÏŸ>=
ÿ¯³ Default 	²²²  	²²²0 	ÿÿÿ@ 02A 0GP 0R 0S 0¡„ 0Š Œ ‡ 
€?
€?@öBox01AêA¨8ï_F@ê@×ÀWpÂH�„?`I×ÀPpÂR¡ƒ¿ÙQ×ÀKpÂöèEÀPZ×ÀCpÂ"‘�A$NAgÄŸÁ¼µ�?±ÒÀn% Á;¬Ž¿,ºÒÀ^% Á¢�ÁWýAißÁX Aî;â½óB»nU@
é½-óBë;UÀ,èï½CóB¥ùÁJ¾ö½XóBì;-=16"ÁãoBZµ˜<=6"ÁãoB’6¤»J6"Á
ãoB#Ðê¼V6"Á
ãoBº’F@“²NÁÏ%pÂÞô„?ͶNÁÈ%p¼;ƒ¿
»NÁÃ%pÂ+¶EÀF¿NÁ»%p‰¹�AÆíÁq¯ ÁÙ#�?½TÁwM Á>Ž¿µÁTÁjM Áªy�Á,4íÁs® Á\/ A
â Áp·BËV@åè Á„·BÜ—TÀ»ï Á›·B¡ÐÁ‘ö Á¯·B-a-=ÓX#ÁÕâoBÛÿ˜<áX#ÁÕâoBŽ£»ìX#ÁÕâoB¢…ê¼úX#ÁÕâoBÝpF@¦ÁpÂ%±„?ºªÁxpÂuƒ¿ö®ÁspÂ	ØEÀ2³ÁkpÂÄtVÀá-
Áª2 ÁùëÁ0ÙÀvßBM·ê¼7—"ÁøâoB<Ó£»+—"ÁùâoB0Θ<—"ÁùâoBWH-=—"ÁùâoB AÞØÀ5ßB:W@ 
ÁÔ2 ÁÌ�F@ˆ¬-Á§pÂÓ„?İ-Á p˜]ƒ¿þ´-Á›pÂÇEÀ;¹-Á“pÂkbVÀú0Á@ ÁMÞÁ•BWÁ“ËBwžê¼ø"ÁçâoBåo£»ø"ÁçâoBç˜<ø"ÁçâoBÂT-=ô÷"ÁçâoB°! A�WÁQËB“0W@Rì0Á.@ Á`A6þÿ¿OBº xN7ðf7tå>»¹ÿ?Â?º·ÿ?å>;oƒ:oƒ:oƒ: Al			



	

	
	

! !"!"#"#! -,- "!.-.!#"/./"-,,.--/..$#$%$%&%&$#0/0#%$101$&%212%0//100211'&'
('(
)()
'&323&('434')(545(322433544*)*+*+ + *)656)+*767* +,7,+655766,770AèDefaultl	

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkPA¶                  @@@@@@@@@@@@@@@@@@@öBox02AêA¨89ÎEÀž‰âÀ4ìoBÜkƒ¿(�âÀ-ìoB¾Ä„?±xâÀ'ìoB¬zF@:pâÀ"ìoBð �Á% A5< AsšŽ¿›tÖÀAÚŸAƒÇ�?okÖÀ3ÚŸAC’�AæpA>; AþÁ‰Ræ=ñÂÅMUÀž'í=!ñÂâ\U@³üó=6ñÂã AÈÑú=KñÂ9ø¼­žÁnpÂÚÙ»¢žÁnpÂ{L‹<”žÁnpÂ}‡&=‰žÁnpÂv›EÀíVTÁ¼ÙoBWƒ¿²RTÁ·ÙoBD*…?vNTÁ¯ÙoBo­F@:JTÁªÙoB�x�ÁÆ"îÁ0QŸAe,Ž¿ížVÁ9²ŸA‘5�?WšVÁ+²ŸA¢º�AeúíÁ9PŸAÕÁ€ŸÁ±, ÂΩTÀ«ŸÁÆ, ÂÙV@ÖŸÁÛ, Âà* AŸÁð, ÂŒî÷¼RÁÁ¤pÂ8°Ø»DÁÁ¦pÂñ–‹<9ÁÁ¦p¸¬&=-ÁÁ¦pÂM½EÀ×JÁæoBJƒ¿œFÁæoB•æ„?aBÁÿåoB™‹F@&>ÁúåoB'W@VýÁÎÌŸAŽ AÐiÑÀ, Âæ“&=jÿÁ‚pÂMe‹;¹ÿ¿ä+º·ÿ?á>;oƒ:oƒ:oƒ: Al			



	

	
	

! !"!"#"#! -,- "!.-.!#"/./"-,,.--/..$#$%$%&%&$#0/0#%$101$&%212%0//100211'&'
('(
)()
'&323&('434')(545(322433544*)*+*+ + *)656)+*767* +,7,+655766,770AèDefaultl	

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkPA¶                  @@@@@@@@@@@@@@@@@@@p-Torus01Ab-Aˆ
 ��Ñ=†JÃèÀ¿o�Ð=¼lIÃ{¶]@�›Í=ôwFÓÎ@¸|É=ùkBÃñ@”NÅ=]^>ÃÞÂÎ@á/Â=,e;ÃT`@ŸöÀ=VL:ÃG¬
¿ÀöÁ= _;Ãä“À¡ëÄ=èS>Ã9/òÀv
É=ã_BÃÞ¤
Á™8Í=~mFÂðòÀNWÐ=°fIëW”Àv?QÂןCÃtr¿V PÂz–BÃG_@MÂx»?Ãü§Î@�àH¬Ò;ÿñ@B±DÂDè7Ã|bÏ@¡AÂÓ5ÃRŽa@ü�@Âmù3ÀÊ¿¡AÂÉ5ÃÂk’Àt±DÂÌÝ7Ù�ñÀÖàH˜Æ;Ã]S
Á1M±?ÃJòÀs PÂq�BÃÄ®“À�RÊÂGk/Ã6¿ô<ɤ}.Ã&Òb@šFÆÂ\î+ÃÊ…Ð@²:ÂÂm(Ã&“ó@Í.¾Âê$ÃÆ,Ñ@}8»ÂZV"äe@ò"ºÂ®b!ÃJŒï¾Œ8»ÂRP"Ú¨�Àæ.¾Â˜ß$ÃOÅïÀÎ:ÂÂð`(ÃWi	Á³FÆÂæã+ÃMlðÀ=É›w.ÃÕÉ‘ÀÐÃWBÃ+Ô¾uYÃÓ€ÃÒh@AÃjÃizÓ@Cd	Ãf�	ÃWxö@�‡Ã¯Ã…Ô@oÃî“©j@ĪÃ_ÌÃ'þ oÃä�Ã*Þ�Àއâ¤Ã�ïìÀRd	ÃQ�	ÿöÁAà_ìwíÀ|YÃÈzÃçÉŽÀ†Q/Ã2¬Ê§k•¾þ`.Ã.œÉÂ*Ÿp@ÞÏ+Ãö¨ÆÂLR×@:N(ÃâœÂÂ$<ú@˜Ì$Ã’�¾Â>²×@~;"Ã�‘»Â’ëq@ûJ!ÃjuºÂ m‰¾…;"Ãn…»Â#=ŠÀ¤Ì$æx¾Â×?éÀHN(ú„ÂÂ×ÁêÏ+Ã
”ÆÂÉŸéÀa.Ã�ÉÂQãŠÀŸ’CîRÂ÷è¾L†BÞóPÂ�±y@B©?Ã=éMÂdÊÛ@ê¿;ùIÂäœþ@•Ö7Ã}‚E¦ûÛ@�ù4ÃkfBÂ0\z@Dí3Ã0:A–˜¾—ù4Ã@NBÂÔ†À¡Ö7ãXEÂoöäÀø¿;ÃňIÂwäÁN©?Ãb¿M±'åÀS†BÃvÛP Z†À½JÃEwͽ,¹`;éiIÃëƒä½pµ�@êrFÃ*ó½¼”à@fBÃ}õ½§APY>Ã.Ýê½ð“à@Vb;Ãi#Ö½´�@ŠL:Ãcݼ½"ñS;]b;üХ½Û~�À\Y>Ê*—½%^àÀ*fBèה½Ð‹ÁörFÃ{wŸ½Y]àÀñiIÃ?1´½v}�À CÃJAQB\Ã>§“BÃ"PBÁ�†@j¶?ÃýLBÁ]å@ÎÌ;ÃfÊHBÿA4ã7ÃDžDBò*å@ü5ÃÑ–ABÆ8†@Ÿù3ÃÔƒ@B3>5Ãû®ABJôyÀ@ã7ÃÈDB#ÇÛÀÜÌ;÷úHBœgþÀv¶?ÃÚ&MBT”ÛÀ®“BÃL.PBKDyÀvk/Ã]SÊB<™˜>Êz.ÃÁ7ÉBÿ‹@Ié+Ã=ÆBõÑé@!g(Ã}/ÂB”-Aùä$Ã6%¾Bœpé@~S"ÃN3»BfmŠ@Øb!ÃÅ#ºBinŒ>…S"Ãa?»B‹qÀå$Ã!:¾By�×À/g(Ã¥GÂB­
úÀUé+ÃíQÆB  ×ÀÑz.ÃÕCÉBÓ9pÀ~BÃ+C}óÖ>ñ}ÃÏVCIöŽ@údÃ/<C¥£í@z‡	Ã�^	CrAü©ê‚Cfí@
‘ÃulC“Ž@ƒÌÃ$«C¯ËÅ>‘ÃrC®TjÀªà �C±×ÓÀˆ‡	ój	CñLöÀeÃ¥FCpNÓÀø}ÃÙ\C;yhÀg¬ÊÂÛQ/CSX?S–ÉÂQ^.Cî‘@¨žÆÂýÊ+C1�ð@ó�ÂÂŒH(C{	ABƒ¾Â¹Ç$Cdèï@¢‹»ÂÒ8"CcË�@œuºÂTK!C'·ñ>°‹»ÂÝ>"CÏdÀ[ƒ¾Â/Ò$C±	ÑÀ‘¡T(C¬oóÀÁžÆÂsÕ+CæaÐÀa–ÉÂZd.CljbÀäRÂí’CCíG?±çP™ƒBChÉ“@kÔMÂ\¤?C•dò@¡IÂ6º;C`
A©mE°Ñ7Cª©ñ@yZBÂßö4Cª…’@a:A—í3CI™?•ZBÂêü4C‚ZaÀÛmEÂ(Ü7ClHÏÀ?¡IÂLÆ;CפñÀ�ÔMÂÑ®?C€�ÎÀÍçP¢‰BCÓ^À´nͽ	€JCûC?5̽3gICh”@íɽnFCæó@úèĽf`BC­
ATÊÀ½kT>C˜?ò@•Õ½½¤_;CD“@�Õ¼½ÙL:CB/?·¾½¯e;CO3`ÀG-Á½à^>C}²ÎÀ<[Ž|lBCµñÀáyɽwxFC/ñÍÀ n̽?mIC²•]À‡AQBY CC…õ?„"PBô�BC*¿“@BMB„±?C}Zò@çâHBÇ;CŽ[
A…³DBOÞ7CúŸñ@.£ABL5C"|’@
„@Bðù3CzM?£ABV	5C’maÀS³DBÇè7CRÏÀ®âHB/Ó;Cº®ñÀMBû»?C™—ÎÀg"PBý–BC|ç^À–SÊBÉk/C#¹?>ÉBx.C9Ú‘@¼GÆBiä+C±|ð@×;ÂBra(Cˆq	Aî/¾Bà$C®Õï@“9»BÓP"Cú¸�@û#ºB/c!C=’ð>…9»BÝV"CäódÀÕ/¾B‘ê$CgÑÀº;ÂB‡m(CÆ‚óÀ£GÆBÞî+CfuÐÀý=ÉB&~.C[±bÀTCÙBC<1Õ>ZCK{CMÚŽ@˜AC!`Cˆí@Öd	CÔ�	CðþAˆC&¥Còÿì@£oCfŽCŠî�@H«CãÌCs-Ä>œoCq”CĈjÀˆC›¯C#òÓÀÇd	Cè�	CõgöÀ‹AC—jCjÓÀùYCV�C5±hÀ
R/C5­ÊBÊq–>‰a.C‘ÉB·óŠ@nÐ+C
•ÆB.°é@ÌN(C½…ÂBA(Í$Cªy¾B8Pé@<"Cq†»B‚MŠ@K!CpvºBsŠ><"C‡’»BÑÊqÀÍ$C˜Ž¾Bß¡×À¾N(Cè�ÂBÃ+úÀbÐ+Cú©ÆBèA×À‚a.C4�ÉBc~pÀ"“CCµ	RB>õ>׆BC|ÝPB†j†@Ò©?CkÁMB8å@|À;CΊIB¨ìA%×7C«ZEBÑå@ú4CIPBB3†@Èí3C7ú4CqhBBo;zÀ×7C„„EBDëÛÀnÀ;C »IB�ŒþÀÆ©?CCëMBºÛÀІBC¥õPBÅ�yÀ@€JC‘†Ñ=4O»ºtjIC–@¸=Ü��@ysFCö†£=½mà@­fBCSç˜=”AàY>Cd:›=‡nà@àb;Cºà©=<��@
M:ClíÀ=ƒî¡ºÙb;Cg3Ú=°£�ÀÓY>Cíî=ŽƒàÀŸfBC«Œù=êžÁmsFC™9÷=X„àÀljICC“è=
¥�À� CCA?Q·¾1”BCD,PÂey@ù¶?CÑ$M¸¤Û@_Í;C±øHÂþwþ@Ãã7CÆD„×Û@†5Cò¬AÂz@"ú3CË�@ÂK¾5CÉ”AÂe(†À·ã7C>œD“åÀQÍ;C]ÈHÂìöÁí¶?C÷úLÂ]MåÀ*”BCPÂ]€†Àùk/CWRÊ“—¾T{.CÑBÉ›Zp@×é+CèPÆÂ„0×@±g(C¢FÂÂú@ˆå$C9¾ÂÚ‘×@T"C\>»ÂÉ«q@Zc!CÂ"ºÂuh‹¾T"CG2»Â]ŠÀ|å$C0$¾Â=`éÀ£g(Cw.ÂÂb%ÁËé+Cû;ÆÂ‘ÁéÀM{.C»6É™‹ÀCC©ÃYíÕ¾z~CX\Úh@‰eC#FÃÕ^Ó@ˆ	C0j	ÃS]ö@‹ªCžŒÃèÓ@“‘CýqÃouj@ÍC¡ªûÅľ�‘CôkÃ3ø�À~ªC)‚Ã
íÀü‡	C^	ÃAÁ|eC¬;Ã@“íÀs~CLVÃæåŽÀk­ÊBXQ/ÃAÕ¿e—ÉB×c.Ã�ªb@ÅŸÆBðÔ+ÃHrÐ@’ÂBT(Àó@`„¾B¬Ñ$ÃÑ@µŒ»BZ>"ÃÐïd@ vºBÐJ!Ã1±ð¾¦Œ»BP8"û�ÀG„¾B6Ç$ÃØïÀø‘ÂB	H(Ãär	Á¬ŸÆBzÊ+ÃÍðÀX—ÉBÎ].ßݑÀí	RBi’CÃÛÄ¿ÕéPB ‰BÃÉó^@¤ÖMBP®?Ãä�Î@G£IBÈÅ;Ã9µñ@ãoEB¤Û7ÃÍXÏ@�\BBgü4ÃC{a@i=12>2?>23?3@?34@4A@45A5BA56B6CB67C7DC78D8ED89E9FE9:F:GF:;G;<G;0<<IH<=I=JI=>J>KJ>?K?LK?@L@ML@AMANMABNBONBCOCPOCDPDQPDEQERQEFRFSRFGSGHSG<HHUTHIUIVUIJVJWVJKWKXWKLXLYXLMYMZYMNZN[ZNO[O\[OP\P]\PQ]Q^]QR^R_^RS_ST_SHTTa`TUaUbaUVbVcbVWcWdcWXdXedXYeYfeYZfZgfZ[g[hg[\h\ih\]i]ji]^j^kj^_k_`k_T``ml`amanmabnbonbcocpocdpdqpdeqerqefrfsrfgsgtsghthuthiuivuijvjwvjkwklwk`llyxlmymzymnzn{zno{o|{op|p}|pq}q~}qr~r~rss€st€t�€tu�u‚�uv‚vƒ‚vwƒwxƒwlxx…„xy…y†…yz†z‡†z{‡{ˆ‡{|ˆ|‰ˆ|}‰}Љ}~Š~‹Š~‹Œ‹€Œ€�Œ€���Ž��‚Ž‚�Ž‚ƒ�ƒ„�ƒx„„‘�„…‘…’‘…†’†“’†‡“‡”“‡ˆ”ˆ•”ˆ‰•‰–•‰Š–Š—–Š‹—‹˜—‹Œ˜Œ™˜Œ�™�š™�ŽšŽ›šŽ�›��›�„���œ�‘�‘ž�‘’ž’Ÿž’“Ÿ“ Ÿ“” ”¡ ”•¡•¢¡•–¢–£¢–—£—¤£—˜¤˜¥¤˜™¥™¦¥™š¦š§¦š›§›œ§›�œœ©¨œ�©�ª©�žªž«ªžŸ«Ÿ¬«Ÿ ¬ ­¬ ¡­¡®­¡¢®¢¯®¢£¯£°¯£¤°¤±°¤¥±¥²±¥¦²¦³²¦§³§¨³§œ¨¨µ´¨©µ©¶µ©ª¶ª·¶ª«·«¸·«¬¸¬¹¸¬­¹­º¹­®º®»º®¯»¯¼»¯°¼°½¼°±½±¾½±²¾²¿¾²³¿³´¿³¨´´ÁÀ´µÁµÂÁµ¶Â¶Ã¶·Ã·Ä÷¸Ä¸Åĸ¹Å¹ÆÅ¹ºÆºÇƺ»Ç»ÈÇ»¼È¼Éȼ½É½Êɽ¾Ê¾Ëʾ¿Ë¿ÀË¿´ÀÀÍÌÀÁÍÁÎÍÁÂÎÂÏÎÂÃÏÃÐÏÃÄÐÄÑÐÄÅÑÅÒÑÅÆÒÆÓÒÆÇÓÇÔÓÇÈÔÈÕÔÈÉÕÉÖÕÉÊÖÊ×ÖÊË×ËÌ×ËÀÌÌÙØÌÍÙÍÚÙÍÎÚÎÛÚÎÏÛÏÜÛÏÐÜÐÝÜÐÑÝÑÞÝÑÒÞÒßÞÒÓßÓàßÓÔàÔáàÔÕáÕâáÕÖâÖãâÖ×ãרã×ÌØØåäØÙåÙæåÙÚæÚçæÚÛçÛèçÛÜèÜéèÜÝéÝêéÝÞêÞëêÞßëßìëßàìàíìàáíáîíáâîâïîâãïãäïãØääñðäåñåòñåæòæóòæçóçôóçèôèõôèéõéöõéêöê÷öêë÷ëø÷ëìøìùøìíùíúùíîúîûúîïûïðûïäððýüðñýñþýñòþòÿþòóÿóÿóôôôõõõööö÷÷÷øøøùùùúúúûûüûðüü	üý	ý
	ýþ
þ
þÿÿÿ


ü			





		
	

0A�Default@	

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ	

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ	

 !"#$%&'()*+,-./0123456789:;<=>?PA	@öBox03AêA¨8_BBPÍ�AC=‹�A¬�AŸ—D=&¨�ÁçŠ�A$/F=«mB³i�AªÆG=¦dBBœ­@"G„<–�A6­@,v‡<��Ág’¬@6¥Š<#hB˜
¬@@Ô�¬�Aφ�Áþý=½ó†�Á¨�Áyf<½]BÂ6É�ÁóÎ:½¬^BB™Ž‚AµhÂ'Š�Afm‚AOhÂ
©�Á3L‚AêgÂnBÂþ*‚A„gÂ4dBB0¡°@ìˆÂ8•�Aa°@‡ˆÂù��Á‘—¯@!ˆ•hB¯@»‡½iBBø¨À$©ÂI �A×|©À¾¨Âè’�Á¦ªÀX¨ÂcBÂu†ªÀò§ÂEoBBP¤€Á[ÉÂZ«�A…Å€ÁõÈÂׇ�Á¸æ€Á�È„]BÂë�Á(ÈÂø^BB½
‚A›	,Á¿Š�A‰ì�A,Ár¨�ÁUË�Al,ÁÑmBÂ"ª�AÖ,ÁIhBÂP­@±…,ÁÀbBÂ牬À�-Á8]BÂɈ�Áj‡-Á?‡�Á”g�Á‰-Áò«�A`F�Á™Š-Á‘oBB-%�Á2Œ-Á	jBB|ûªÀT-Á€dBB»�®@yŠ,ÁÒ^BB+N‚Ak¬ÁsŠ�A÷,‚APj¬Á¾¨�ÁÄ‚A…i¬Á÷mB‘ê�A¹h¬ÁohBÂ	®@&©¬ÁæbBÂ.ˆ«À•é¬Á^]BÂZH�Á*­Á‹‡�Á''�ÁÏ*­Á¦«�Aò�Áš+­ÁkoBB¾ä€Áf,­ÁãiBBÃù©Àùë¬ÁZdBBtŸ¯@Š«¬Á`A6'\Ï¿†~Tº£7€zT:î[Ï¿?¢š»ŸÐ¶7)¢š»ï[Ï?oƒ:oƒ:oƒ: Al			



	

	
	

! !"!"#"#! -,- "!.-.!#"/./"-,,.--/..$#$%$%&%&$#0/0#%$101$&%212%0//100211'&'
('(
)()
'&323&('434')(545(322433544*)*+*+ + *)656)+*767* +,7,+655766,770AèDefaultl	

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkPA¶                  @@@@@@@@@@@@@@@@@@@öBox04AêA¨8_BBPÍ�AC=‹�A¬�AŸ—D=&¨�ÁçŠ�A$/F=«mB³i�AªÆG=¦dBBœ­@"G„<–�A6­@,v‡<��Ág’¬@6¥Š<#hB˜
¬@@Ô�¬�Aφ�Áþý=½ó†�Á¨�Áyf<½]BÂ6É�ÁóÎ:½¬^BB™Ž‚AµhÂ'Š�Afm‚AOhÂ
©�Á3L‚AêgÂnBÂþ*‚A„gÂ4dBB0¡°@ìˆÂ8•�Aa°@‡ˆÂù��Á‘—¯@!ˆ•hB¯@»‡½iBBø¨À$©ÂI �A×|©À¾¨Âè’�Á¦ªÀX¨ÂcBÂu†ªÀò§ÂEoBBP¤€Á[ÉÂZ«�A…Å€ÁõÈÂׇ�Á¸æ€Á�È„]BÂë�Á(ÈÂø^BB½
‚A›	,Á¿Š�A‰ì�A,Ár¨�ÁUË�Al,ÁÑmBÂ"ª�AÖ,ÁIhBÂP­@±…,ÁÀbBÂ牬À�-Á8]BÂɈ�Áj‡-Á?‡�Á”g�Á‰-Áò«�A`F�Á™Š-Á‘oBB-%�Á2Œ-Á	jBB|ûªÀT-Á€dBB»�®@yŠ,ÁÒ^BB+N‚Ak¬ÁsŠ�A÷,‚APj¬Á¾¨�ÁÄ‚A…i¬Á÷mB‘ê�A¹h¬ÁohBÂ	®@&©¬ÁæbBÂ.ˆ«À•é¬Á^]BÂZH�Á*­Á‹‡�Á''�ÁÏ*­Á¦«�Aò�Áš+­ÁkoBB¾ä€Áf,­ÁãiBBÃù©Àùë¬ÁZdBBtŸ¯@Š«¬Á`A6'\Ï¿†~Tº£7€zT:î[Ï¿?¢š»ŸÐ¶7)¢š»ï[Ï?oƒ:oƒ:oƒ: Al			



	

	
	

! !"!"#"#! -,- "!.-.!#"/./"-,,.--/..$#$%$%&%&$#0/0#%$101$&%212%0//100211'&'
('(
)()
'&323&('434')(545(322433544*)*+*+ + *)656)+*767* +,7,+655766,770AèDefaultl	

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkPA¶                  @@@@@@@@@@@@@@@@@@@öBox05AêA¨8y,…Á	ÌABDÅ>@È‚Áûg€AuD=d€ÁÈ‚Á">½žÿ{ÁüBÂï*¾»À2BB?ë>,‹±À4�AfE=Iú§À	ü�Á0~=½fižÀ–BÂñ¾Çyž@˜BB<>ª
¨@!‚AX¯E=�›±@ö/�Á?æ<½o,»@0BÂõÞ¾Ï|A&þBB87> h€A4Ì‚AIGF=YÌ‚Aãc€ÁNN<½’0…AýÉAÂù¸¾^-…Á¯,BB¯Â%É‚ÁF)�AVhÂìd€ÁÑ‚ÁûÈÂg|Át›BŸ)¡»À¸’BB‰Â¿Ž±ÀYõ�A0hÂÜý§À¾:�ÁÕÈÂùlžÀj5BÂz)Â5vž@ÂøBBc¨@lÁ‚A
hÂú—±@«n€Á¯ÈÂÝ(»@aÏAÂT)Â|AË^CB=»ÀJRBBî„*Á-…ÁwBB©«ÁÙÈ‚ÁØè€A\j¬Á d€Á?G‚Á¦+­ÁÏ|Á«»BÂñì­ÁÈkžÀ¢UBÂ¥ì­Á*»@˜ïAÂYì­Áù/…A�‰AÂ
ì­ÁÁË‚A
ÆÁÃ*­Áˆg€AMƒAyi¬Áž|A”>CB.¨«Ágwž@ŠØBBz¨«Áo»À�rBBƨ«Á`A6zãt<¬YÏ¿=¢š»çYÏ?zãt<¨T¶7éê¶7;¢š»ï[Ï?oƒ:oƒ:oƒ: Al			



	

	
	

! !"!"#"#! -,- "!.-.!#"/./"-,,.--/..$#$%$%&%&$#0/0#%$101$&%212%0//100211'&'
('(
)()
'&323&('434')(545(322433544*)*+*+ + *)656)+*767* +,7,+655766,770AèDefaultl	

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkPA¶                  @@@@@@@@@@@@@@@@@@@öBox06AêA¨8y,…Á	ÌABDÅ>@È‚Áûg€AuD=d€ÁÈ‚Á">½žÿ{ÁüBÂï*¾»À2BB?ë>,‹±À4�AfE=Iú§À	ü�Á0~=½fižÀ–BÂñ¾Çyž@˜BB<>ª
¨@!‚AX¯E=�›±@ö/�Á?æ<½o,»@0BÂõÞ¾Ï|A&þBB87> h€A4Ì‚AIGF=YÌ‚Aãc€ÁNN<½’0…AýÉAÂù¸¾^-…Á¯,BB¯Â%É‚ÁF)�AVhÂìd€ÁÑ‚ÁûÈÂg|Át›BŸ)¡»À¸’BB‰Â¿Ž±ÀYõ�A0hÂÜý§À¾:�ÁÕÈÂùlžÀj5BÂz)Â5vž@ÂøBBc¨@lÁ‚A
hÂú—±@«n€Á¯ÈÂÝ(»@aÏAÂT)Â|AË^CB=»ÀJRBBî„*Á-…ÁwBB©«ÁÙÈ‚ÁØè€A\j¬Á d€Á?G‚Á¦+­ÁÏ|Á«»BÂñì­ÁÈkžÀ¢UBÂ¥ì­Á*»@˜ïAÂYì­Áù/…A�‰AÂ
ì­ÁÁË‚A
ÆÁÃ*­Áˆg€AMƒAyi¬Áž|A”>CB.¨«Ágwž@ŠØBBz¨«Áo»À�rBBƨ«Á`A6zãt<¬YÏ¿=¢š»çYÏ?zãt<¨T¶7éê¶7;¢š»ï[Ï?oƒ:oƒ:oƒ: Al			



	

	
	

! !"!"#"#! -,- "!.-.!#"/./"-,,.--/..$#$%$%&%&$#0/0#%$101$&%212%0//100211'&'
('(
)()
'&323&('434')(545(322433544*)*+*+ + *)656)+*767* +,7,+655766,770AèDefaultl	

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkPA¶                  @@@@@@@@@@@@@@@@@@@öBox07AêA¨8˜pB%9ÜÀ<ßD@‘pBåÜÀ*Ž�?‹pB£ÖÛÀ*¢†¿‚pBd¥ÛÀ?iGÀ£øŸAuAÙÔ�Aà A�[ÔÀ‚ÏŒ?РA&ÔÀ(’‘¿‹÷ŸA/KA^�Á3ñÂ14E½é AKñÂaSë¼jmU@bñÂÂ|¼É;¹ÿ¿þÿ¿=ºK7<º·ÿ?æ>;oƒ:oƒ:oƒ: Al			



	

	
	

! !"!"#"#! -,- "!.-.!#"/./"-,,.--/..$#$%$%&%&$#0/0#%$101$&%212%0//100211'&'
('(
)()
'&323&('434')(545(322433544*)*+*+ + *)656)+*767* +,7,+655766,770AèDefaultl	

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkPA¶                  @@@@@@@@@@@@@@@@@@@öBox08AêA¨8xûoÂr‘ÝÀ®QGÀqûo²ÂÝÀs†¿kûoÂóóÝÀG½�?bûoÂ6%ÞÀÏöD@k Á0ùA]�Á(÷ŸÁ ÊÔÀx‚‘¿÷ŸÁ†ÿÔÀ3ߌ?X Á#AØÕ�A@óBúdM=®ýÁWóB
²û<…LUÀpóB>49<³]U@†óB™û¼ú ApBûîÁR…ƒ½!pBCïÁ)&½!pB�ïÁ4�м!pBÕïÁ_ÈÜ;MøoÂ×ÚQÁ5yHÀDøoÂvóQÁˆ¿=øoÂRÁsÜ~?6øo¹$RÁHÏC@	àŸÁ@6íÁHžÁGðŸÁ®ÉUÁ,”¿7ðŸÁ`äUÁ}^Š?öÞŸÁQ!îÁÉêœA€ýB™ŸÁSì Á—ýBåÀŸÁYÀ®ýB«èŸÁ&£Q@ÆýBq ÁWA)pB  Á²ñƒ½)pBç Á>'½)pB/ Á°AŒ¼)pBw ÁkÖ;iúoÂÂÎÁ0´GÀbúoÂdçÁ8‡¿[úoÂÁCø€?UúoÂ¥ÁK”D@¾ôŸÁ¨fÁ«5U@ðöB•—ÕÀn²A#pB¶PÁf†Ú;#pBlPÁ² ‹¼$pB$PÁ¿q&½$pBÜOÁr©ƒ½¬öBOºÓÀ:M ÁîôŸÁ“Áá\XÀZùoÂËÔ0Á´HÀSùoÂlí0Áý‡¿LùoÂ1Á>3€?Eùo­1ÁÉ1D@tòŸÁÝ22ÁâÊT@[úBVvUÁãbA&pB˜±ÁfDØ;&pBN±Á2±‹¼&pB±Áþ¹&½'pB¿°Á’̓½úB´‡TÁÆœ Á¡òŸÁÆâ1Á¨ÇXÀ`A6”ƒ_7€é>»ºÿ?þÿ?2:€G·2º¶ÿ?é>;oƒ:oƒ:oƒ: Al			



	

	
	

! !"!"#"#! -,- "!.-.!#"/./"-,,.--/..$#$%$%&%&$#0/0#%$101$&%212%0//100211'&'
('(
)()
'&323&('434')(545(322433544*)*+*+ + *)656)+*767* +,7,+655766,770AèDefaultl	

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkPA¶                  @@@@@@@@@@@@@@@@@@@öBox09AêA¨85Ü@ûoB×bQ@üÿÛ@7pB_•š?ÄÿÛ@_pBè5[¿‰ÿÛ@†
pB£å:ÀWÁc‚ŸAžA‰QÔ@ AÄ–?KQÔ@Y Aš�‡¿.YÁpm AÕ�Á�B­<ÿ ÂÒ&Aó‰¬<ûÂñM@VÑ«<8ç¹\À¸«¾ÏíA}ùoÂüeV¾TQA<þoB£aQ@7QAdpBø’š?QAŒ
pB³:[¿þQA´pB׿:Àª‡íAʪŸAžA��UAâ AvÁ–?b�UA; A3 ‡¿™†íAו AÉ �ÁO+ A¾ ÂÚ%A!+ AÚðÂ9íM@ó* A÷ÜÂú¼\ÀÅ* AÉÂÍÙ!Át!AªùoÂI½
¾u!A˜ùoÂ’õ%¾s!A†ùoÂë->¾s!AtùoÂ5fV¾-AüoBobQ@AFpB‘”š?ôAnpB�7[¿×A–pB	æ:ÀÄô
Aü ASÀlÖ@êÏÂ&Ù!Á°N AzùoÂfV¾°N AŒùoÂÆ->¾²N A ùoÂmõ%¾±N A²ùoÂ$½
¾–Ö@” €&A!õ
AñöŸAr’Z@@0A-ýoB	bQ@#0AUpBÆ“š?0A}	pB9[¿ê0A¥pBoæ:ÀÁ1AG! A…SÀàªUAÌÂyÙ!Á’¯ AwùoÂ"fV¾’¯ A‰ùoÂÙ->¾”¯ A›ùoÂõ%¾“¯ A­ùoÂ6½
¾õ«UA) Â-&A`Á1A<ùŸA’Z@`A6³‰]·,ç>;¸ÿ¿
?:¶ÿ¿Fç>»þÿ¿zAºÄF7oƒ:oƒ:oƒ: Al			



	

	
	

! !"!"#"#! -,- "!.-.!#"/./"-,,.--/..$#$%$%&%&$#0/0#%$101$&%212%0//100211'&'
('(
)()
'&323&('434')(545(322433544*)*+*+ + *)656)+*767* +,7,+655766,770AèDefaultl	

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkPA¶                  @@@@@@@@@@@@@@@@@@@öBox10AêA¨8�ëÝ@ðñoÂÉDQÀÈëÝ@øoÂBYš¿ìÝ@@þo ®[?8ìÝ@hp±;@(Á/’ŸÁxžÁMõÔ@IðŸÁ¦‡–¿ŠõÔ@¢ýŸÁÚ‡?Á<} Ác$�A¨Éœ¼ BŸÁUœ¼(ýBFÐMÀ_›¼EéBíÙ\@±©š¼bÕBá!AÎ÷AùpB¢�>Í÷AçpBìÅ'>Í÷AÕpBEþ?>Í÷AÃpBŽ6X>RAÂîoÂôEQÀRAìôo—[š¿9RAûoÂv©[?URA<p†;@œ¯íAÍiŸÁfžÁcßUAhéŸÁ.Š–¿�ßUAÁöŸÁyׇ?¨°íAÛT Áu#�AÌØŸAJ B�ÁúØŸAg B
ÔMÀ'ÙŸA†óB)Ö\@TÙŸA£ßBà!Ap ApBl�>q AïpBµÅ'>q AÝpB
þ?>q AÌpBW6X>ÛûAáðoÂ+EQÀ÷ûA	÷oÂ	Zš¿üA0ýoÂ’¬[?/üAXpÂM;@!GA° ÁnS@ªºÔ@ÎØB¸à!A®XAÆpB|6X>®XAØpB2þ?>®XAêpBÙÅ'>­XAüpB��>ЏÔ@u BîÁÆFA¥àŸÁuZÀí1AÑïoÂ�EQÀ1AùõoÂÐZš¿'1A!üo«[?B1AKpÂë;@`2Ae ÁS@UA7ÜBgà!A�¹AÉpBi6X>�¹AÛpB þ?>�¹AípBÇÅ'>�¹AþpB}�>ïUAá B@Á2AZÞŸÁ…uZÀ`A6ЕY7sè>»¸ÿ?ø)º·ÿ?Žè>;þÿ¿\,º‚!A7oƒ:oƒ:oƒ: Al			



	

	
	

! !"!"#"#! -,- "!.-.!#"/./"-,,.--/..$#$%$%&%&$#0/0#%$101$&%212%0//100211'&'
('(
)()
'&323&('434')(545(322433544*)*+*+ + *)656)+*767* +,7,+655766,770AèDefaultl	

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkPA¶                  @@@@@@@@@@@@@@@@@@@öBox11AêA(˜ÁªïA¬WK>õýïÁž¨ïA¾÷¢>õýïÁ°YîAtU…>ôýïÁªYîAòî…>ôýïÁV®ïA;Q>õýïÁ2¬ïA×¥>õýïÁ»~¿AׯÀ½D¨¾Alݹ@¾¯¹½euÆ:Ql½·­¹½�\:C‚t=¶­¹½'ŒÁAó´Àﯹ½®µÀAPáË@¿¯¹½º~¿AׯÀº&ò¼C¨¾Alݹ@ú%ò¼Ë5Æ:Ql½Úò¼·ºÿ9<‚t=Øò¼&ŒÁAó´À½&ò¼­µÀAPáË@ý%ò¼º~¿AׯÀ#:=C¨¾Alݹ@ƒ:=06Æ:Ql½“?=L¼ÿ9;‚t=“?=&ŒÁAó´À!:=­µÀAPáË@�:=¹~¿AׯÀĽ=B¨¾Alݹ@BĽ=•öÅ:Ql½Iƽ=ã½þ96‚t=Jƽ=%ŒÁAó´ÀĽ=¬µÀAPáË@AĽ=ТïAð>>ðA< ïA�¨>ðA‘1îAÍ.…>ðAŠ1îAŒç…>ðA¸¦ïAßëD>ðA%¤ïA87¬>ðAESðAwkQ>òýïÁ!QðA£¦>òýïÁ¹¥ñA4‡>ñýïÁ´¥ñAþ¿‡>ñýïÁDSðAxÎQ>òýïÁQðA"3¦>òýïÁ†«Bi
²À|±¹½K@BÙñÍ@L±¹½(ÿoB0ñ>†³¹½4þoBx?†³¹½0«BÌÔ°À|±¹½ô?Bv'Ï@L±¹½†«Bi
²Àñ*ò¼K@BÙñÍ@1*ò¼(ÿoB0ñ>4ò¼4þoBx?4ò¼0«BÌÔ°Àð*ò¼ô?Bv'Ï@0*ò¼…«Bi
²À8=J@BÚñÍ@h8=(ÿoB0ñ>s3=4þoBx?t3=/«BËÔ°À8=ó?Bw'Ï@h8=…«Bh
²À„½=J@BÚñÍ@´Â½=(ÿoB0ñ>zÀ½=4þoBx?zÀ½=/«BËÔ°À„½=ó?Bw'Ï@´Â½=W[ðA¡>E>ðAÃXðA˜`¬>ðAÜÍñAŒ;‡>ðAÖÍñA
ä‡>ðAT[ðA µE>ðAÁXðAœ¬>ðA�SðA>L>ôýïÁlQðAV£>ôýïÁ�ïA0µN>ôýïÁiïA¦¤>ôýïÁ%WðAÌÒQ>ôýïÁUðAM5¦>ôýïÁ`ZB/;Ï@O±¹½`ZB/;Ï@=*ò¼_ZB.;Ï@a8=_ZB.;Ï@±Â½=]ðAwž¬>ðA“_ðA^ºE>ðA éîAÓª>ðA³ëîAÑ#B>ðAYðAÀ)©>ðA«[ðAoÑ>>ðAå¾BùÄÂÀ‚½=å¾BùÄÂÀ8=æ¾BùÄÂÀú*ò¼æ¾BùÄÂÀ~±¹½HðA±€½òýïÁ€®ïAg´©=ôýïÁ\¬ïAâqO>ôýïÁ8ªïAØ¥>ôýïÁ¨ïAÏPâ>ôýïÁÜùïAÊå?òýïÁí íACòA¦°¹½ì íACòA—&ò¼ì íACòA5:=ì íACòAZĽ=»øïAx?ðAhŸïAÈûô>ðAû¡ïA`:«>ðA�¤ïApòB>ðA"§ïA¿==ðANðA½WǽðA,©ñAiäíÁjý=,©ñAiäíÁU8=,©ñAiäíÁV*ò¼-©ñAiäíÁ–±¹½ÎðAây½òýïÁOWðA‹-«=óýïÁ*UðA³.P>óýïÁSðA@c¥>óýïÁãPðA¯â>óýïÁÔúïAæ?òýïÁ&.îA~òA§°¹½&.îA~òA›&ò¼&.îA~òA2:=%.îA~òAYĽ=ËùïA^x?ðAEXðAcõ>ðAØZðAÀ¡«>ðAk]ðA/ÁC>ðAþ_ðA~ù@=ðAøðATǽðA‘†òA{âíÁiý=’†òA{âíÁS8=’†òA{âíÁ\*ò¼’†òA{âíÁ—±¹½vªïAå®P>óýïÁR¨ïAZ£¥>óýïÁúýðAeëP>òýïÁÖûðAšÁ¥>òýïÁtªïAåQ>óýïÁP¨ïAÙÔ¥>óýïÁ×€¾A˜ÍË@¼¯¹½Ö€¾A˜ÍË@ð%ò¼Ö€¾A˜ÍË@ˆ:=Õ€¾A˜ÍË@DĽ=åŸïAØ4¬>ðAx¢ïAçD>ðA³ñA	¬>ðAFñAÎ�D>ðAçŸïAYù«>ðAz¢ïA!pD>ðAúW¿AGdµÀĽ=ûW¿AGdµÀ(:=ûW¿AGdµÀ±&ò¼üW¿AGdµÀ쯹½`A6sú¼‚ý?3À3ï­¦³€?‚ý?`ú<À³oƒ:oƒ:oƒ: A†,			





		
	




   !!!"""##$%++*$%&,,+%&'--,&'(..-'()//.(*+110*+,221+,-332,-.443-./554.01776012887123998234::9345;;:467==<678>>=789??>89:@@?9:;AA@:<=CCB<=>DDC=>?EED>?@FFE?@AGGF@IIHJJIKKJLLKMMLHI]]\HIJ^^]IJK__^JKL``_KLMaa`L\]qqp\]^rrq]^_ssr^_`tts_`auut`pq……„pqr††…qrs‡‡†rstˆˆ‡stu‰‰ˆt„…%%$„…†&&%…†‡''&†‡ˆ(('‡ˆ‰))(ˆNNMOONPPOQQP#RRQMNbbaMNOccbNOPddcOPQeedPQRffeQabvvuabcwwvbcdxxwcdeyyxdefzzyeuvŠЉuvw‹‹ŠvwxŒŒ‹wxy��ŒxyzŽŽ�y‰Š//)‰Š‹55/Š‹Œ;;5‹Œ�AA;Œ�ŽGGA�#"SSR#"!TTS"! UUT! VVU WWVRSggfRSThhgSTUiihTUVjjiUVWkkjVfg{{zfgh||{ghi}}|hij~~}ijk~jz{��Žz{|���{|}‘‘�|}~’’‘}~““’~Ž�FFGŽ��EEF��‘DDE�‘’CCD‘’“BBC’XXWYYXZZY[[ZHH[WXllkWXYmmlXYZnnmYZ[oonZ[H\\o[kl€€klm��€lmn‚‚�mnoƒƒ‚no\ppƒo€””“€�••”€�‚––•�‚ƒ——–‚ƒp„„—ƒ“”<<B“”•66<”•–006•–—**0–—„$$*—0AhDefault,	

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ	

 !"#$%&'()*+PA¶                                                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@°ï
°MAXSCENEd°d	°
°n0°°Box01@ÿÿ°Ömð>ˆª³Âpn)Á °&!°ð
d

ç	I@êÉ4¹hÁ4?dH5?á€H@�ý¿�ù¼Dµ8¶2=^–¿ƒ“+<¼ÊL?(¶2=Y–?A“+<ÀÊL?2ófß>€?‹ô;³ëTŒ±<8 À?ÄP}2.¹Ê²€?F<å#p¶ôè¶€?P�Í?^qV<'õ¿O€?MGK³ã¨°±<8 À?QÕų›·L3€?F<625
‚6€?P�Í?†qV<'õ¿kO~�•¿K‹> °&!°Ú
d	
¨I@™xÕ6ê羺ïÿ?á€H@�ý¿�ù¼Fµ8ºpÖ<€¿Ð<3õQ¿³(qÖ<€?òa:³úõK22ófß>€?åý<³¼øí¯<8 À?íL2àÄ~±€?Fú5ú=u%u¯Ëâ³€¿Z,@€¿=³°üµ’2dQËB@f	¿¬«F?v ª¾"°&)\Ï?)\Ï?)\Ï?°X0°°Box03@ÿÿ° ¤Ü>>Vòœê)Á °&!°Ú
d	
¨I@™xÕ6ê羺ïÿ?á€H@�ý¿�ù¼Fµ8ºpÖ<€¿Ð<3õQ¿³(qÖ<€?òa:³úõK22ófß>€?åý<³¼øí¯<8 À?íL2àÄ~±€?Fú5ú=u%u¯Ëâ³€¿Z,@€¿=³°üµ’2dQËB@f	¿¬«F?v ª¾"°&)\Ï?)\Ï?)\Ï?°X0°°Box04@ÿÿ° ¤Ü>$ìBœê)Á °&!°Ú
d	
¨I@™xÕ6ê羺ïÿ?á€H@�ý¿�ù¼Fµ8ºpÖ<€¿Ð<3õQ¿³(qÖ<€?òa:³úõK22ófß>€?åý<³¼øí¯<8 À?íL2àÄ~±€?Fú5ú=u%u¯Ëâ³€¿Z,@€¿=³°üµ’2dQËB@f	¿¬«F?v ª¾"°&)\Ï?)\Ï?)\Ï?°X0°°Box05@ÿÿ°Gµ>"íBœê)Á °&!°Ú
d	
u—@Ë¿:ÏË¿:Üÿ¿á€H@�ý¿‡ù¼Aµ8ºpÖ<€¿¤ö/3Dî
5(qÖ<€?z{–³q=662ófß>€?l:³+;´<8 À?4p°Í3¤¯€?Fú5ú=ü§ë²†(4€¿Z,@€¿K¸:3eœ ¯dRËB@g	¿««F?r ª¾"°&)\Ï?)\Ï?)\Ï?°X0°°Box06@ÿÿ°î:Ù¿Féêœê)Á °&!°Ú
d	
u—@Ë¿:ÏË¿:Üÿ¿á€H@�ý¿‡ù¼Aµ8ºpÖ<€¿¤ö/3Dî
5(qÖ<€?z{–³q=662ófß>€?l:³+;´<8 À?4p°Í3¤¯€?Fú5ú=ü§ë²†(4€¿Z,@€¿K¸:3eœ ¯dRËB@g	¿««F?r ª¾"°&)\Ï?)\Ï?)\Ï?°n0°°Box07@ÿÿ°Ëà>›Œ´Â¨ù#Á °&!°ð
d

é†@m®¿ö›?,?á€H@�ý¿”ù¼ÏÅ8¶2=p–¿Î•+<¯ÊL?(¶2=d–?}—+<¸ÊL?2ófß>€?ÄîY´ð§ó/<8 À?ù‡¿±:X"2€?F€?囜³L>C´<8 À?œšP35W³€?F<šy€²¨ºs·€?P�Í?]qV<'õ¿—Oêp±Â|�Á °&!°ð
d

Í+I@ 5¿ù0žº45?á€H@�ý¿�ù¼Î°8¶2=X–¿«•+<ÁÊL?(¶2=Y–?õ‘+<ÀÊL?2ófß>€?°ªŒ3oB�2<8 À?$ž7³>w²2€?F<‡'6^¢µ€?P�Í?IqV<'õ¿¡O€?ÅyC4M‹œ±<8 À?.dL²§³×²€?F< c¶c¸´€?P�Í?hqV<'õ¿¨O€?‡Ù¾³%¿¯´<8 À?½èX2šyn²€?Fý»üøüÂýéþ>•Öï²û žêÿ®ý“ûØùÀødøãø<úFü²þû³V³Ü þ
ûJøBödõ¼õR÷×ùàüùÿ¾ñvIbçô¥%¯†ìÿùÿ«Ñ3zP`e`„ÿ4üù¾ö•õÆõ(÷€ùyü¾ÿõ·¯†(«6c{ÿžÿ¼ve+p ‰Oÿ·ûEøZõkó¹òXó6õ
øtûÿþDÓtô]цÍÿøü|úÙø‡ø±ù*ü}ÿ »íçõÿý±úNùùúïû‹þfT椔ª
ð¡…ÿáýÿüýþÐÿéÈíÿ:	Òýèûqú–ù]ùàùû¼ü�þäÿ’yÆÿ½þ¾ýðüaüüßûØûü¨ü¥ýÿŸ läª\þîüüÏû{üÿý3Æ?*Áaíü…úHùIùlúBühþ‹|E×Ãá|-7¼ÿ¶ÿ
ª˜ÑaÄób	ÆQúmý4úÍ÷„ö—öÌ÷Ðù3üoþ';ÚþGýçûÜú:úâùÂù½ùÔùúªú¯ûýÕþ¶ˆ4b·€>þvü~û‡û�ü;þSaï¾¾åÂ	°Ðå^ˆB÷¯ÿôÿ¥€8™n¹†ÿ±ýÈü˜ü0ýfþ¾ÿ®Îúÿ^þuüÍúëùútûºýrð’í	.âÿ³ýþûûñúŽûÄü@þÀÿ	ï`|x•îoð0É>šúy,L­Î!4RÿÃþ¥þÿÊÿȹF/<˜ÿ—ý¶û|ú5úåú>üÌýÿ¿ÿÃÿIÿnþnýsü¦û%ûûúûQû—ûÚûü[üÚü£ý¶þk±£3mY*üáûMÄw>†Žÿ¡ýüòú©úBû¦üœþÁšË ¾ýAÈž °ª~-¿>¦ÿÿjþþäýþjþÍþÿ8ÿCÿCÿCÿMÿYÿ‘ÿïÿro��X18o°·gµÅÿ®þ�ýgü`û‘ú?úŽúŠûýçþ¥ô‰c§œ‰ÿ¬þ<þCþ¾þ~ÿcCàŠ8ø Å÷ÿïýìûúÙøVøÀø%úZüÿáZúx½õ…ÿþÌü]ûóú�ûDýŽÿôõ)Tõ~aÜÿËãð–ü7[c@Ðö¯Xÿ¾ý~üµûtû®ûIü0ý2þ	ÿTÿÔþkýVûù4÷<ölö®÷×ù}üJÿÞ÷\ÜÒfþ½ÿÏþBþ3þ¡þtÿkOç	³øúÿØþ·ý­üãûgûbûÞûÛü=þâÿ¡?uìnõÎ…þÅü-üäü´þûKp…Ä´ÿ¼ýVü·ûüûýÖþC@´�¦Duk;õ´‚Rÿ7þ>ý¢ü¨üŠýOÿŽÏ_ß	&óüúøg÷øýù²ü¤ÿ7è‹'_rÿkýqû¦ù@øa÷-÷½÷öøÃúíü8ÿIÝ-âõÿÂý¶û&ú[ù’ù÷úmý¯,/	°	Úá;kâþý\üÍüfþÔŸDHM	L	[Éø2¢]Rÿyþ²ý	ý‘ü[ürüÛüŒýGþØþøþ€þlýðûaú7ù½ø%ùpúWü€þ…÷%¹_‡¥Q,¾¦—–Ç‚ºþÝüšûïúÌúüúXûÄû6üÕü¸ýåþYÊüžv†ú"ÿlýRüü›üÝýuÿóý>¢3QþaüÌúëùßù�ú­ûâüçý¨þ'ÿ{ÿ¾ÿûÿFŽåXÎC™Ê̵�jYM>Ú‚Ç€VX…çhè+[0¨þ2ýü ûûûýÑþÔÅjrÍ^@¨ÎâþýmûCúÌùGúÃû7þ[ÃÎõ	Í

è}Wü!ø:õ§ó‰óÉô÷úXýR¹6§|sbþªü°ûŸûnüþ
GD³me¡>Bçÿoý1ûù¨øÆøÐù™ûÇýöA°&Û$Œþ’ýšýÇþæ�(j	•	°ÏL” ÿ2ýìû1ûÎú‘úhú\ú•úEû„ü5þ'í.¹„ÛGåïdÐ9!k4·ÿIþIýàüÿü€ýþ¬þÿ6ÿÿþ¯ýàü\ü…ü�ýWÿœÛ™�‘çÞá,Â{
3Úÿ!þZüÝúøùÁù"úÈúWûžû€û)ûÒú§ú¼úûÔûîüuþWmt,C˜ËíÁ¨ÿæýªü
ü
ü�üˆý®þÀÿt¨tšÿoÿ“ÿõÿO~hDEœhŠÓÌþv3FáÿkýCûéùÅùðúBý/
%ΗïfC´ÿ²ÿ
Ž�â!G\6×9t”ÿšþxý/üÝú¹ùù&ù-úüû-þ<¡»¹–ÿ§þFþvþ&ÿ$*ô1ªE3þÑû¡ù0ø¹÷Mø¼ùÍû0þ›À`U‹
¶iY¯ÿ{ÿÓÿ¯å8]W#ÜQ­ÿþ³üÉû‚ûü\ý=ÿL6¡-Ï‚rýþ”ü¸úÜùBúÒûEþÇÏÀ˜g‚[\ÿÉý³üü¶û„û‡ûÍû€ü¯ý=ÿìj^Àˆ×ÈtÿõýTýgýFþßÿØÒ:Á=ºxÚþCü,úòøÌø¤ù2ûý¥þÑÿgl	`ÿ¥þåýKýíüÕüóüDý¶ýpþ†ÿºPPp²C{¶ÿ6þýPüñûâûAüý0þ‡ÿ×ôªñß“=úï/Ǫ˜R xò:gšØÏþtý+üFûõúDû&üdýµþÛÿ ùöÄ—˜è�M—¦,RBI—ÿoÿÛÿ½Áy†œÄÿ;ýcúž÷aõòó€óôƒõ­÷7úáülÿ¯�ýâ˜Y~TBþ–ü¬û’ûSüÓýËÿö÷|Q_½š2ͧ÷ÿ¹ÿÔÿ68Ûÿ¤ÿ‡ÿzÿeÿÿzþ{ýJü1û™úËúîûîýxQÍYš/_PÔËÿ
Ÿ~xŸ%Yýƒúø:ö^õxõdöó÷ÝùüAþqUÊ­ú·þð¸yjÿ¹þŒþûþëÿ&inòËÝ5ÿþ”üeúÛø>øÀø8úWüÅþ**›XaàôÃz;ÿ7þ ýaý}ýñýŸþ:ÿ¨ÿÖÿÝÿÔÿÇÿ¤ÿsÿ5ÿêþ–þHþþÙýÞýþ˜þ5ÿ×ÿyrÙ\½fÜí�‡Auþíüöûªûüâüþ@ÿb^2Ï$¡×æ`ÿÿ1ÿ‘ÿ%ÕxQT
u�€ÿWþ1ý>ü¦û�ûñûçüAþ¿ÿÌ÷ŒÆÒÿÖþðý1ý­üƒüÉürýaþ^ÿL‹Òèψˆûÿ™ÿ|ÿ¼ÿ?çœ>¹8,Ú5>¨þSýDüÂûüýÄþ«_n’Ø·þ˜üòú
úúûÔüõþ	¿ãjmƒëQ½zÚÿIÿÛþŠþsþ˜þ	ÿ¬ÿ_ò,úZrÿ~þ½ýYý†ýIþ�ÿ”«µ¯BÛÿµþäýxýRýeý“ýÈýáýàýªýZýýÒüýãý3ÿÊU‹@‹m�¢k_fB½æËÿÀþþàýþmþ~þþøüwûâù´øZøùÖú}ýš¤8;tdÿêý>ýsýtþóÿªëõ9øŠHÿcþÚýªý¬ý½ýÛýûýþTþŸþ	ÿ•ÿ!£éã˜6úÿ¨¡Öüï^;z8˜ÚÿKþýbü-ütü*ý<þ‹ÿþ^tñª¡IÿÇý®ü)üüBü¶ü?ýÑýPþ£þÆþ¦þrþ2þþ&þrþþþÚÿõ4mq/ÍõÐb×ÿLþêüüû¤ûÖûhü
ý{ý¤ýwýBý.ýRýªýþeþ«þïþRÿàÿ�g[gŠ£™<lÏVæ¬ÊÿFÿÿåþ þþøü‰ûþù¼øø5ø%ù¯ú‘ünþ3ÉÜ—8PùßÁyê#<�ßî.¿±<ÿ©üRú…ø¨÷Ø÷	ùîúýßþ�gÌÿÿ>þÚýþÇþ�Ò¸Û•V#Ñ75±ÿÅý©û«ùø;÷]÷røNúsüYþ ÿëÿDÿlþ¡ý ýýÁýÿùñ4Ÿ- Äv…üÑÞ ÈTÞÿ¤ÿÁÿDë’Ô“ãíãÿÿ…þ™þJÿ…øIüÁ€w+þ)üàúyúûú"üšýÿPn_¿‰ˆ¯Ð¿a¶ÿéþ!þ™ýwý½ý{þ|ÿƒHgÖ”ÿëýPü%û¸ú1ûrüGþL)zô„BoyþÃü�û6ûŠûˆüèýVÿ¯Ã„í0OT=ñb¬èW1ƒVt ¶n¦D5�ÁîþuýšüqüëüÔýÝþ±ÿ#]ÿNþýàûûæú^ûmüðý¨ÿ^ì*ÿ\.�ÈÞ
u-&82ícµÿ÷þPþ¹ý6ý ü×û½úcùø÷òöÅ÷žù(üýþq
{ÈHiÿ±ý‘üoüfýpÿM†§kd£¢o|ÿýUûXúú@úËúoûü üý”ýþýHþfþ=þäý}ýBýsý;þšÿsvC�ö~,6ë¤þÎü¼û›ûeüéýÕÿÎps¨ÿ ¹¦þÖü§ûrûRü-þ½‡
çÚÑèE ¬7ÿûü<û"úâùˆúü/þ¤ÜÁŠ7ýCÿzüúŒøÿ÷…øÖùœû`ý¿þkÿ/ÿþDü(ú7øçö‚ö3÷Øø:ûéý‰Ëi`µ NýÂŒKâWÃaG}Äà›Ú¸cÿþýuü_üÔüÉýÿš6ßènÐ#iÂ'°ÿ]ÿ@ÿ`ÿ�ÿÙÿîÿËÿlÿöþ…þ&þæý½ý´ýÑý@þÿ'g…H€8‘É	}-/F3Ôÿ&ÿ8þ2ýVüãûëû`üýÁý4þYþJþJþ¨þ…ÿâsÞÂÚ©ßÿuý`üØûñûnü%ýÇý:þlþ^þ#þ»ý1ý’üü û—ûõû¿üæýHÿË`Þ>c%eS=,€ÉËxã+RP8½D£öÿ]ÿ÷þàþÿyÿÇÿÜÿ¡ÿÿzþéýŽý�ýËýJþÞþ[ÿ®ÿÓÿÕÿÜÿíÿ*˜(À,Aáãÿ‰þ<ý1üŸû�ûéûmüÝüýýÙüÁüäü_ý2þ$ÿúÿv…,}ÿªþäýzý‘ý@þtÿÖ
»È<?/;ÿ¦þŒþðþÎÿèÝUiTP”ÇOy'[L)I±ÿ[ÿ/ÿ!ÿ(ÿ3ÿ,ÿ
ÿÌþ}þþµýWýýýzý>þ,ÿ¦çÒ‰0Üÿ¡ÿ„ÿ~ÿ�ÿ¥ÿÑÿøÿÄÿzÿCÿ<ÿaÿ¤ÿÎÿµÿHÿ£þúý˜ý¢ý.þ2ÿ�ñB?¬z«jõ„ÿNþtýýýŽýYþYÿmQñ55õ{ÈÕÿ²þ|ýTürûýúûÎûõürþüÿcR†ÜožþíüÒû‹ûüNý¾þ%ÍV�¢3Œ‚Ô•’ÿ×þ‡þ„þÁþ"ÿ”ÿzÛ/á£b;4O”ð8n‰¥ÇUŸ¡Da�þ&ý#ü¥ûÕû‘üÄý6ÿºyc×ïÊzÿ'þÛü«ûœúÄùSùjùú\ûýüÅþYzãx?qþtü·ú´ù®ùµú¥ü-ÿâ[?Jl±Q›×XHÿ­þ’þÊþ>ÿèÿ´«¹Ã³Ifè½`þ-ýÉü@ýjþ
½40'"ŸÔÿ
þ—ü«ûrû×û«ü¸ý³þÿ÷ÿ)%ûÿ¾ÿvÿðþ+þý÷ûïúSúGúèú!ü½ýÿ0ˆe£H{pwùÿÜ(¢ð°®Ý]oaÿˆý!üRûûeû÷û•ü)ý°ý:þÜþ¥ÿ—Œ\Ï·´ÿYþCý¯üÇü�ýÆþ(`.‡Žb/ãʦs±9Çÿlÿ)ÿþþãþÓþóþQÿòÿÑÅ—ÙèÿÿÂþ"ÿ+¥Nƽ	£°s+kÿÇþ þjý£üÓûû_úúú¨ú”û�ü9ý]ýÞüðûßúú½ùúûÂüÜþµ’‹¾UÄUbÿêþÚþÿuÿùÿ‡`Ž…@Ñ6wÿ±þæý<ýñü%ýþÿP8ÐÏ�e´Ôÿäý_ý‘ýeþ�ÿÞ40¤éµ
É‹jpÿ°þ3þþþ@þPþþý<ýüyúÚø†÷®ö‰ö÷høAúwüÉþî©Õi�CàrëÍ­là?‰ÿ$ÿÿ=ÿ{ÿ™ÿiÿåþþ0ýtüü>üüüHþþÿ᪠"˜œKå}%°øÍ@vÿ®ýüÍúú·ùÿùÆúëû2ýpþ}ÿG¼Ò“Sÿ’þûý©ý¦ýØýþZþˆþºþýþ[ÿÀÿO]G#ôÿÀÿƒÿPÿUÿ¿ÿ¯-Ωÿ’b¾Ý—þ�ý#ý ýqýÝýWþÇþCÿÁÿLÚXµí÷ߟ)„®ÿÚþ<þ
þcþ0ÿ4~Kp-ÿÉý¡üçûÁûüªüMýÀýßýªý+ýƒüòû°ûêû£ü¾ýÿ]xHÁú,O{� m·Yíßèô÷õܪ`÷næÿSÿéþ’þgþnþžþõþ\ÿÈÿUqoz‘ºÙèÉyûÿ`ÿ¿þFþþDþ·þ=ÿŸÿžÿ
ÿ÷ýƒüûÖù:ùCù×ùÖúüoýÅþùÿÛœFñŒø0¯TŸ	ª†–»Ð¼dÝ7�ÿ-ÿÿþÿ]ÿÉÿE«HomJÕŸ^÷ÿGÿCþý¿û­úúîùoú_ûŸüìý#ÿÔAjSשž¹õ=~¥«˜a†äÿ.ÿVþ{ý¤üèûsûbûÌû®üþ­ÿ†añpäH“%@ÿïþ'ÿ²ÿeúQe#° |ÿÝþAþÅýgýTý€ýðý¹þÊÿE;¾�Ï[‚ÿ ý9üŸûúû-ýÓþÓ~uÓɾÿàþfþTþŸþÿŸÿa�¡ž“n/´ÿÿ5þfýÄü”üÖü§ýËþ0�Ň³L€„—ûÿâÿS>v¢’ï!«ÌÕþý¿û÷ú®úÊú,û§û3ü¹ü&ý|ýÁýþWþ’þ þ|þ1þôýþ³þú1JçÅ®»
걫ÿ(þ?ýý|ýxþÓÿ:\ᚃÖÿéýüÄúúúŒú]ûeü†ý¸þîÿ=CñJ!uwUU®ÿ†ÿÏÿd§IA–	\…ÿnþ9ýþûñú#úªùpùiù‡ù»ùõù>úŽúûü|ýMÿo¦«HP¬Y€/¤ºÚ…©¤a€l/ÕIšÂÿ¿þœývü[ûˆú,úuúpûýíþóÃ7Sñ	¿Tÿ–þtþ‚þ‘þ}þBþöý¿ý»ýþ¿þ›ÿ^Øåi~ÿ[þ/ýIüÛûþû¬ü«ýÈþ½ÿW„Vìÿrÿ$ÿ
ÿ9ÿ}ÿÉÿíÿùÿ }Ö¼�>¡ÍÄŒ-˜Úú#eÎÿgÿÿãþ¯þnþ3þùý¿ý‘ýeýCýýóüÃüwü&üÎûŸûÆûMüXýÄþk„—*1»·N³ÿ¬ý½üoüêü"þþÿ�8÷ã7iÇÿžþþ+þÏþÃÿ¹}ëâ Y†¹ÿ˜þTý+üiûYûüiý7ÿ,ôL(‘SºñÿHþöüü§û£ûîûjüúüýãýþêý›ý?ýþüëüý€ýþßþ¯ÿrù4	�éÿOÿëþÓþÿdÿñÿ�.¿1lQúcÄ3Èÿ‡ÿ{ÿ£ÿ	º°¾Å†×ª
èÒòÿnÿqÿêÿ·£mð¥É�ÿ…ý9ühû>û®û¢üØý"ÿL-´ß¨JKÿ5þ8ýzü"üRüý0þ«ÿ8€;A�J°ÿþ¤ü¨ûNûžû„üëýˆÿ2¯ÕŠÆ†ãÚ‹©þ�ýòüùü…ýeþPÿžù.WbAâDsÿŸþóý�ýšýþÿþ3)Õ÷�
ŸQ;,ÍM�ÿ“þpý|üëûîû‹ü˜ýáþ,>üIggVÿzþþþcþùþ�ÿÍÿÚÿ´ÿ‹ÿ£ÿŲ̈�«¬Åÿ;ÿÿeÿóÿ’'~•TÏDÿ�þþòýþþ
þ¬ýÿü+ü‡ûOûÈûøü¥þšc¸hfË–t�ÿ2ÿ6ÿ©ÿlE‰•9up_ÿhþºý6ýßü—üeüTü“ü/ýGþ¼ÿwAÚ¬€†Êžyÿ»ý²ütüäüÔýïþôÿ°ýàˆ¸ÿ‚ÿ“ÿÙÿB¯)7,$%L›e�P ‹?ÿåý±ü«ûÛú?úËùzùeù�ùúáúüý6ÿú°ö¡�ÄLe]‡þCýÅü,ýKþôÿÄdŸ::¤—+�ÿ‹ýYüxûû.ûÒûéüMþØÿEj
|u.Úþ¶ýéü•ü½üTýFþÿå9k4†HŒjÏÿ´þüýµýëýŒþyÿ�˜^̰ëÿ®þ§ýÜücü1ü;üüý´ýšþˆÿm#�ØêÜ̶«µÉéäš)º+‘ÿìþMþÃýRýöü­üfü'üêû·û±ûëûnü)ýùýºþKÿ”ÿ£ÿŸÿ¶ÿâ\”tËŒÏκ·âHØÿŸÿ¡ÿÎÿ(šY{PíQœÿôþxþ6þLþ¿þ}ÿ`>äEBôVvqÿRþ/ýBüÏûôûÃü!þÙÿŠéª¡Ã6@ÿ)ýnûOúéùCú=û™ü8þÍÿ
Œ¦}#·>¹xÿÞþtþ\þ¯þgÿr�tëÃÞ‰ÿcþ¸ýÅýyþ¨ÿ!«hdÓÿþeüEûãú[û�üþÀÿ,(¬Í°‰ƒ¢ê2n†~G¼�aG§îÜÿ{þùü�û†úúXúQûÊüšþY×ÁN�ºÿ5ÿÿaÿ#5q¥|·7÷(ÿýbû8ú©ù­ùúÍú�ûGüÜüoýûý³þ}ÿFÜ&»f<iõÎÓÅgžB_þTŸþýôûzû²û‹üÚý]ÿÄÎ_TàVÉÿ„ÿ‘ÿîÿ[Ä'5n¨Ê¿‹&‹Üÿ#ÿ‹þ:þ2þ€þôþiÿ©ÿ•ÿ0ÿ’þþý¥ýÁýdþuÿÓ.e6›~äíºnFÿkþîýÉýÌýØýÓý°ýŽýpý`ý`ýeý{ý’ý¶ýäýþ>þ„þìþ‘ÿmswHÉØ€ÌóOÕÿÆÿ+å²K5•¸ÀÿÝþ*þÂý¶ýþÒþßÿÿìl{)É‚e]9éN’ÿëþ¡þ¼þ>ÿóÿ›

±ÿþý7ü”ûXû„ûüý&þ]ÿ}ZİFQÿsþ¼ýAýýýLýàý¯þ´ÿÑêà�ØŸþöóÿ>ÿóþÿ˜ÿM´4‚¡„7ÉA¸'¨ÿ7ÿåþÌþçþ7ÿ˜ÿ÷ÿ>b‹ÀW�Œ[õyõÿlÿÜþ>þ„ýÊüü‚û+ûû@ûºû�ü›ýêþaÈ	¹'5ïHQ+%·ÿÌÿGþ¨7ß%çþªý™üÁûQûGû™ûü¹üRýæýxþÿ®ÿUÔªhìá@L*	ÿˆþIþyþÿÎÿ«tù	´üÿAþ´ývýƒýÚýaþÿþ˜ÿq½G‚¢„\gÿlþªýYý¯ý¡þ
šûÛð.£ŠÿFýNûóùzùâùêú5üUýýýþ�ýÌü;üüšüŸýðþLyg˜…Ày%žœþ¾þcOÿÿ—ÿ®Ý±Àà(öýÆûúSù›ùËúœü¢þZŠÒ&VœÿSÿ†ÿ=(g,Uíþþ·ýþý¹þ­ÿ‚þç/îþwý&üyûžû¯üZþ(�úhÕÿ¸ý¤û!ú¢ùJúòû:þ¦­ùd5båÇ÷7/c¾¡•ÿþ–ýþ+ÿŒ�éMÔÿÙýÍû-úiù²ùûýIÿ3V„Ì{ÿäý_ý�ý}þÆÿ‡b¾Ùùÿlÿ;ÿ_ÿ¡ÿ»ÿxÿÌþáýîü[ü^üýþdzLv¤½ôº�þýüiü×ü'þñÿÈ8ï&Ül'ÿBþÕýÌýþ‘þ+ÿÈÿƒDä�O-›œB¿ÿkþ“ýhýíýúþ8V÷Ýøaÿ[ýMûŸù£ø§øÀùÒû�þaô¾ˆAr¢ÿÿÈþþºý°ýãý:þ¸þ4ÿªÿòÿóÿ—ÿßþßý£üXû&ú5ù±øÖø´ùhû´ýdû5\™Mʈ¯S~ôcxêž�Ó©^ÿ=ý ûÄú¶úpû®ü2þÁÿ"0Øü—¡2Šþîü«ûùúþú¸ûýÀþ¡W«[AP¯¦ÿ‚ý¤ûUúÏù+úFûÿüÿUi"I·ovýAuæþ³ýñüŽüxüŠü®üíü2ýœýþ•þ(ÿ¨ÿ'’ˆ.úÛ¸näî�–EÀ9éþöýgý%ýýÚüˆüÿûYû¾úMú1úhúûñû$ý~þéÿCkOô=F¬*„Æö*†ÿ8ÿCÿ°ÿRëTbajÿaþpýÃü…üÅüwý‡þÀÿñÞz­”,œç0ÿDþmý·ü:ü&ü�üŽýÿÝ´B:fÄtÈ
›þ»ý~ýèýÈþÖÿÑp P ¶ÿÑþþ¼ý£ýÆýþYþ¢þëþUÿìÿ³¢˜iãòj{3Óÿ—þ²ýWýzýþ³þ\ÿÍÿçÿ·ÿPÿ×þrþ4þ/þqþâþuÿþÿ]uKßÿHÿ£þþÌýÔý'þ¶þcÿþÿ_�e3Z®òÖuS:§.’žÓ¶ÛŽ þývüÖûüýNþ¦ÿ¨‘öÿ{ÿGÿ{ÿáÿS‘}
Rÿ�þëý…ýrýªý	þ_þyþ.þ€ý‡ü�ûÕú²úûü@ýeþ2ÿ‰ÿpÿüþbþÙý•ý¼ý\þ^ÿŸì´Æ-þvéþ¡ýäüËüSýfþ­ÿ÷ëyÜ;¦\o.ŸÓa'[é˜'OàÈøþµü�úßøá÷Á÷ƒø"úUüÈþ´��äÒ¬·ÿ"ÿêþÿkÿÄÿòÿÖÿyÿëþZþìý¥ý‰ý~ýfý?ýûüÃü¬üËü5ýëýàþíÿøÌNkp­¦ÿºÿ(齂#íp×DÍ�k\bm‰®í@´6¤êò¾VªÐÅÿ˜þýˆüåû˜û”ûÕûNüðüÂý²þ²ÿ£YÂÜ©; îÿ6ÿˆþþäýþ±þ‰ÿ‚cþ1øYe:ÿþãüüyûPû“û=ü@ý„þÞÿ‹ŽGUzÿæþ°þôþ˜ÿ�µàë¿0>àóœ5óþþý{ý…ýþëþóÿ÷¼(2ÓÎþzý9ü9û”úkúÇú¦ûùü”þD·³Û?rוËa(õŒØµ)õÿÿ‡þEþ;þSþtþ‘þ£þ¯þºþÏþêþÿ$ÿ7ÿ6ÿ!ÿÿ#ÿ]ÿÉÿrO>ÆÃá�ûÿwþKýÈüøüÎýÿ?%~?�”ÿ™þÉýJýýýVýºý&þ•þ
ÿƒÿüÿkÅJ…·ö 4Úxò_Ûÿwÿ4ÿÿÿÿÿAÿvÿÆÿ&ÚF9×þþ¥ýPüCûÈúû7ü
þ8LßžcCnNÿ8ýƒûmúú\ú*ûLü‹ýÂþáÿåÐÂ�aÛõ™Ú;Þt™>?M6³•á¥mÿþVý?ý¾ý¡þ¦ÿ‚	¸/°ÿeÿ`ÿ¯ÿ%©I2ÜnâÿðÿEÅR±³<:Ãþ$ý”û\ú­ù—ùú±úqûü\ütü[üGücüÏüšý£þÓÿþç~¥däNÅ€Žö¢g&À&OI,÷¡9º'‰èQÍÿyÿ_ÿ€ÿØÿNÂ
«þÿ%ÿVþ±ýaývýêý¡þÿBÙ
âb£ÿÀþâýý�üJü8üLü�ü¿üýhýßýoþ	ÿŸÿ v–…Oðÿ�ÿhÿpÿÊÿ�p{dû%Ç
!G¿½<;aU׳ßdziþ~üû$úýùuúlû»ü3þÂÿCžÇ–þóej5êµÿÑþXþwþÿ!X<W´J?ÿÒüXú6ø³ö
öKöY÷ù
û&ýÿžÃ„èöÆ‹]Nh¢àõ‘ö9d†ÿ±þþ„ýbý›ý)þæþ°ÿeì8QG4%3_®ú08÷w–}ÿ+þÅüuûfúÀùžùú0û®üiþ*´Ó[WËãÑÑÿÿ þ¢þ	ÿÄÿÄè/wV‘<t�ÿÔý‰üÙûÙû}ü�ýÖþ�¥ZÙJ×ÿ¢ÿÆÿAøÂ{û#ã3"ÒÿjþýñûDû+û£û¥üøýhÿ¹Î‘ìÆÁÿ=ýšû~ú2úÂú(ü2þŒÆ„¢æƒ¸ìÿUþ!ýaüü5üÀü¤ýÕþ>°)ÁÇ(}âÿƒþ˜ýMý¨ý’þÇÿ9tO�Š1Ëþ‰ý�üüáû*üÁü�ý‚þ‡ÿ‰r-š°[¥ ÿmþžýDýzý'þÿÈÐ'Tÿsþ¿ýYýKý˜ý0þôþºÿYÉ
"1ExÏ@¼)wŠ^“ªMâlØÿ5ÿ‘þþÓýÔýþ„þùþdÿ¡ÿ¬ÿ‰ÿHÿ	ÿÐþ¿þèþRÿñÿ°{5¾ö·ñ¼.ÿ„ýôûÇúúðù^ú;ûuüëýmÿÞ×DR�û}FfðÅÑÒ�ûÅõ�»¯ÿ ýØûˆúåùöù°úïûnýïþ1ò)ÌÿþAýÕüòüŒý£þÿÿwÔÝtŒ5îxùþšý„üÔûŽû¶û#üÂü_ýÝý+þGþ0þþöýþPþÈþqÿ,ñªKÜA}|GË-,Mÿ¶þ‘þíþ¼ÿ× Íû’¼švvÿàþºþ*ÿ_Çå$¹µG§ÿ½ý×üdüküÔüqý þ¬þÿ6ÿ'ÿàþuþîý[ýÁü3üÍû¡ûÍû]ü-ýþÿÇÿ0$¦ÿÛþùý;ýÑüÕü;ýãý¯þ†ÿJówß6{·èA_‰¿dØK¥Å—üÁ‰bÿvþ½ýSýAý‹ýþÖþ�ÿøÿïÿ‘ÿ*ÿåþÛþ	ÿfÿÝÿNŒšZÓÿ)ÿwþîý�ý]ýXýný|ý{ýdý8ý	ýîüñüý\ý­ýîýþ,þ7þXþ±þLÿ%2B.á?:Ö;t‘®ãÿ2ÿ·þzþvþ‡þ¢þµþ¹þ°þ³þÂþóþAÿšÿçÿ'P|½%®Vž æ`˜¹ß(™ÿDÿ*ÿ;ÿiÿ”ÿºÿËÿÉÿ¬ÿ—ÿÿ~ÿ•ÿ½ÿåÿþÿÞÿ»ÿ›ÿ‡ÿ†ÿ‹ÿœÿ¶ÿÒÿìÿýÿ	ýÿòÿàÿÃÿ¢ÿhÿ	ÿ�þ þ¼ý„ý ýþ·þ©ÿ¹Õã«üuƒKÿþHþþýþwþÿŽÿ5.ÙÿVÿ´þþ¥ý[ýVý…ýÕý7þºþWÿæÃ‚ó¯ý;ÿˆþ!þ	þ=þ½þcÿv¶œG¸ÿÿ¥þxþ¯þAÿ
åu­“CØdöšJÉÿ’ÿdÿEÿLÿkÿ±ÿøÿ3Fuÿ¶þñýcý.ý€ý=þKÿv�`¾¥'s²�ÿcÿˆÿïÿzó>Cök¾ÿÿyþ
þÄý©ý­ýÖý!þ§þfÿKUbh$vDŒhåÿúþ…þžþ"ÿòÿʇïè_Yêþ:ýŒû ú8ùôøjù”ú?üHþrnøë3Û'Oo­~øÿ{ÿÿÍþŸþ“þ¡þ¯þ§þyþ1þàý†ýMýOý¦ý\þ\ÿ‚±È®Q°Ä�’±sCòWm8ÿØý”ü—ûûÞúû¢ûRü
ýÀý^þÚþLÿ¬ÿGtw7Àÿ&ÿ—þ<þ<þªþ�ÿ°Ô¹!ýB«ÿ3þñüüšûºû^üsýÂþ(bg0Ák$,pÁ&ÂE¯
pñÿ„ÿ2ÿþþæþïþÿ^ÿÍÿbí»tÜÕ\�f@Mÿªþbþ[þþªþ¯þ„þþBýZüqûÃúrúŒúûþûý%þ!ÿñÿ„ß	ÊŠ6êÿ§ÿxÿ„ÿÁÿBï¬CŒf¿Ÿ7ÿÊý‡ü¬ûZû’ûIüpýÓþE““<„†KìýxõŠW`¸O¥Ç%m§Ãÿ¾ÿpâ Ç>‘ÿåþ]þþðýþ%þ,þ	þ±ý6ý¶üRüü)ü€üý®ýcþ	ÿ‘ÿåÿ"NŠåQ¼
A@Þ»¾øu ÚªíÄi
ÿõý@ýùüý€ý/þÿàÿŸ&ckIÐ�%Ëÿgÿ/ÿÿSÿ¾ÿKÕ)1áAuÿ‡þ¡ýàüGüòûúûNüùü÷ý)ÿo“iΨ
üÿÿQþõýáýþ]þ²þÿEÿoÿŠÿ£ÿÊÿ“LÞwÀºgö†.òÒ­nl«ÿÞþ+þ±ý}ý§ýþÃþ~ÿ$“µ‰œÿ4ÿÿHÿ¸ÿLäfÀàÄpîG†ÿÁþþŠý-ýôüèüýUýÝýŠþDÿøÿx¬‘+‘ÿÝþGþéýìýWþÿ/F(²×‹áéÖÒÿÿµþÅþ)ÿºÿF¦Ä»…@×ÿ¿ÿ¬ÿžÿ”ÿŒÿ�ÿ²ÿýÿm
¾\ÅÔt¤„Dÿ)þrý0ýˆýeþ�ÿÚé…€íòÍÿÄþþ¢ý¶ý-þßþ±ÿháûÐjãÿaÿøþ¶þ‘þœþÁþþþLÿ´ÿ@ê¥R¶¥ÛMÿ½ýuü¯û˜û'ü6ýžþQ"QÛà“ÿPþVýÓüÔüQý1þVÿ�ÃÊ|À„ÒÍ”ZÿSþ¯ýˆýïýÝþ ›ïêS)·ðÿ0þ¿üèûàûÁümþ”Ó½
�5>ºþ’üÝúÂùUù†ù6úGûŒüòýOÿ�YÀ«<˜®ÿ¤ÿçÿa¥3‡‘BŸÍ^ÿÿÿtÿ§-sZÝ
ÿÞýÝü-üÚûòûzüný·þM³EÔ¥æμþ	ýüüÓüpþru""R±tÆöÿ=þàüüšû¡ûü”ü>ýåýŠþÿ‡ÿÐÿïÿáÿ™ÿ6ÿ¢þþ—ýSýlýçý¹þÆÿДùèh³vÿKÿŒÿ-ý€xÙ¾aÿþlý7ýoýãýþ+ÿÐÿ\¼ø&@VQ¿IÖÿ�ÿ›ÿâÿv,äxÍÃW‡~XÿOþ•ý/ý$ý`ýÆýEþÅþ<ÿ­ÿn¹êôã½�iD68<.ÄÿkÿÿÆþ¡þ­þÓþ
ÿEÿlÿŽÿ¨ÿÃÿåÿ);Ke„®Ïàêôõôøøà¸¶Í÷@”ÍÜ�
ÿõýý£ü¨üýéýêþñ”âè·zF0*Æ;ˆÿµþüýqý8ý[ýÎýmþÿ•ÿÔÿµÿ0ÿgþxý™üõû­ûèû—ü«ýøþNyaðÇw Ìv&Þ¥ŠŸÐf›º·‰:¹xÿÿÏþüþqÿ¼S¼Ü¬ RVÿTþjýÍü�ü§üýµýyþFÿïÿ\s4ËÿWÿôþÊþÉþþþ[ÿçÿ§ŸºÔ³'†hðO¯þGýQüúûKü)ýpþÙÿZ){€cÿ{þÝýµýúý£þ�ÿ{l5¼ñà�ÿI‡Ëÿ*ÿ³þYþ7þ;þlþºþÿoÿ”ÿˆÿ5ÿ±þþ“ýDýTýËý•þ¦ÿ»°Mx `heÿ‹þþÌýúýcþãþZÿ›ÿ¦ÿ’ÿwÿiÿŽÿÌÿRk]@5N—ûd·ïõÏ“Dô´�aL6·ÿ2ÿ‘þïýQýëüÈüýªý�þ¹ÿèýÓ>Fâ0Z‡èÿ£ÿ¬ÿ�“ãí¯\æPšÿÌþýýPýøüý´ýÃþo‘Jx=œ½ÁËÿöþ]þ(þVþäþ©ÿ~`8�£ÿ{þIýAü‡û<ûmûüñü!þfÿ ž8cu—°ÿîþuþLþxþùþÆÿ¼¯b¬_št)ÿòýÿüvü_üÅü˜ý¿þ,žêáejú-(ðÿÿ¦þ²þ?ÿ8l™�
lFÏ*ÿžý\ü’ûCûhûïû±ü˜ý‹þqÿ+Š•Tìÿ{ÿ9ÿ,ÿZÿºÿMÄuL=Ü:o™ÁÿôþBþ¸ýfýMý]ý—ýäý1þpþŸþ¬þ®þºþÔþÿ|ÿ	’Yu_"ÈlÈÿŸÿ¨ÿñÿt¹5qTê<u·ÿ7ÿÿÿwÿóÿoÚE_rˆ•†HÙ>�ÿçþ_þ'þ6þ‘þÿÌÿsñ¡5éÿÕÿN�¢w ÿ'ÿ¯þIþèý�ý]ý.ýýòüìüþü>ý½ýrþIÿ-­(llBõ�6üù1“î)-é_™’ÿvþcý€üùûíûQüýÙýºþ‰ÿN�VKîb³
˜ÿeÿ€ÿáÿ4®#Aï2™ÿ#þâü
üÈûüðüþoÿ¢‹8þŒø]áÿ–ÿ‘ÿ¾ÿ
c»ð+GcxZý`…ÿˆþ¤ýýÁüæühýþÒþUÿ�ÿ‰ÿ`ÿFÿdÿÒÿ�‡¦¼�–™Kãœÿ þõý¦ý�ýÃýþGþ†þ¬þ¯þ‰þ<þßýwýýÙüÍüòücýþ!ÿeŠœ)A¦Mÿ(þuý:ý|ýþçþªÿ?ŽŽFØÿQÿÓþyþGþ]þ¬þ"ÿ¬ÿ:¶.•ìÎYÐXøÿÀÿ­ÿ¬ÿÂÿìÿU‚ ¹­�e%àÿ±ÿ¡ÿÌÿ)²G¼ò½'@&ÿþýpü"ü?üªüDýñý˜þ/ÿ¾ÿCÆ6›ÐèÕ£d8,Gpœ¡y˜óÿCÿ‘þøý‰ýSýbý³ý@þæþ…ÿYŒš£Áz–P[!¨	gÉ2¯ÿ$ÿ®þ:þÀýLýúüÈüÆüüüRý¾ý1þ¡þÿ‹ÿ¨Iñœ3¥âÒp½ÖÖÞÿÿþ[þþòý*þvþ¬þ±þƒþþUý°ü)üãûõûoüCýfþÁÿ1•»”ÿëhŒvBóþøý&ý�üNüxüýÞýÆþ¤ÿ#1Õÿ/ÿmþÑýyý�ýýýÝþ5Aƒ´«‚W/ á†ú3_«ÿ<ÿ8ÿ’ÿr“F„ÿxþVýUüžûPûsûüÜüâýûþâÿ‚ÑßÙê!ˆ÷YˆkªKQŽÅО#sªÿñþoþ<þZþ¾þHÿÌÿ3hi/ËÿSÿîþÇþÛþ5ÿºÿQ¿ð݇™ÿ3ÿ	ÿÿÿ+ÿ/ÿÿÞþ™þQþ(þ8þˆþÿÁÿx
db„îÿmÿÿ	ÿ*ÿfÿšÿÅÿ½ÿ¤ÿxÿEÿ!ÿ(ÿeÿÜÿ�3Àæk¥Öÿ"ÿÈþÜþkÿI^i2t'N&àÿªþ¼ý%ýÒü»üÒüýMýÊý‡þÿ°õ%ƒWŽ2€Øþ™ýóüý¼ýôþT§¨06­Ê¯–ÿµþ<þþPþ¯þÿ~ÿãÿTÍ@œÀ±bÍ$ÿMþµýƒýÏýˆþ†ÿ—dÆ—çßÿ®þ�ý½üVügüðüÍýÙþúÿõ·(D
™ôF�ÿÿÆþÏþ"ÿ¦ÿMóŠù22è`�¥ÿÍþ3þúý5þÔþËÿí(îE"wb°ÿkþhýÇü‰ü®ü+ýåý´þ~ÿ*¨ñö­(nÿ¤þäýUýý ýgýáýrþ
ÿ˜ÿøÿ13ñÿáÿüÿ=¢\UïLŽÿÞþRþùýéýþjþêþ�ÿ*ä¤Vë?S'».’öp3‹	ˆâô c¼ÿLÿ'ÿ@ÿ•ÿþÿc¨¾«]òÿ‡ÿ.ÿÿòþîþïþâþÏþ¸þµþÌþÿHÿ“ÿÛÿ	.CL?ýÿÏÿ¯ÿ—ÿ†ÿ�ÿŠÿ¨ÿÜÿ âÿœÿJÿýþÓþÊþèþ"ÿVÿ‡ÿ®ÿÂÿáÿvâP¯åöÚ™>Ð_Çÿ ÿŽÿyÿSÿÿÅþ`þøýžýaýEýLýyý»ýþlþÕþJÿËÿZó§a
—ó¦Vkv�ÿ¹þ(þ¾ý…ýbýEýýåü°ü üÊü8ýìýØþðÿVkGÖÓO˜¶ÙF²ÿYÿ#ÿÿÿDÿvÿ«ÿÛÿñÿêÿ¼ÿYÿãþVþßý–ý—ýñý²þ¹ÿî´Ók�^
ÑþÊý
ýªü�ü¥üñü_ýÿýÁþ¦ÿ�OØ#ñŸ5·>Ùÿ˜ÿ€ÿ—ÿ°ÿÂÿ¤ÿWÿÛþFþºýiýXý“ýþºþrÿ/Ê>„’ƒ\;ðÜÄ·´¹Òð Q`Rp©ÿÄþÜýý†üUüˆü#ý
þ(ÿg §V¤ˆMU@6ÿFþ‘ý!ýý0ý ý9þøþµÿhòBW7ª=âÿ®ÿ£ÿËÿ‘}ŽpÖAÿ›þGþWþ®þ1ÿ¨ÿAT^y³
nË锆Ùÿ-ÿ“þþÑýÎýþXþ­þíþûþêþÏþÃþÒþÿþ@ÿ�ÿçÿEM.>�cž�4–Ãÿèþ*þ²ý£ýþ±þ”ÿ…Há=|¢Ñ\°ëëµ`íZ®ê
ÿþðüæûòú1ú³ù‚ùµùSúNû…üåý:ÿZiC¹iÿüþìþ(ÿ¢ÿBÎF’ÅÁ�'¡
vÿùþ˜þaþNþnþ¼þFÿèÿ™BÃ$ý¦?ݘ{{›Çÿ8adBâdÑÿDÿÓþ†þ_þ`þ’þËþÿXÿ‘ÿªÿ£ÿ‚ÿLÿ"ÿÿ1ÿ{ÿðÿ�$£û'3!õ°Qá{'ÿÿO¯ nŒeùO�ÿæþnþ8þIþ—þÿuÿØÿèÿ£ÿkÿXÿrÿ¼ÿn›œ…b8	Óÿ†ÿÿwþ¾ýýˆü?ü;ü~üûü¨ýkþ ÿÂÿ@Ž¥’f+AÅu?ù€´™7Ÿë*x×ÿfÿ?ÿVÿ¾ÿY¥øé}ÀÕÿÖþÛýý�üjü¤ü5ýþÿ4+äEFè?i�ÿÈþ@þþHþåþ¼ÿ¶º‚)æLhX#ÿõýàüütû>ûnûêû¬ü“ýŠþŒÿŽ•k�º•"yÁ,Ѩ¨·¶±¡|Z2ôÿ ÿ6ÿ·þ=þÐýŒýlýiý{ýŸýÍý#þ�þOÿ;/ ô‡ÓÜž!u¡ÃýÿKÿÔþ¡þ«þèþ4ÿ€ÿÁÿéÿôÿõÿáÿ©ÿIÿÐþCþ¶ýDýýýSýâý±þ¦ÿ¸½‘`V÷P�¨îÿgÿÿÿÿ9ÿ[ÿxÿ•ÿªÿ´ÿ�ÿ7ÿ³þ!þ¤ýaýaý ý
þ…þÿ•ÿbµÿ3PYP6(8e¯ø"#ë}ñ^Ñÿhÿ ÿÿíþöþ(ÿkÿËÿ%y¤œg˜ÿ6ÿäþ¾þÃþùþTÿÃÿ0�›‹`Ñÿ�ÿ}ÿuÿ~ÿ¥ÿÚÿ%r·ô<LK8ÚŽHºÿ‘ÿÿŽÿ½ÿt©�G±ÿÿ}þCþkþòþ¾ÿªŒ:¨¿ƒø;^wÿªþþªý…ý‰ý¶ýèýþ5þLþcþŽþÈþ	ÿAÿcÿ€ÿ ÿ×ÿ0·`ŽèùÞ�#—í"OÿŒþöý–ýƒý—ý­ý§ý{ý/ýÕü�üvü©ü7ý#þQÿ§E[*®Ö˜ñÿà·¬¸ÿöþnþþËýÁýØýñýöýØý–ý3ýÈü‡ü…üÖüsýcþ”ÿðX»ß¤Þ•ÄžKWÿÿ	ÿ1ÿmÿ‹ÿqÿÿ“þþ«ý‚ý ýáý>þ·þ9ÿÂÿ@¾)ŽöhÝ*U/³ó.sÿùþ¸þžþ–þ~þZþþ¼ýSýüü¹ü²üåü\ýþèþÀÿŽ=¶ìôã¼›ˆ~`!º/˜ÿ	ÿ þQþ*þ!þ2þJþeþtþ}þlþ[þRþsþÌþmÿD5Í7D	—%Ï¡–™˜t'³7¿ÿkÿ2ÿÿÿMÿ’ÿpÃÄc¨ÿ¼þÕý+ýæüýüTýÝýlþæþ0ÿHÿ5ÿ
ÿÙþÑþõþHÿ±ÿV}…œÊ­Kâ?@ÌñÑ®ÿÃþEþ=þ�þ!ÿÂÿ;ws6ÖÿSÿ¿þ,þ³ý~ý¯ý@þÿ!1&ìv´¹z}å;‡ßÿDÿÃþ†þ€þ´þÿ„ÿáÿãÿxÿàþ=þµýlý–ýRþÿÿ‘üxN’[á_ÿöý=ýÕü�ülü0üÜûjûû¶ú°úûú¥û›ü¸ýÞþÞÿ³Ußr#ÿê·?b
?þq ÿÎýñü—üµü ýŒýÑýÙý¹ý„ý[ýeý±ý4þÎþsÿ|×Y‡É$Šñ.5êEH²þZýCü’ûgû¨û(üÆü`ýïý‚þ-ÿ÷ÿйœLÑ"8›â	.wÛÿùÿ1aNçÿDÿ�þÆýPý9ý“ýHþ,ÿÓO{^É’ˆ¢ÞE3äDfÿ|þÇýiýnýÉýaþùþhÿ‰ÿdÿÿ—þDþ0þnþôþ”ÿ@Ô2N]fx›á Xto/³D�ÿôþjþþÂý“ývýdýiýyý®ýûýdþáþjÿðÿ^©À¯ƒG!*aµm� lÁtG<Q‚¢Èàåß¼�Júÿ¡ÿQÿ"ÿÿ/ÿYÿiÿ\ÿ*ÿêþ¦þ€þˆþÖþKÿÌÿH½Jhj@îxîÿhÿÿþ¬þ‰þ‘þÆþ(ÿ²ÿZ³F¥¼‰2?^ÿªþ4þþ þcþÀþÿpÿ¥ÿ©ÿžÿ€ÿbÿNÿMÿgÿŽÿ¶ÿàÿTª+«7¨öúÃF—ÞjÿËþ=þ¿ýTýýýDý«ý2þÅþNÿ¼ÿKŒÚ6¨ž|P?jÏh†À”ñèšÿ¯ýgühûÎú•ú°úûÎû³üÈýïþÒ;]1¼g¼ÿ.ÿæþãþ'ÿ˜ÿc€VÚ
     } a, b;
     

Exemples

     struct cellule {
         char  **p;
         int    *t[10];
         int   (*f)();
     };

     struct cellule cel1, *cel2;
     struct cellule cel[15];

     struct boite {
         struct cellule  cel1;
         struct cellule *cel2;
         struct boite   *boite_suivante;
         int             ent;
     } b1, b2, *b3;
     


Un champ de bits est un ensemble de bits contigus à l'intérieur d'un même mot.

Le constructeur de structures permet de définir un découpage mémoire en champs de bits. Les membres de cette structure désignent les différents champs de bits. Ils doivent être du type unsigned int et indiquer le nombre de bits de chaque champ.

Syntaxe

     struct [ nom ] {
         unsigned int champ1 : longueur1;
         unsigned int champ2 : longueur2;
                   ...
         unsigned int champn : longueurn;
     };
     

Exemple

     struct {
         unsigned int actif  :  1;
         unsigned int type   :  3;
         unsigned int valeur : 14;
         unsigned int suivant: 14;
     } a, b;
     
Un champ peut ne pas avoir de nom. Sa longueur indique alors le nombre de bits que l'on veut ignorer. Une longueur égale à 0 permet de forcer l'alignement sur le début du mot mémoire suivant.

Exemple


     struct zone {
         unsigned int a:  8;
         unsigned int  :  0;
         unsigned int b:  8;
         unsigned int  :  8;
         unsigned int c: 16;
     };
     struct zone   z1, *z2;
     

Remarques



Le constructeur union permet de définir des données de type différent ayant la même adresse mémoire.

Syntaxe

     union [ nom ] {
        < liste de déclarations >
     };
     

Remarques

Exemples

     struct complexe {
         float x;
         float y;
     };

     union valeur {
         long   entier;
         float  reel;
         struct complexe complexe;
     };

     enum type {Entier, Reel, Complexe};

     struct nombre {
         enum type    type;
         union valeur valeur;
     };

     struct nombre n;
     

Exemples

     struct zone {
         int      nb_parm;
         char   **parm;
         union {
           unsigned char mask;
           struct {
              unsigned int a: 1;
              unsigned int b: 1;
              unsigned int c: 1;
              unsigned int d: 1;
              unsigned int e: 1;
              unsigned int f: 1;
              unsigned int g: 1;
              unsigned int h: 1;
           } drapeaux;
         } infos;
     } z1, *z2;
     

Retour début .

3.7 - Définitions de types

Il existe plusieurs manières de se définir de nouveaux types :

A la différence des constructeurs hétérogènes qui créent de nouveaux types, le constructeur typedef permet seulement de donner un nouveau nom à un type déjà existant.

Syntaxe

     typedef < déclaration >
     

Exemples

     typedeflong            size_t;
     typedefunsigned long   Cardinal;
     typedefchar           *va_list;
     typedefstruct complexe Complexe;
     typedefint             Matrice[10][20];

     Complexe  c1, *c2;
     Cardinal  nombre;
     va_list   arg;
     size_t    dimension;
     Matrice   tab, *ptr_mat;

     typedef struct cellule {
         Cardinal        n;
         struct cellule *ptr_suivant;
     } Cellule;

     Cellule cel1, *cel2;
     

Une expression de type est une expression construite en retirant l'objet de la déclaration qui le définit.

Exemples

     char     *c;
     int       (*f)();
     char      (*tab)[100];
     char      (*(*x())[6])();
     char      (*(*vec[3])())[5];
     Complexe  (**ptr)[5][4];
     
Les types des objets déclarés précédemment sont donnés par les expressions de types suivant :
     char     *
     int      (*)()
     char     (*)[100]
     char     (*(*())[6])()
     char     (*(*[3])())[5]
     Complexe (**)[5][4]
     

Retour début


.

4 - Expressions et opérateurs

Retour début .

4.1 - Constantes littérales

Constantes entières

Une constante entière peut s'écrire dans les systèmes décimal, octal ou hexadécimal.

Une constante entière préfixée :

Une constante entière est par défaut de type int. Elle est de type long si elle est suffixée par les lettres l ou L et non signée lorsqu'elle est suffixée par les lettres u ou U.

Exemples

base102256178932765
22u56L29UL1L
base 80643017706440755
0177L0222UL0777u0766ul
base160xff0Xabcd0x800X1
0xffL0X1uL0X7fU0x5fUL

Constantes réelles

Une constante réelle (ou constante en virgule flottante) est un nombre exprimé en base 10 contenant un point décimal et éventuellement un exposant séparé du nombre par la lettre e ou E.

Une constante réelle est par défaut de type double. Elle sera du type float si on la suffixe par la lettre f ou F.

Exemples

0.1.0.21789.5629
50000.0.00074312.3315.0066
2E-80.006e-31.66E+83.1415927
1.6021e-19f6.0225e23F2.7182816.6262e-34

Constantes caractères

Une constante caractère est assimilée à un entier sur un octet dont la valeur correspond au rang du caractère dans la table ASCII.

Une constante caractère est constituée soit :


Séquences d'échappement

SyntaxeSéq. d'éch.Code ASCII
sonnerie\a7
retour arrière\b8
tabulation h.\t9
tabulation v.\v11
retour à la ligne\n10
nouvelle page\f12
retour chariot\r13
guillemets\"34
apostrophe\'39
point d'interr.\?63
antislash\\92
caractère nul\00

Exemples

                          Valeur entière associée
        'A'      ====>            65
        'x'      ====>           120
        '3'      ====>            51
        '$'      ====>            36
        ' '      ====>            32
        '\n'     ====>            10
        '\t'     ====>             9
        '\b'     ====>             8
        '\"'     ====>            34
        '\\'     ====>            92
        '\''     ====>            39
        '\0'     ====>             0
        '\177'   ====>           127
        '\x0a'   ====>            10
        '\000'   ====>             0
  

Constantes chaîne de caractères

Une constante chaîne de caractères est une suite de caractères entre guillemets.

En mémoire cette suite de caractères se termine par le caractère NULL ('\0').

La valeur d'une chaîne de caractères est l'adresse du premier caractère de la chaîne qui est donc du type pointeur de caractères (char *).

Ne pas confondre "A" et 'A' qui n'ont pas du tout la même signification !

Pour écrire une chaîne de caractères sur plusieurs lignes on peut :

Exemples

char *chaine = "\
\n\
\t/----------------------------------------------\\\n\
\t| Pour écrire une chaîne sur plusieurs lignes, |\n\
\t|   il suffit de terminer chaque ligne par \\  |\n\
\t\\---------------------------------------------/\n";

char *chaine = "écriture d'une "
               "chaîne de caractères "
               "sur plusieurs "
               "lignes\n\n";
  

Retour début .

4.2 - Constantes symboliques

Les constantes symboliques sont de plusieurs types :

Exemple

        char    tab[100];
        double  func(int i)
        {
              ...
        }
        const   int   nombre;
        const   char *ptr1;
        char   const *ptr2;
        char * const  ptr3;
     
Les objets précédents sont respectivement :

Retour début .

4.3 - Opérateurs arithmétiques

Une expression est constituée de variables et constantes (littérales et/ou symboliques) reliées par des opérateurs. Il existe 5 opérateurs arithmétiques : Leurs opérandes peuvent être des entiers ou des réels hormis ceux du dernier qui agit uniquement sur des entiers. Lorsque les types des deux opérandes sont différents, il y a conversion implicite dans le type le plus fort suivant certaines règles.

Règles de conversions

Les opérateurs + et - admettent des opérandes de type pointeur, ceci pour permettre notamment de faire de la progression d'adresse.

OpérateurOp. 1Op. 2Résultat
+pointeurentierpointeur
+entierpointeurpointeur
-pointeurentierpointeur
-pointeurpointeurentier

Exemples

    char  *pc;
    int   *pi;
    int    a, b, c;
        ...
        ...
    c  = 2*a + b%2;
    pc = pc + a;
    pi = pi - c;
  

Retour début .

4.4 - Opérateurs logiques

Le type booléen n'existe pas. Le résultat d'une expression logique vaut 1 si elle est vraie et 0 sinon. Réciproquement toute valeur non nulle est considérée comme vraie et la valeur nulle comme fausse.

Les opérateurs logiques comprennent :

Le résultat de l'expression :

Exemple

  int   i;
  float f;
  char  c;

  i = 7;
  f = 5.5;
  c = 'w';

  f > 5                    ====>  vrai (1)
  (i + f) <= 1             ====>  faux (0)
  c == 119                 ====>  vrai (1)
  c != 'w'                 ====>  faux (0)
  c >= 10*(i + f)          ====>  faux (0)
  (i >= 6) && (c == 'w')   ====>  vrai (1)
  (i >= 6) || (c == 119)   ====>  vrai (1)
  (f < 11) && (i > 100)    ====>  faux (0)
   

Retour début .

4.5 - Opérateur de taille

L'opérateur sizeof renvoie la taille en octets de son opérande. L'opérande est soit une expression soit une expression de type.

Syntaxe

     sizeof  expression
     sizeof (expression-de-type)
     
L'opérateur sizeof appliqué à une constante chaîne de caractères renvoie le nombre de caractères de la chaîne y compris le caractère NULL de fin de chaîne.

Si p est un pointeur sur un type t et i un entier :

      l'expression  p + i
      a pour valeur p + i*sizeof(t)
     

Exemples

int menu[1000];
typedef struct cel {
      int         valeur;
      struct cel *ptr;
} CEL;

sizeof menu / sizeof menu[0]
                    ===> nombre d'éléments
                         du vecteur menu.

sizeof(long)       ===> taille d'un entier long.
sizeof(float)      ===> taille d'un flottant
                        simple précision.
sizeof(struct cel) ===> taille d'un objet du
                        type struct cel.
sizeof(CEL)        ===> taille d'un objet du
                        type CEL.
     

Retour début .

4.6 - Opérateurs d'adressage et d'indirection

L'opérateur & appliqué à un objet renvoie l'adresse de cet objet. L'opérateur * s'applique à un pointeur et permet d'effectuer une indirection c'est-à-dire retourne l'objet pointé. Si vect est un vecteur, la valeur de la constante symbolique vect est égale à &vect[0]. Si a est un objet de type t, &a est de type t *. Réciproquement, si p est un objet de type t *, *p est de type t.

Exemples

        int  u;
        int  v;
        int *pu;
        int *pv;
        typedef struct cel {
           int         valeur;
           struct cel *ptr;
        } CEL;
        CEL  c1, *c2;

        u  = 3 ;
        pu = &u ;
        v  = *pu ;
        pv = &v ;
        c2 = &c1 ;
     

Retour début .

4.7 - Opérateur de forçage de type

Il est possible d'effectuer des conversions explicites à l'aide de l'opérateur de forçage de type ou cast.

Syntaxe

     (type) expression
     (expression-de-type) expression
     

Exemples

int    n;
int    tab[100];
int    (*p)[2];
double puissance;

n = 10;
puissance = pow((double)2, (double)n);
p = (int (*)[2])tab;
**(p+49)     = 1756;
*(*(p+49)+1) = 1791;
     

Schéma d'adressage
** Schéma adressage

La fonction pow est la fonction exponenciation, elle renvoie 2n dans l'exemple précédent.

Retour début .

4.8 - Opérateurs de manipulations de bits

Opérateurs arithmétiques "bit à bit"

Ils correspondent aux 4 opérateurs classiques de l'arithmétique booléenne :

Les opérandes sont de type entier. Les opérations s'effectuent bit à bit suivant la logique binaire.

b1 b2 ~b1 b1&b2 b1|b2 b1^b2
110110
100011
011011
001000

Exemples

int a, b, c, flag;
int Mask;

a = 0x6db7;
b = 0xa726;
c = a&b ;        ===> 0x2526
c = a|b ;        ===> 0xefb7
c = a^b ;        ===> 0xca91
flag = 0x04;
c = Mask & flag;
c = Mask &  flag;

Opérateurs de décalage

Il existe 2 opérateurs de décalage :

Le motif binaire du 1er opérande, qui doit être un entier, est décalé du nombre de bits indiqué par le 2e opérande.

Dans le cas d'un décalage à gauche les bits les plus à gauche sont perdus. Les positions binaires rendues vacantes sont remplies par des 0.

Lors d'un décalage à droite les bits les plus à droite sont perdus. Si l'entier à décaler est non signé les positions binaires rendues vacantes sont remplies par des 0, s'il est signé le remplissage s'effectue à l'aide du bit de signe.

Exemple

int  etat;
int  oct;
int  ent;
int  a;

a = 0x6db7;
a = a << 6;                 ===>  0x1b6dc0
a = 0x6db7;
a = a >> 6;                 ===>  0x1b6
ent = 0xf0000000;
ent = ent >> 10;            ===>  0xfffc0000
oct = (etat >> 8) & 0xff;
  

Retour début .

4.9 - Opérateurs à effet de bord

Ce sont des opérateurs qui modifient l'ensemble des valeurs courantes des variables intervenant dans l'évaluation d'expressions.

Opérateurs d'affectation

Les opérateurs d'affectation sont :

L'affectation est une expression. La valeur de ce type d'expression est la valeur de l'expression située à droite de l'affectation.

On appelle g-valeur toute expression pouvant figurer à gauche d'une affectation. Un identificateur de vecteur n'est pas une g-valeur.

Une expression de la forme :

     e1 op= e2      est équivalente à
     e1 = e1 op e2
     

Exemple

int           valeur;
int           i;
char          c;
unsigned char masque;
int           n;

...

valeur >>= i;
c       &= 0x7f;
masque  |= 0x1 << (n - 1);
masque  &=  (0x1 << (n - 1));
     

Opérateurs d'incrémentation et de décrémentation

Les opérateurs d'incrémentation (++) et de décrémentation (--) sont des opérateurs unaires permettant respectivement d'ajouter et de retrancher 1 au contenu de leur opérande.

Cette opération est effectuée après ou avant l'évaluation de l'expression suivant que l'opérateur suit ou précède son opérande.

Ces opérateurs ne s'appliquent qu'à des g-valeurs.

Exemple

int   i;
int   j;
int   tab[100];
char  buffer[2048];
char *ptr;
int  *p_ent;

i = 99;
j = 2;
i++;
p_ent  = tab;
*(p_ent + --i) = ++j;
ptr    = buffer;
*ptr++ = '\n';
    

Retour début .

4.10 - Opérateur conditionnel

L'opérateur conditionnel (?:) est un opérateur ternaire. Ses opérandes sont des expressions.

Syntaxe

     expr1 ? expr2 : expr3
     
La valeur de l'expression expr1 est interprétée comme un booléen. Si elle est vraie, c'est-à-dire non nulle, seule l'expression expr2 est évaluée sinon c'est l'expression expr3 qui est évaluée.

La valeur de l'expression conditionnelle est la valeur de l'une des expressions expr2 ou expr3 suivant que l'expression expr1 est vraie ou fausse.

Exemple

int i;
int indic;
int a, b;
int c;

...

indic = (i < 0) ? 0 : 100;
c    += (a > 0 && a <= 10) ? ++a : a/b;
c     = a > b ? a : b;
     

Retour début .

4.11 - Opérateur séquentiel

L'opérateur séquentiel (,) permet de regrouper des sous-expressions sous forme de liste. Ces sous-expressions sont évaluées en séquence. La valeur d'une liste d'expressions est celle de la dernière de la liste.

Exemple

int    i;
float  r;
double dble, d;
char  *ptr;
char   buffer[100];

d = (i = 1, r = 2.718f, dble = 2.7182818);
r = (float)(ptr = buffer, i = 10);
     

Retour début .

4.12 - Autres opérateurs

Opérateur d'indexation

Cet opérateur ([ ]) permet de référencer les différents éléments d'un vecteur. C'est un opérateur binaire dont l'un des opérandes est un identificateur de vecteur ou un pointeur et l'autre opérande un entier.

Si p est un pointeur ou un identificateur de vecteur et n un entier, alors l'expression p[n] désigne le (n+1)e élément à partir de l'adresse p, c'est-à-dire l'élément situé à l'adresse p+n.

Cette expression est donc équivalente à *(p+n).

Exemple

  char  buffer[4096];
  char *ptr;
  int   i;
  int   ta[5], tb[5], tc[5];

  buffer[10] = 'a';
  *(buffer + 9) = 'b';
  i = 0;
  buffer[i++] = 'c';
  i  += 15;
  ptr = buffer + i;
  ptr[0] = 'd';
  *++ptr = 'e';
  *ta = 1, *tb = 2;
  tc[0] = ta[0] + tb[0];
  

Opérateur d'appel de fonction

C'est l'opérateur () qui permet de déclencher l'appel à la fonction dont le nom précède. Ce nom peut être soit un identificateur de fonction, soit un pointeur de fonction.

A l'intérieur de ces parenthèses, apparaît éventuellement une liste d'expressions appelées paramètres qui sont évaluées puis transmises à la fonction. L'ordre d'évaluation de ces expressions est indéterminé.

Exemple

char *f(int i, float x);
char *(*pf)(int i, float x);
char *ptr;
int   i;
float x;

i = 2, x = 1.;
ptr = f(i, x);
pf = f;
i = 10, x *= 2.;
ptr = (*pf)(i, x);
/* non portable */
ptr = (*pf)(i++, x = (float)i);
/*              */
i++;
ptr = (*pf)(i, x = (float)i);
     

Opérateurs de sélection de champ

L'opérateur . permet d'accéder aux champs d'une structure ou d'une union. Il est binaire. Le 1er opérande doit être une structure ou une union et le 2e opérande doit désigner l'un de ses champs.

Le type et la valeur de l'expression op1.op2 sont ceux de op2.

Pour accéder à un champ ch d'une structure ou d'une union pointée par un pointeur ptr, on écrira l'expression (*ptr).ch qui est équivalente à ptr->ch.

Exemple

typedef struct cellule {
    int    n;
    char  *c;
    int    nb_parm;
    char **parm;
} CEL, *PTR_CEL;
typedef struct boite {
    int     nb_boite;
    PTR_CEL cel;
} BOITE;
CEL     c1;
PTR_CEL ptr_cel;
BOITE   b[10], *p_boite;
c1.n         = 10;
c1.c         = "nom de la cellule";
ptr_cel      = &c1 ;
ptr_cel->n   = 20;
b[0].cel     = ptr_cel;
b->nb_boite  = 5;
b[0].cel->n++;
b->cel->n++;
b[1] = b[0]; p_boite = &b[1];
p_boite->cel = (PTR_CEL)0;
     

Retour début


.

5 - Portée et visibilité

Retour début .

5.1 - Niveau d'une variable

Le niveau d'une variable est déterminé par l'emplacement de sa déclaration dans le programme.

Exemple

Cardinal  nb_elements;     /* niveau 0 */
size_t    taille;          /* niveau 0 */
main()
{
    int   i, j;            /* niveau 1 */
    char  c;               /* niveau 1 */
    {
        Complexe  c1, *c2; /* niveau 2 */
        int       i;       /* niveau 2 */
        if (...) {
          char car;        /* niveau 3 */
            ...
        }
    }
      ...
}
int   ent;                 /* niveau 0 */
void f(void)
{
    long  i;               /* niveau 1 */
      ...
}

Retour début .

5.2 - Durée de vie d'une variable

La durée de vie d'une variable est le temps pendant lequel cette variable a une existence en mémoire. Une variable peut avoir une durée de vie :

Retour début .

5.3 - Classes de mémorisation

Il existe quatre classes de mémorisation :

Les classes static et extern concernent les variables permanentes. Les classes auto et register concernent les variables temporaires. C'est au moment de la déclaration des variables que ces attributs peuvent être spécifiés.

Exemples

       extern          int i;
       static unsigned int j;
       register        int n;
     

Retour début .

5.4 - Portée d'une variable interne

La portée ou la visibilité d'une variable est l'endroit du programme où elle existe et est accessible. La portée d'une variable interne est le bloc où elle est déclarée ainsi que tous les blocs contenus dedans à l'exception de ceux dans lesquels cette variable a fait l'objet d'une redéclaration. Pour déclarer une variable interne permanente il suffit de mentionner l'attribut static lors de sa déclaration.

Par défaut, en l'absence d'attribut de classe mémoire, une variable interne est temporaire et reçoit l'attribut auto. Ce type de variable est alloué dynamiquement dans le << stack >> ou pile d'exécution (pile de type LIFO).

Lorsqu'une variable est très utilisée, il peut être avantageux de demander au compilateur qu'elle soit, dans la mesure du possible, rangée dans un registre de la machine. Cette possibilité, qui ne peut s'appliquer qu'à des variables temporaires, ne sera satisfaite que s'il existe des registres disponibles au format de la donnée. C'est l'attribut register spécifié à la déclaration qui permet de formuler une telle demande.

Exemple

main()
{
  int a = 1, b = 2;
  a++, b++;
  {
    char b = 'A'; int  x = 10;
    a++, b++, x++;
    {
      int a = 100, y = 200;
      a++, b++, x++, y++;
      {
        char a = 'L'; int  z = -5;
        a++, b++, x++, y++, z++;
      }
      a++, b++, x++, y++;
    }
    a++, b++, x++;
  }
}

Retour début .

5.5 - Portée d'une variable externe

A - Programme monofichier

La portée d'une variable externe est l'ensemble du source à partir de l'endroit où celle-ci a été déclarée.

Cela implique que seules les fonctions définies après la déclaration des variables externes peuvent y accéder.

Dans une fonction, une variable externe est masquée lorsqu'elle subit une redéclaration au sein de cette fonction.

Exemple

int i = 10;
main()
{
    ...           /* la variable externe r
                     n'est pas visible. */
  {
     int i = 20;  /* dans ce bloc la variable
                     externe i est masquée. */
         ...
  }
}
float r = 3.14;
void f(...)
{
    ...
  {
     double r;    /* dans ce bloc la variable
                     externe r est masquée. */
         ...
  }
    ...
}

Dans une fonction, il est possible de rendre une variable externe visible si elle ne l'était pas déjà. Il suffit de la référencer en indiquant l'attribut extern.

Exemple

double y = 10.123;
   ...
main()
{
  int y;    /* y déclarée en externe
               est masquée. */
   ...
  {
    extern double y; /* On rend la variable
                         externe y a nouveau
                         accessible.  */
      ...
  }
   ...
}

Exemple

main()
{
   ...     /* la variable externe z
              n'est pas visible */
}
void f(void)
{
   extern float z; /* la variable externe
                      z est visible dans f. */
       ...
}
int g(void)
{
   ...     /* la variable externe z
              n'est pas visible */
}
float z = 2.0;
float h(int i)
{
   /* la variable externe z
      est visible dans h ainsi que
      dans les fonctions suivantes. */
}

B - Programme multifichiers

L'unité de compilation est le fichier. Les différents fichiers sources constituant une application sont donc traités de façon indépendante par le compilateur.

Lorsque l'on a besoin de partager une variable entre ces différents fichiers, on devra allouer son emplacement mémoire dans un seul de ces fichiers et la référencer dans les autres. On parlera de définition lorsque la mémoire est allouée et de déclaration lors d'une référence.

Tous les compilateurs (avant et après la norme) considèrent :

Les compilateurs de l'après-norme admettent l'attribut extern dans les deux cas. Pour ceux-là une simple initialisation suffit pour indiquer une définition.

Exemple

source1.c

main()
{
   ...
}
extern int i; /* déclaration de la
                  variable externe i. */
void f(int a)
{
   ...
}

source2.c

int i = 11; /* définition de la
                variable externe i. */
int g(void)
{
   ...
}
source3.c
float h(void)
{
   ...
}
extern int i; /* déclaration de la
                  variable externe i. */
void func(void)
{
   ...
}
De plus la norme dit qu'une variable sans l'attribut extern et sans initialisation fait l'objet d'une définition potentielle.

Si pour une variable n'apparaîssent que des définitions potentielles, l'une sera considérée comme définition et les autres comme déclarations. Cette variable sera initialisée avec des zéros binaires.

Exemple

  sourceA         sourceB          sourceC
int x = 10;   | extern int x;    | extern int x;
extern int y; | extern int y;    | extern int y;
int z;        | extern int z;    | extern int z;
int a;        |                  | int a;
int b = 20;   | int b = 21;      |
int c;        | int c = 30;      |
              |                  |
main()        | int calcul(void) | int somme(void)
{             | {                | {
    ...       |       ...        |      ...
}             | }                | }

On peut limiter la portée d'une variable au source au sein duquel elle est définie. Pour cela on indiquera l'attribut static au moment de sa définition.

Exemple

      sourceA               sourceB
static float r = 2.154;  |  void f2(void)
double dble = 17.89;     |  {
main()                   |     ...
{                        |  }
   ...                   |  extern double dble;
}                        |  int f3(int i)
float f1(void)           |  {
{                        |     ...
   ...                   |  }
}                        |  static int n = 10;
                         |  void f4(float r)
                         |  {
                         |     ...
                         |  }

Retour début .

5.6 - Initialisation des variables

Il est possible d'initialiser une variable lors de sa déclaration.

Syntaxe

     type construction = expression;
     

L'initialisation des variables permanentes doit se faire à l'aide d'expressions constantes :
Par contre l'initialisation des variables temporaires peut se faire à l'aide d'expressions quelconques.

Exemple

static int   n    = 10 ;
static char *ptr  = "Aix-en-Provence" ;
static int  *p    = &n ;
static int   etat = 0x1 << 5 ;
int flag = etat;               <==>  int flag;
                                     flag = etat;
     
L'initialisation des vecteurs, des structures ou des unions s'effectue au moyen de listes de valeurs entre accolades :
         {val1, val2, ..., valn}
     

Si l'élément d'un vecteur est lui-même un vecteur on applique récursivement la notation précédente. L'initialisation des vecteurs doit se faire au moyen d'expressions constantes.

Seule la première composante d'une union peut être initialisée.

Exemple

int   tab1[5] = { 2, 6, 8, 10, 17};
int   tab2[]  = { 3, 7, 10, 18, 16, 3, 1};
char  v1[]    = "Wolfgang Amadeus Mozart";
char  v2[]    = "musique";
char  v3[]    = {'m', 'u', 's', 'i',
                 'q', 'u', 'e', '\0'};
char *p       = "musique";
typedef struct date {
   int   jour, mois, annee;
} Date;
typedef struct {
   char  sexe;
   char *nom;
   Date  annee_naiss;
} Individu;
Individu tab[] = {
           {'F', "France Nathalie", {1,  7, 65}},
           {'M', "Deneau Michel",   {8, 10, 61}}
                 };
union donnees {
   int   i;
   float r;
} u = {2};
     

Exemple

int tab[3][4] = {
                  {1, 2,  7, 11},
                  {2, 3, 12, 13},
                  {4, 8, 10, 11}
                };
int t1[][4]   = {
                  {1},
                  {2, 3},
                  {4, 8, 10}
                };
int t2[3][4]  = {1, 0, 0, 0, 2, 3, 0, 0,
                 4, 8, 10, 0};
int t3[][3]   = {0, 1, 2, 3, 8, 9, 9, 1};
int t4[2][3][4] = {
                    {
                       {1, 2, 3, 8},
                       {3, 2},
                       {1}
                    },
                    {
                       {3, 4, 9},
                       {2}
                    } };
     

Retour début .

5.7 - Visibilité des fonctions

La définition d'une fonction comprend un en-tête (appelé prototype), indiquant le type de la valeur qu'elle retourne ainsi que la liste et le type des arguments transmis, et une instruction composée (appelée corps de la fonction), renfermant des déclarations d'objets et des instructions exécutables.

La déclaration d'une fonction s'effectue au moyen de son prototype.

Lors de l'appel à une fonction, pour que le compilateur connaisse le type de la valeur qu'elle retourne et puisse vérifier le nombre ainsi que le type des arguments transmis, il est nécessaire qu'il ait visibilité sur le prototype de cette fonction.

Cette visibilité existe lorsque :

Lorsque que le compilateur n'a pas cette visibilité, il suppose que la valeur retournée par la fonction est de type int.

Une fonction ne peut être contenue dans une autre fonction, de ce fait toutes les fonctions sont externes. C'est pourquoi préciser l'attribut extern, que ce soit lors de la déclaration ou lors de la définition de la fonction, n'apporte aucune information supplémentaire.

A l'instar des variables, une fonction peut n'être connue que dans le fichier dans lequel elle a été définie. Pour cela on indiquera l'attribut static lors de sa définition.

Exemple


      sourceA              sourceB
float f(double d);       |  int g(void)
main()                   |  {
{                        |     int i;
   float  r;             |     int j;
   double d;             |     static int h(int i);
                         |       ...
   r = f(d);             |     j = h(i);
   ...                   |  }
}                        |  void func(int i)
static float f(double d) |  {
{                        |   /* la fonction h n'est
   int g(void);          |      pas visible ici. */
   int i;                |  }
                         |  static int h(int i)
   i = g();              |  {
   ...                   |     ...
}                        |  }

Retour début


.

6 - Instructions

Retour début .

6.1 - Instructions élémentaires

Une instruction élémentaire est une expression terminée par un ;.

Contrairement aux expressions, les instructions n'ont ni type ni valeur. Lorsqu'on forme une instruction à partir d'une expression la valeur de cette dernière est perdue.

N'importe quelle expression peut former une instruction, même lorsqu'elle ne génère pas d'effet de bord.

Une instruction composée ou bloc est un ensemble d'instructions élémentaires et/ou composées, précédées éventuellement de déclarations, délimité par des accolades.

Exemple

#include <stdio.h>
#include <math.h>
main()
{
  int    i = 10;
  double r = acos(-1.);

  i *= 2;
  {
     double cosh_pi;

     cosh_pi = (exp(r) + exp(-r)) / 2;
     printf("cosh_pi : %f\n", cosh_pi);
  }
}
   

Retour début .

6.2 - Structures de contrôle

Les structures de contrôle sont les tests, les boucles et l'aiguillage.
.

6.2.1 - Les tests : syntaxe

     if (expression)
        partie-alors
     [else
        partie-sinon]
     

La partie-alors et la partie-sinon peuvent être indifféremment une instruction élémentaire ou composée.

La partie-alors sera exécutée si la valeur de l'expression entre parenthèses est non nulle. Sinon, si le test comporte une partie-sinon c'est celle-ci qui sera exécutée.

Exemple

char buffer[2048];
void f(void)
{
   static char *p = (char *)0;

   if (!p)
     p = buffer;
   else {
     *p = '1';
     p++;
   }
}
     

Si plusieurs tests sont imbriqués, chaque partie-sinon est reliée au if le plus proche qui n'est pas déjà associé à une partie-sinon.

Exemple

if (x > 0)                   if (x > 0)
  ecrire("positif");           ecrire("positif");
else if (x < 0)       <==>   else
  ecrire("negatif");         {
else                           if (x < 0)
  ecrire("nul");                 ecrire("negatif");
                               else
                                 ecrire("nul");
                             }
     

Retour début .

6.2.2 - Les boucles "tant-que" : syntaxe

     while (expression)
         corps-de-boucle

     do
         corps-de-boucle
     while (expression);
     

La partie corps-de-boucle peut être soit une instruction élémentaire soit une instruction composée.

Dans la boucle while le test de continuation s'effectue avant d'entamer le corps-de-boucle qui, de ce fait, peut ne jamais s'exécuter.

Par contre dans la boucle do-while ce test est effectué après le corps-de-boucle, lequel sera alors exécuté au moins une fois.

Exemple

#include <stdio.h>
main()
{
   int chiffre = 0;

   printf("Boucle \"while\"\n\n");
   while (chiffre) {
      printf(" %d", chiffre++);
      if (!(chiffre%5))
        printf("\n");
   }
   printf("Boucle \"do-while\"\n\n");
   do {
      printf(" %3d", ++chiffre);
      if (!(chiffre%5))
        printf("\n");
      if (chiffre == 100)
        chiffre = 0;
   }
   while (chiffre);
}
     

Retour début .

6.2.3 - La boucle "pour" : syntaxe

     for ([expr1]; [expr2]; [expr3])
         corps-de-boucle
     

L'expression expr1 est évaluée une seule fois, au début de l'exécution de la boucle.

L'expression expr2 est évaluée et testée avant chaque passage dans la boucle.

L'expression expr3 est évaluée après chaque passage.

Ces 3 expressions jouent respectivement le rôle :

Exemple

main()
{
  int   tab[] = {1, 2, 9, 10, 7, 8, 11};
  int   i, j;
  char  buffer[] = "Voici une chaine"
                   " qui se termine "
                   "par un blanc ";
  char *p;
  int   t[4][3];

  for (i=0; i < sizeof tab / sizeof tab[0]; i++)
     printf("tab[%d] = %d\n", i, tab[i]);

  for (p=buffer; *p; p++)
       ;
  *--p = '\0';
  printf("buffer : %s$\n", buffer);
  for (i=0; i < 4; i++)
    for (j=0; j < 3; j++)
      t[i][j] = i + j;
}
     

Retour début .

6.2.4 - L'aiguillage

L'instruction switch définit un aiguillage qui permet d'effectuer un branchement à une étiquette de cas en fonction de la valeur d'une expression.

Syntaxe

     switch (expression)
     {
        case etiq1 :
        [ liste d'instructions ]
        case etiq2 :
        [ liste d'instructions ]
              ...
        case etiqn :
        [ liste d'instructions ]
     [ default:
        [ liste d'instructions ]]
     }
     

Les étiquettes de cas (etiq1, etiq2, ..., etiqn) doivent être des expressions constantes.

Une fois le branchement à l'étiquette de cas correspondante effectué, l'exécution se poursuit, par défaut, jusqu'à la fin du bloc switch. L'instruction d'échappement break; permet de forcer la sortie du bloc.

L'expression indiquée au niveau du switch doit être de type entier.

Exemple

#include <stdio.h>
main()
{
  char *buffer = "\nCeci est une chaine\n"
                 "de caracteres\tsur\n\n"
                 "plusieurs     lignes.\n";
  int   NbCar  = 0, NbEsp = 0, NbLignes = 0;

  for (; *buffer; buffer++, NbCar++)
    switch (*buffer) {
      case '\n': NbLignes++;
                 break;
      case '\t':
      case ' ' : NbEsp++;
      default  : break;
    }
  printf("NbCar = %d, NbEsp = %d, NbLignes = %d\n",
          NbCar, NbEsp, NbLignes);
}
     

Retour début .

6.3 - Instructions d'échappement

Ces instructions permettent de rompre le déroulement séquentiel d'une suite d'instructions.

Instruction continue;

Le rôle de l'instruction continue; est de forcer le passage à l'itération suivante de la boucle la plus proche.

Exemple

#include <stdio.h>
main()
{
  char *buffer = "\nCeci est une chaine\n"
                 "de caracteres\tsur\n\n"
                 "plusieurs     lignes.\n";
  int   NbCar  = 0, NbEsp = 0, NbLignes = 0;

  for (; *buffer; buffer++) {
    switch (*buffer) {
      case '\n': NbLignes++;
                 break;
      case '\t': continue;
      case ' ' : NbEsp++;
      default  : break;
    }
    NbCar++;
  }
  printf("NbCar = %d, NbEsp = %d, NbLignes = %d\n",
          NbCar, NbEsp, NbLignes);
}
     

Instruction break;

L'instruction break; permet de quitter la boucle ou l'aiguillage le plus proche.

Exemple

#include <stdio.h>
main()
{
   char *buffer = "Wolfgang Amadeus Mozart\n"
                  " est un musicien divin.\n";
   char *p;

   for (p=buffer; *p; p++)
     if (*p == '\n')
     {
       *p = '\0';
       break;
     }
   printf("Nom : %s\n", buffer);
}
     

Instruction return; : syntaxe

     return [expression];
     

Cette instruction permet de sortir de la fonction qui la contient :

Exemple

#include <stdio.h>
void main()
{
   char c;
   char majus(char c);

     ...

   printf("%c\n", majus(c));
   return;
}
char majus(char c)
{
   return c >= 'a' && c <= 'z' ?
          c + 'A' - 'a' : c;
}
     

Instruction go to;

Cette instruction sert à effectuer un transfert inconditionnel vers une autre partie du programme.

Syntaxe

     goto étiquette;
     

Etiquette fait référence à une instruction étiquetée. On utilisera cette instruction avec parcimonie car elle nuit à l'écriture de programme structuré. Elle peut à la rigueur être utilisée lorsque l'on désire sortir de plusieurs boucles imbriquées, ce que ne permet pas l'instruction break;.

Exemple

#include <stdio.h>
main()
{
   int tab[][4] = {1, 2, 8, 9, 10, 12, 1, 9, 5};
   int i, j;

   for (i=0; i < sizeof tab / sizeof tab[0]; i++)
     for (j=0; j < 4; j++)
       if (tab[i][j] == 10)
         goto trouve;

   fprintf(stderr, "Element non trouve.\n");
   return 1;

trouve:
   printf("L'élément tab[%d][%d]"
          " est égal à 10.\n", i, j);
}
     


Un programme peut être interrompu au moyen de la fonction exit.

Syntaxe

     exit(expression);
     

L'argument de cette fonction doit être un entier indiquant le code de terminaison du processus.

Exemple

#include <stdio.h>
main()
{
   int tab[][4] = {1, 2, 8, 9, 10, 12, 1, 9, 5};
   int i, j;

   for (i=0; i < sizeof tab / sizeof tab[0]; i++)
     for (j=0; j < 4; j++)
       if (tab[i][j] == 10) {
         printf("L'élément tab[%d][%d]"
                " est égal à 10.\n", i, j);
         return 0;
       }
   fprintf(stderr, "Element non trouve.\n");
   exit(1);
}
     

Retour début


.

7 - Préprocesseur

Retour début .

7.1 - Introduction

Le préprocesseur effectue un prétraitement du programme source avant qu'il soit compilé.

Ce préprocesseur exécute des instructions particulières appelées directives.

Ces directives sont identifiées par le caractère # en tête. Elles peuvent se continuer sur plusieurs lignes, chaque ligne à continuer étant terminée par le caractère \ suivi d'un return.

Retour début .

7.2 - Pseudo-constantes

La directive #define permet la définition de pseudo-constantes.

Une pseudo-constante est un identificateur composé de lettres et de chiffres commençant par une lettre. (Le caractère _ est considéré comme une lettre).

Syntaxe

    #define identificateur [chaîne-de-substitution]
    

Le préprocesseur remplace tous les mots du fichier source identiques à l'identificateur par la chaîne-de-substitution.

On préférera n'utiliser que des majuscules pour écrire ces identificateurs afin de les différencier des autres (variables, vecteurs, fonctions).

Exemple

#define  TAILLE 256
#define  TAILLE_EN_OCTETS \
          TAILLE*sizeof(int)
main()
{
   int  tab[TAILLE];
   int  i;

   for(i=0; i < TAILLE; i++)
     tab[i] = i;
   printf("Le tableau tab contient %d octets\n",
          TAILLE_EN_OCTETS);
}
    

Remarque

La directive #undef permet d'annuler la définition d'une pseudo-constante.

Pseudo-constantes prédéfinies

La plupart des préprocesseurs reconnaissent les pseudo-constantes prédéfinies suivantes :

Retour début .

7.3 - Pseudo-fonctions


Les pseudo-fonctions ou macros sont des substitutions paramétrables.

Exemple

#define ABS(x) x>0 ? x : -x
#define NB_ELEMENTS(t) sizeof t / sizeof t[0]
#include <stdio.h>
#include <math.h>
main()
{
  int    tab[][2] = { 1,  2,  3,  9,
                     10, 11, 13, 16};
  double r = -acos(-1.);
  int    i, j;

  for(i=0; i < NB_ELEMENTS(tab); i++)
    for(j=0; j < 2; j++)
      tab[i][j] = i + j;

  printf("%f\n", ABS(r));
}
    

Remarques


Exemple

#define CARRE(x)   x*x
main()
{
    float x = 1.12;
/*
    Erreur : l'instruction suivante
             calcule 2*x+1 et non pas
             le carre de x+1.
*/
    printf("%f\n", CARRE(x+1));
}
    

Exemple

#define CARRE(x)   (x)*(x)
#define MAX(a,b)   ( (a) > (b) ? (a) : (b) )
main()
{
    float x = 3.1, y = 4.15;
    printf("%f\n", CARRE(x+1));
    printf("%f\n", MAX(x+10., y));
/*
    Erreur : l'instruction suivante
             provoque une double
             incrémentation de x.
*/
    y = CARRE(x++);
}
    

Retour début .

7.4 - Inclusion de fichiers

La directive #include permet d'insérer le contenu d'un fichier dans un autre.

Ce mécanisme est en général réservé à l'inclusion de fichiers appelés fichiers en-tête contenant des déclarations de fonctions, de variables externes, de pseudo-constantes et pseudo-fonctions, de définition de types. Ces fichiers sont traditionnellement suffixés par .h.

Syntaxe

    #include <nom-de-fichier>
    #include "nom-de-fichier"
    
Si le nom du fichier est spécifié entre guillemets, il est recherché dans le répertoire courant. On peut indiquer d'autres répertoires de recherche au moyen de l'option -I de la commande cc.

Si le nom du fichier est spécifié entre <>, il est recherché par défaut dans le répertoire /usr/include.

Exemple

def.h

#define  NbElements(t)  sizeof t / sizeof t[0]
#define  TAILLE 256
typedef struct cellule {
     int tab[TAILLE];
     struct cellule *ptr;
} CEL;
typedef enum bool {FAUX, VRAI} logical;
extern void init(int t[], logical imp);
CEL c;
    
#include "def.h"
main()
{
   int t[TAILLE] = {1, 2, 9, 10};
   logical imp = VRAI;

   init(t, imp);
}

    
#include "def.h"
#include 
void init(int t[], logical imp)
{
   int i;

   for(i=0; i < NbElements(c.tab); i++) {
     c.tab[i] = t[i];
     if (imp)
       printf(" %d", c.tab[i]);
   }
   printf("%s", imp ? "\n" : "");
   c.ptr = NULL;
}
    

Il existe une bibliothèque standard de fichiers en-tête nécessaires lors de l'appel de certaines fonctions :

Retour début .

7.5 - Compilation conditionnelle


Test d'existence d'une pseudo-constante

Ce sont les directives #ifdef et #ifndef qui permettent de tester l'existence d'une pseudo-constante.

Syntaxe

    #ifdef identificateur
       partie-alors
    [#else
       partie-sinon]
    #endif

    #ifndef identificateur
       partie-alors
    [#else
       partie-sinon]
    #endif
    

Exemple

      def.h               source.c
  #ifdef TAILLE_BUF
  # undef TAILLE_BUF
  #endif /* TAILLE_BUF */
  #define TAILLE_BUF 4096
  
#ifdef DEBUG            |  #define DEBUG
  #define trace(s) \    |  #include "def.h"
          printf s      |  #include <stdio.h>
#else                   |  main()
#define trace(s)        | {
#endif/* DEBUG */       |     int f(float x);
                        |     int i;
                        |     float r;
                        |
                        |     i = f(r);
                        |     trace(("%d\n", i));
                        |  }
  
La définition d'une pseudo-constante ainsi que sa valorisation peuvent se faire à l'appel de la commande cc au moyen de l'option -D.

Syntaxe

  cc -Dpseudo-constante[=valeur] ...
  

On peut appliquer ce principe à la pseudo-constante DEBUG de l'exemple précédent au lieu de la définir dans le fichier source.c :
            cc -DDEBUG source.c
  

Évaluation de pseudo-expressions

Il est possible de construire des expressions interprétables par le préprocesseur à l'aide :

Syntaxe

     #if pseudo-expression
        partie-alors
     [#else
        partie-sinon]
     #endif
     

Remarque

Si l'on désire mettre en commentaire une portion de programme, la solution consistant à l'encadrer par les caractères /* et */ ne marche pas si elle contient elle-même des commentaires.

Une solution simple est de placer en tête de la région à commenter la directive #if 0, et à la fin la directive #endif /* 0 */.

Exemple

source.c

#define TBLOC 256
#if !defined  TAILLE
#  define TAILLE TBLOC
#endif
#if TAILLE%TBLOC == 0
#  define TAILLEMAX TAILLE
#else
#  define TAILLEMAX ((TAILLE/TBLOC+1)*TBLOC)
#endif
static char buffer[TAILLEMAX];
main()
{
   printf("Taille du vecteur : %d caractères\n",
          sizeof buffer);
}
     
  1. cc -DTAILLE=255 source.c
  2. cc -DTAILLE=257 source.c
  3. cc source.c

Retour début


.

8 - Les fonctions

Retour début .

8.1 - Passage arguments-paramètres

Dans les langages de programmation il existe deux techniques de passage d'arguments :

Des langages comme Fortran ou PL/1 ont choisi la 1ère solution, tandis qu'un langage comme Pascal offre les deux possibilités au programmeur.

Le langage C a choisi la 2e solution.

Si un argument doit être passé par adresse, c'est le programmeur qui en prend l'initiative et ceci grâce à l'opérateur d'adressage (&).

Exemple

#include <stdio.h>
void main()
{
   int a, b, c;
   void somme(int a, int b, int *c);

   a = 3;
   b = 8;
   somme(a, b, &c);
   printf("Somme de a et b : %d\n", c);

   return;
}

void somme(int a, int b, int *c)
{
   *c = a + b;

   return;
}
     

Retour début .

8.2 - Fonction retournant un pointeur

Il convient d'être prudent lors de l'utilisation d'une fonction retournant un pointeur. Il faudra éviter l'erreur qui consiste à retourner l'adresse d'une variable temporaire.

Exemple

#include <stdio.h>
void main()
{
   char *p;
   char *ini_car(void);
   p = ini_car();
   printf("%c\n", *p);
}
char *ini_car(void)
{
   char c;
   c = '#';
   return(&c);     <===  ERREUR
}
     

Retour début .

8.3 - Passage d'un vecteur comme argument


Un vecteur est une constante symbolique dont la valeur est l'adresse de son 1er élément.

Lorsqu'un vecteur est passé en argument, c'est donc l'adresse de son 1er élément qui est transmise par valeur.

Exemple

#define NbElements(t) sizeof t / sizeof t[0]
#include <stdio.h>
main()
{
   int  tab[] = { 1, 9, 10, 14, 18};
   int  somme(int t[], int n);
   void impression(int *t, int n);
   printf("%d\n", somme(tab, NbElements(tab)));
   impression(tab, NbElements(tab));
}
int  somme(int t[], int n)
{
   int i, som=0;
   for (i=0; i < n; i++) som += t[i];
   return som;
}
void impression(int *t, int n)
{
   int i=0, *p;
   for (p=t; t-p < n; t++)
      printf("t[%d] = %d\n", i++, *t);
}
     

Exemple

#define NbElements(t) sizeof t / sizeof t[0]
#include <stdio.h>
main()
{
   int tab[][5] = {
                     { 4, 7, 1, 9, 6},
                     { 5, 9, 3, 4, 2},
                     { 2, 9, 5, 9, 13}
                  };
   int somme(int (*t)[5], int n);

   printf("Somme des éléments de tab : %d\n",
           somme(tab, NbElements(tab)));
}
int somme(int (*t)[5], int n)
{
   int i, som = 0;
   int (*p)[5] = t;
   for(; t-p < n; t++)
     for (i=0; i < 5; i++)
        som += (*t)[i];
   return som;
}
     

Exemple

#define DIM1 10
#define DIM2  4
#define DIM3  5
#include <stdio.h>
main()
{
   int tab[DIM1][DIM2][DIM3];
   void init(int (*t)[DIM3], int n);
   int i, n = DIM2;

   for(i=0; i < DIM1; i++)
     init(tab[i], i);
}
void init(int (*t)[DIM3], int n)
{
   int i, j;

   for(i=0; i < DIM2; i++)
     for(j=0; j < DIM3; j++) {
       t[i][j]      = 2*(i+n*DIM2);
       *(*(t+i)+j) += 1;
     }
}
     

Retour début .

8.4 - Passage d'une fonction comme argument


Le nom d'une fonction est une constante symbolique dont la valeur est un pointeur sur la 1ère instruction exécutable du code machine de la fonction.
Passer une fonction en argument, c'est donc transmettre l'adresse, par valeur, du début du code machine constituant cette fonction.

Exemple

double integrale(double b_inf, double b_sup,
                 int pas, double (*f)(double));
double carre(double x);
void main()
{
   double b_inf, b_sup, aire;
   int    pas;
   b_inf = 1., b_sup = 6., pas = 2000;
   aire = integrale(b_inf, b_sup, pas, carre);
   printf("Aire : %f\n", aire);
}
double integrale(double b_inf, double b_sup,
                 int pas, double (*f)(double))
{
   double surface = 0., h;
   int    i;
   h = (b_sup - b_inf)/pas;
   for(i=0; i < pas; i++)
     surface += h*(*f)(b_inf+i*h);
   return surface;
}
double carre(double x) {return x*x;}
     

Retour début .

8.5 - Passage d'arguments à la fonction main

Lorsqu'un exécutable est lancé sous un interprète de commandes ({shell}), un processus est créé et son exécution commence par la fonction main à laquelle des arguments sont transmis après avoir été générés par le shell.

Ces arguments sont constitués de :


Les premier et dernier sont transmis sous forme de vecteurs de pointeurs de caractères.

Par convention :


Les arguments précédents sont transmis à la fonction main dans cet ordre.

Exemple

La commande a.out toto titi tata génère la structure de données suivante :

Tableau des arguments

*** Schéma ***

Exemple

#include <stdio.h>
main(int argc, char **argv, char **envp)
{
   void usage(char *s);

   if (argc != 3)
     usage(argv[0]);
   for(; *argv; argv++)
     printf("%s\n", *argv);
   for(; *envp; envp++)
     printf("%s\n", *envp);
}

void usage(char *s)
{
   fprintf(stderr, "usage : %s arg1 arg2\n", s);
   exit(1);
}
     

Retour début .

8.6 - Fonction avec un nombre variable d'arguments

Lors de l'appel à une fonction, le compilateur génère une liste des arguments fournis qu'il empile dans la pile d'exécution rattachée au processus (pile de type LIFO).

Exemple

int puissance(int n, int x)
{
  int p = 1;
  while(n--) p *= x;
  return p;
}
void main()
{
  int m, k, r;
  k = 4; m = 2;
  r = puissance(k+3, m);
}
    

A l'appel de la fonction puissance de l'exemple précédent il y a :

Processus de passage d'arguments

Schéma

Ce type de passage d'arguments permet d'écrire des fonctions avec un nombre variable d'arguments.

Dans le prototype d'une telle fonction, on indiquera les arguments suivis de :

Comme les arguments sont rangés de façon consécutive dans la pile, le programmeur a la possibilité d'aller chercher les arguments en surnombre.

Exemple

void fonction(int a, ...);
main()
{
   int i = 10, j = 11, k = 12;
   printf("Avant appel fonction i = %d\n", i);
   printf("Avant appel fonction j = %d\n", j);
   printf("Avant appel fonction k = %d\n", k);
   fonction(i, j, k);
}
void fonction(int a, ...)
{
   printf("Valeur de a = %d\n", a);
   printf("Récupération de j = %d\n", *(&a + 1));
   printf("Récupération de k = %d\n", *(&a + 2));
}
     
Cette technique de récupération d'arguments dans la pile, nécessite cependant que le programmeur connaisse les types des arguments en surnombre et qu'il ait un moyen d'arrêter la recherche.

Pour ce faire, le dernier argument fourni à l'appel de la fonction peut par exemple indiquer le nombre d'arguments en surnombre, ou bien ceux-ci peuvent être suivis par un argument supplémentaire de même type avec une valeur spéciale (valeur sentinelle).

Par contre la norme ne précise pas l'ordre dans lequel les arguments doivent être empilés, cette méthode de la pile n'est donc pas portable.

Pour assurer cette portabilité, chaque système propose des pseudo-constantes et pseudo-fonctions permettant au programmeur de gérer cette recherche.

Version Unix System V

Les pseudo-constantes et pseudo-fonctions sont stockées dans le fichier en-tête varargs.h :

Exemple

#include <stdio.h>
#include <varargs.h>
main()
{
   int moyenne();
   printf("moyenne = %d\n", moyenne(4, 1, 2, 3, 4));
   printf("moyenne = %d\n",
           moyenne(5, 1, 2, 3, 4, 5));
}
int moyenne(nombre, va_alist)
int nombre;
va_dcl
{
   int     somme = 0, i;
   va_list arg;
   va_start(arg);
   for(i=0; i < nombre; i++)
     somme += va_arg(arg, int);
   va_end(arg);
   return somme/nombre;
}
     

Exemple

#include <stdio.h>
#include <varargs.h>
main()
{
   float moyenne();
   printf("moyenne = %f\n",
           moyenne(4, 1.f, 2.f, 3.f, 4.f));
   printf("moyenne = %f\n",
           moyenne(5, 1.f, 2.f, 3.f, 4.f, 5.f));
}
float moyenne(nombre, va_alist)
int nombre;
va_dcl
{
   float   somme = 0.f;
   int     i;
   va_list arg;
   va_start(arg);
   for(i=0; i < nombre; i++)
     somme += va_arg(arg, double);  ===> surtout
   va_end(arg);                          pas float!
   return somme/nombre;
}
     

Version ANSI

Les pseudo-constantes et pseudo-fonctions sont stockées dans le fichier en-tête stdarg.h :

Les arguments en surnombre sont symbolisés par ... dans le prototype de la fonction.

Exemple

#include <stdio.h>
#include <stdarg.h>
main()
{
   int moyenne(int nombre, ...);
   printf("moyenne = %d\n", moyenne(4, 1, 2, 3, 4));
   printf("moyenne = %d\n",
           moyenne(5, 1, 2, 3, 4, 5));
}
int moyenne(int nombre, ...)
{
   int     somme = 0, i;
   va_list arg;
   va_start(arg, nombre);
   for(i=0; i < nombre; i++)
     somme += va_arg(arg, int);
   va_end(arg);
   return somme/nombre;
}
     
Retour début


.

9 - La bibliothèque standard

Retour début .

9.1 - Notion de pointeur générique

La norme a défini le type void * ou pointeur générique afin de faciliter la manipulation des pointeurs et des objets pointés indépendamment de leur type.

On ne pourra pas appliquer les opérateurs d'indirection et d'auto-incrémentation, auto-décrémentation à un pointeur générique.

Par contre, si p et q sont deux pointeurs, les affectations :

sont toutes deux correctes si l'un au moins des deux pointeurs p ou q est de type void *, quel que soit le type de l'autre pointeur.

Exemples

int x[5], i, *k;
float *r;
void  *p;
void  *q;

p = &x[0];       /* correct  */
*p = ...         /* interdit */
q = p + 1;       /* interdit */
r = p;           /* correct  */
p = r;           /* correct  */
p[1] = ...;      /* interdit */
    

Exemples

void echange (void *p, void *q)
{
  void *r;

   r          = *(void **)p;
  *(void **)p = *(void **)q;
  *(void **)q =  r;
}
main()
{
  int    *i1, *i2;
  float  *f1, *f2;
  double *d1, *d2;
      ...
  echange(&i1, &i2);
  echange(&f1, &f2);
  echange(&d1, &d2);
}
    

Retour début .

9.2 - Entrées-sorties de haut niveau


Les entrées-sorties de haut niveau intègrent deux mécanismes distincts : Toute opération d'entrée-sortie se fera par l'intermédiaire d'un flot (stream) qui est une structure de données faisant référence à :

Cette structure de données est un objet de type FILE. Dans le programme, un flot sera déclaré de type FILE *.
Trois flots sont prédéfinis au lancement d'un processus :

Les informations précédentes sont contenues dans le fichier en-tête stdio.h. Ce fichier contient, de plus, les déclarations des différentes fonctions d'entrée-sortie, ainsi que la déclaration d'un vecteur (_iob) de type FILE dont la dimension est définie à l'aide d'une pseudo-constante.

Extrait du fichier stdio.h sur IBM/RS6000

#define _NIOBRW         20
extern FILE     _iob[_NIOBRW];

#define stdin           (&_iob[0])
#define stdout          (&_iob[1])
#define stderr          (&_iob[2])
     

Retour début .

9.2.1 - Fonctions d'ouverture et de fermeture

L'acquisition d'un nouveau flot s'effectue par l'appel à la fonction fopen. La fonction fclose permet de le fermer.

Syntaxe

FILE *fopen(const char *file, const char *type);
int   fclose(const FILE *flot);
     

La fonction fopen retourne un pointeur sur le 1er élément libre du vecteur _iob s'il en existe, sinon sur une zone de type FILE allouée dynamiquement.

Un pointeur NULL, pseudo-constante définie comme (void *)0 dans stdio.h, indique une fin anormale.

La fonction fclose retourne 0 en cas de succès, -1 sinon.

Le 2e argument de la fonction fopen indique le mode d'ouverture du fichier.

Accès Paramètre Position Comportement
si le fichier
existe
si le fichier
n'existe pas
lecture r début .erreur
écriture w
a
début
fin
mis à zéro création
création
lecture
et
écriture
r+
w+
a+
début
début
fin
mis à zéro erreur
création
création

Certains systèmes font la distinction entre les fichiers texte et binaire. Pour manipuler ces derniers, il suffit de rajouter le caractère b dans la chaîne indiquant le mode d'ouverture. Sous UNIX, il est ignoré car il n'existe aucune différence entre un fichier binaire et un fichier de données quelconques.

Exemple

#include <stdio.h>
main()
{
   FILE * flot;

   if ((flot = fopen("donnees", "r")) == NULL) {
     fprintf(stderr, "Erreur a l'ouverture\n");
     exit(1);
   }
       ...
       ...
   fclose(flot);
}
  

Retour début .

9.2.2 - Lecture et écriture par caractère

Les fonctions getc, fgetc et putc, fputc permettent de lire ou écrire un caractère sur un flot donné.

getc et putc sont des pseudo-fonctions.

Syntaxe

  int getc(FILE *Stream)
  int fgetc(FILE *Stream)
  int putc(int c, FILE *Stream)
  int fputc(int c, FILE *Stream)
  

Il existe deux pseudo-fonctions supplémentaires :

Ces fonctions retournent soit le caractère traité, soit la pseudo-constante EOF, définie comme -1 dans le fichier stdio.h, en cas d'erreur (fin de fichier par exemple).

Deux pseudo-fonctions feof et ferror, définies dans le fichier stdio.h, permettent de tester, respectivement, la fin de fichier et une éventuelle erreur d'entrée-sortie sur le flot passé en argument.

Dans le cas d'une entrée-sortie au terminal, c'est le retour chariot qui provoque l'envoi au programme de la mémoire tampon rattachée au pilote /dev/tty.

Exemple

#include <stdio.h>
main()
{
  char c;  <=== Attention Erreur !
                ----------------

  while ((c = getchar()) != EOF)
     putchar(c);
}
  

Exemples corrects

#include <stdio.h>
main()
{
  int c;

  while ((c = getchar()) != EOF)
     putchar(c);
}
  

#include <stdio.h>
main()
{
  int c;

  c = getchar();
  while (!ferror(stdin) &&
         !feof(stdin)) {
     putchar(c);
     c = getchar();
  }
}
  

Retour début .

9.2.3 - Lecture et écriture de mots

Les fonctions getw et putw permettent de lire ou écrire des mots.

Syntaxe

  int getw(FILE *flot)
  int putw(int c, FILE *flot)
  

Exemple

#include <stdio.h>
#define DIM 100
main()
{
   FILE *flot;
   int   tab[DIM];
   int   i;

   if ((flot = fopen("resultat", "w")) == NULL) {
     perror("fopen");
     exit(1);
   }
   for (i=0; i < DIM; i++) {
      tab[i] = i*i;
      putw(tab[i], flot);
   }
   fclose(flot);
}
  

Retour début .

9.2.4 - Lecture et écriture d'une chaîne de caractères

Les fonctions gets, fgets et puts, fputs permettent de lire et écrire des chaînes de caractères.

Syntaxe

  char *gets(char *string)
  int   puts(char *string)
  char *fgets(char *string, int nombre, FILE *flot)
  int   fputs(char *string, FILE *flot)
  


Les fonctions gets, fgets renvoient la chaîne lue ou le pointeur NULL si fin de fichier. Les fonctions puts, fputs renvoient le nombre de caractères écrits ou EOF si erreur.

Exemple

#include <stdio.h>
main()
{
  char *mus1 = "Wolfgang Amadeus Mozart\n";
  char *mus2 = "Ludwig van Beethoven\n";
  char  buffer[BUFSIZ+1];
  FILE *f;
  if ((f = fopen("musiciens", "w")) == NULL) {
    perror("fopen");
    exit(1);
  }
  fputs(mus1, f); fputs(mus2, f);
  fclose(f);
  if ((f = fopen("musiciens", "r")) == NULL) {
    perror("fopen");
    exit(2);
  }
  while (fgets(buffer, sizeof(buffer), f))
     fputs(buffer, stdout);
  fclose(f);
  puts("\nExecution terminee.");
}
  

Retour début .

9.2.5 - Lecture et écriture de blocs

Les fonctions fread et fwrite permettent de lire et d'écrire des blocs de données tels des structures ou des tableaux.

Syntaxe

size_t fread(void *p, size_t t, size_t n, FILE *f)
size_t fwrite(void *p, size_t t, size_t n, FILE *f)
  
Ces fonctions retournent le nombre de blocs traités. Utiliser les pseudo-fonctions feof et ferror pour tester la fin de fichier et une erreur d'entrée-sortie.

Exemple

#include <stdio.h>
#define NbElt(t) ( sizeof t / sizeof t[0] )
main() {
  typedef struct { int   n; float t[10]; char  c;
                 } DONNEE;
  DONNEE s1   = { 1, { 1.,  2., 3.}, 'a'};
  DONNEE s2[] = { {4, {10., 32., 3.}, 'z'},
                  {5, { 2., 11., 2., 4.}, 'h'} };
  FILE *f, *f_sauve; DONNEE s;
  if ((f = fopen("donnee", "w")) == NULL)
    perror("fopen"), exit(1);
  fwrite(&s1, sizeof(DONNEE), 1, f);
  fwrite( s2, sizeof(DONNEE), NbElt(s2), f);
  fclose(f);
  if ((f = fopen("donnee", "r")) == NULL ||
      (f_sauve = fopen("sauvegarde", "w")) == NULL)
    perror("fopen"), exit(2);
  fread(&s, sizeof(DONNEE), 1, f);
  while (!feof(f)) {
    fwrite(&s, sizeof(DONNEE), 1, f_sauve);
    fread(&s, sizeof(DONNEE), 1, f); }
  fclose(f); fclose(f_sauve);
}
  

Retour début .

9.2.6 - Accès direct

Par défaut, les fonctions précédentes travaillent en mode séquentiel. Chaque lecture ou écriture s'effectue à partir d'une position courante, et incrémente cette position du nombre de caractères lus ou écrits.

Les fonctions fseek et ftell permettent, respectivement, de modifier et récupérer la position courante.

int  fseek(FILE *f, long decalage, int position);
long ftell(FILE *f);
    

La fonction ftell retourne la position courante en octets.

La fonction fseek permet de la modifier :

Exemple

#include <stdio.h>
main(int argc, char **argv)
{
   FILE *f;
   void  usage(char *s);

   if (argc != 2)
     usage(argv[0]);
   if ((f = fopen(argv[1], "r")) == NULL) {
     perror("fopen");
     exit(2);
   }
   fseek(f, 0L, SEEK_END);
   printf("Taille(octets) : %d\n", ftell(f));
   fclose(f);
}

void  usage(char *s)
{
   fprintf(stderr, "usage : %s fichier\n", s);
   exit(1);
}
     

Retour début .

9.2.7 - Entrées-sorties formatées

Les fonctions scanf, fscanf, sscanf et printf, fprintf, sprintf permettent d'effectuer des entrées-sorties de données avec conversions.

Syntaxe

int scanf(const char *format [, ...])
int fscanf(FILE *f, const char *format [, ...])
int sscanf(const char *buffer,
           const char *format [, ...])
int printf(const char *format [, ...])
int fprintf(FILE *f, const char *format [, ...])
int sprintf(const char *buffer,
            const char *format [, ...])
  

Fonctions printf, fprintf, sprintf

Le paramètre format désigne une chaîne de caractères comprenant :

Après les conversions effectuées, cette chaîne est reproduite : Les spécifications de conversions portent successivement sur les arguments passés à la suite du paramètre format.

Une spécification de conversion est constituée du caractère %, suivie dans l'ordre :

Exemples

printf("|%d|\n", 1234);             |1234|
printf("|%-d|\n", 1234);            |1234|
printf("|%+d|\n", 1234);            |+1234|
printf("|% d|\n", 1234);            | 1234|
printf("|%10d|\n", 1234);           |      1234|
printf("|%10.6d|\n", 1234);         |    001234|
printf("|%10.2d|\n", 1234);         |      1234|
printf("|%.6d|\n", 1234);           |001234|
printf("|%06d|\n", 1234);           |001234|
printf("|%.2d|\n", 1234);           |1234|
printf("|%*.6d|\n", 10, 1234);      |    001234|
printf("|%*.*d|\n", 10, 6, 1234);   |    001234|
printf("|%x|\n", 0x56ab);           |56ab|
printf("|%#x|\n", 0x56ab);          |0x56ab|
printf("|%X|\n", 0x56ab);           |56AB|
printf("|%#X|\n", 0x56ab);          |0X56AB|
  
printf("|%f|\n",1.234567890123456789e5);
               |123456.789012|
printf("|%.4f|\n",1.234567890123456789e5);
               |123456.7890|
printf("|%.15f|\n",1.234567890123456789e5);
               |123456.789012345670000|
printf("|%15.4f|\n",1.234567890123456789e5);
               |    123456.7890|

printf("|%e|\n",1.234567890123456789e5);
               |1.234568e+05|
printf("|%.4e|\n",1.234567890123456789e5);
               |1.2346e+05|
printf("|%.18e|\n",1.234567890123456789e5);
               |1.234567890123456700e+05|
printf("|%18.4e|\n",1.234567890123456789e5);
               |        1.2346e+05|
printf("|%.4g|\n",1.234567890123456789e-5);
               |1.235e-05|
printf("|%.4g|\n",1.234567890123456789e+5);
               |1.235e+05|
printf("|%.4g|\n",1.234567890123456789e-3);
               |0.001235|
printf("|%.8g|\n",1.234567890123456789e5);
               |123456.79|
  
#include <stdio.h>
main()
{
  char *chaine = "Wolfgang Amadeus Mozart";

  printf("|%s|\n", chaine);      ===> 1)
  printf("|%.16s|\n", chaine);   ===> 2)
  printf("|-23.16s|\n", chaine); ===> 3)
  printf("|23.16s|\n", chaine);  ===> 4)
}

  1) |Wolfgang Amadeus Mozart|

  2) |Wolfgang Amadeus|

  3) |Wolfgang Amadeus       |

  4) |       Wolfgang Amadeus|

  

Fonctions scanf, fscanf, sscanf

Ces fonctions permettent d'effectuer des entrées formatées. Les données lues sont converties suivant les spécifications de conversions indiquées dans la chaîne format, puis stockées dans les arguments successifs fournis à sa suite. Ces arguments doivent être des pointeurs.

La valeur retournée correspond au nombre d'arguments correctement affectés. La chaîne format peut contenir :

Les données en entrée sont découpées en champs.

Chaque champ est défini comme une chaîne de caractères qui s'étend soit :

Une spécification de conversion est constituée du caractère % suivi dans l'ordre :

Remarques

Les arguments correspondant aux spécifications :

On peut faire précéder les spécifications d, i, o, x, u par la lettre h ou l pour référencer un short * ou un long *.

De même les spécifications e, f, g peuvent être précédées de la lettre l pour référencer un double *.

Exemples

#include <stdio.h>
main()
{
  int   i;
  float x, y;
  char  buffer[BUFSIZ];
  char *p = "12/11/94";
  int   jour, mois, annee;

  scanf("%d%f%f%*c", &i, &x, &y);
  printf("i = %d, x = %f, y = %f\n", i, x, y);
  scanf("%[^\n]%*c", buffer);
  while (!feof(stdin)) {
    fprintf(stderr, "%s\n", buffer);
    scanf("%[^\n]%*c", buffer);
  }
  sscanf(p, "%d/%d/%d", &jour, &mois, &annee);
  printf("jour  : %d\n", jour);
  printf("mois  : %d\n", mois);
  printf("annee : %d\n", annee);
}
  
#include <stdio.h>
main()
{
  char   mois[10], buffer[BUFSIZ];
  int    quantite;
  double prix;
  FILE  *f;
  if ((f=fopen("donnees", "r")) == NULL)
    perror("fopen"), exit(1);
  fgets(buffer, sizeof(buffer), f);
  while (!feof(f)) {
    sscanf(buffer, "%s%d%lf",
            mois, &quantite, &prix);
    printf("mois : %s, qte : %d, prix : %f\n",
            mois, quantite, prix);
    fgets(buffer, sizeof(buffer), f);
  }
  fseek(f, 0L, SEEK_SET);
  fscanf(f, "%s%d%lf", mois, &quantite, &prix);
  while (!feof(f)) {
    printf("mois : %s, qte : %d, prix : %f\n",
            mois, quantite, prix);
    fscanf(f, "%s%d%lf", mois, &quantite, &prix);
  }
  fclose(f);
}
  

Retour début .

9.2.8 - Autres fonctions

La fonction freopen permet de redéfinir un flot déjà initialisé. Elle est principalement utilisée avec les flots stdin, stdout, stderr, ce qui correspond à une redirection d'entrées-sorties.

La fonction fflush permet de forcer le vidage de la mémoire tampon associée à un flot en sortie. Sur un flot en entrée l'effet est imprévisible.

Syntaxe

FILE *freopen(char *fichier, char *mode, FILE *flot);
int   fflush(FILE *flot);
    

Exemple

#include <stdio.h>
main(int argc, char **argv)
{
  void usage(char *s);

  if (argc != 2)
    usage(argv[0]);
  if (freopen(argv[1], "w", stdout) == NULL) {
    perror("freopen");
    exit(2);
  }
  printf("Ce message est redirige ");
  printf("dans le fichier ");
  printf("dont le nom est ");
  printf("passe en argument.\n");
}

void usage(char *s)
{
  fprintf(stderr, "usage : %s fichier\n", s);
  exit(1);
}
    

Retour début .

9.3 - Manipulation de caractères


Le fichier en-tête ctype.h contient des déclarations de fonctions permettant de tester les caractères. Elles admettent un argument de type entier et retourne un entier :

Les caractères imprimables sont compris entre 0x20 et 0x7e, les caractères de contrôle sont compris entre 0 et 0x1f ainsi que 0x7f.

Il existe, de plus, deux fonctions permettant de convertir les majuscules en minuscules et réciproquement :

Exemple

#include <stdio.h>
#include <ctype.h>
main()
{
   int c;
   int NbMaj = 0;
   int NbMin = 0;
   int NbNum = 0;
   int NbAutres = 0;
   while((c=getchar()) != EOF)
      if (isupper(c))
        NbMaj++;
      else if (islower(c))
        NbMin++;
      else if (isdigit(c))
        NbNum++;
      else
        NbAutres++;
   printf("NbMaj    : %d\n", NbMaj);
   printf("NbMin    : %d\n", NbMin);
   printf("NbNum    : %d\n", NbNum);
   printf("NbAutres : %d\n", NbAutres);
}
     

Retour début .

9.4 - Fonctions de conversions


Le fichier en-tête stdlib.h contient des déclarations de fonctions permettant la conversion de données de type chaîne de caractères en données numériques :

Exemple

#include <stdio.h>
#include <stdlib.h>
main()
{
  char   *s = "     37.657654";
  double  d;
  long    l;

  d = strtod(s, NULL);
  printf("d : %f\n", d);            ===> 37.657654
  s = "11001110101110";
  l = strtol(s, NULL, 2);
  printf("%ld\n", l);               ===> 13230
  s = "0x7fff";
  l = strtol(s, NULL, 0);
  printf("%ld\n", l);               ===> 32767
  s = "0777";
  l = strtol(s, NULL, 0);
  printf("%ld\n", l);               ===>   511
  s = "777";
  l = strtol(s, NULL, 0);
  printf("%ld\n", l);               ===>   777
}
     

Retour début .

9.5 - Manipulation de chaînes de caractères


Le fichier en-tête string.h contient des déclarations de fonctions permettant la manipulation de chaînes de caractères :

Le type size_t est un alias du type unsigned long.

Exemple

#include <stdio.h>
#include <string.h>
main(int argc, char **argv)
{
   char *parm1, *parm2, buffer[BUFSIZ];
   if (argc != 3) usage(argv[0]);
   parm1 = strdup(argv[1]);
   parm2 = strdup(argv[2]);
   strcat(strcpy(buffer, "Resultat de la "
                         "concatenation : "),
          parm1);
   strcat(strcat(buffer, parm2), "\n");
   printf("%s", buffer);
   sprintf(buffer, "%s%s%s\n", "Resultat de la "
                               "concatenation : ",
                                parm1, parm2);
   printf("%s", buffer);
   free(parm1); free(parm2);
}
void usage (char *s) {
   fprintf(stderr, "usage : %s ch1 ch2.\n", s);
   exit(1);
}
      

Exemple

#include <stdio.h>
#include <string.h>
main(int argc, char **argv)
{
   void usage (char *s);
   char *s  = "/usr/include/string.h", *p;
   int   NbSlash = 0;
   if (argc != 3) usage(argv[0]);
   if (!strcmp(argv[1], argv[2]))
     printf("Les 2 arguments sont identiques.\n");
   else if (strcmp(argv[1], argv[2]) > 0)
       printf("arg1 > arg2\n");
   else printf("arg1 < arg2\n");
   for (p = s-1; p = strchr(++p, '/'); NbSlash++)
              ;
   printf("La chaine s contient %d\n", NbSlash);
   printf("slashs sur %d caracteres.\n", strlen(s));
}
void usage (char *s)
{
   fprintf(stderr, "usage : %s ch1 ch2.\n", s);
   exit(1);
}
      

Il existe d'autres fonctions qui agissent sur des tableaux de caractères plutôt que des chaînes de caractères :

Exemple

#include <stdio.h>
#include <string.h>
main()
{
   char  buffer[100];
   char  tab[] = "Voici\0une chaine qui"
                 "\0\0contient\0des"
                 "\0caracteres \"null\".";
   char *p, *ptr;
   int   taille = sizeof tab / sizeof tab[0];
   int   n;

   memset(buffer, ' ', 100);
   n = --taille;
   for (p=ptr=tab; p=memchr(ptr, '\0', n);)
   {
      *p = ' ';
      n -= p - ptr + 1;
      ptr = ++p;
   }
   printf("%s\n", tab);
   printf("%.*s\n", taille, tab);
}
      

Retour début .

9.6 - Allocation dynamique de mémoire


Les fonctions permettant de faire de l'allocation dynamique de mémoire sont :