Fonctions sur les caractères

Les fonctions sur les caractères sont dans ctype.h

 

Fonction de test, rendant 0 ou 1 :

Et fonctions de conversion minuscule/majuscule :

tolower et toupper

 

Conversion d’une chaîne en minuscules :

for (i = 0; ch[i] != '\0' ; i = i + 1)

        ch[i] = tolower(ch[i]);

 

Fonctions sur les chaînes

 

Les fonctions sur les chaînes sont dans string.h

Elles sont décrites dans le livre de Kernighan et Ritchie et dans le cours de Garreta (document PDF accessible sur developpez.com).

 

Attention,

char s1[80] = "bonjour" ;

effectue une déclaration et initialisation de s1

mais

char s1[80] ;

s1 = "bonjour" ;

ne fonctionne pas. C’est une affectation de tableau et ça n’existe pas en C.

 

Copie

L’affectation de chaînes est appelée copie de chaînes et se fait avec la fonction strcpy

strcpy(s2,s1);

copie s1 dans s2

strcpy(s1,"Bonjour");

copie "Bonjour" dans s2

 

Concaténation

char s1[40] = "Bonjour", s2[40] = "Madame";

strcat(s1,s2); /* copie s2 au bout de s1 */

printf("%s",s1);

affiche BonjourMadame

 

Comparaison

strcmp(s1,s2)

rend 0 si s1=s2

rend entier strictement négatif si s1<s2

rend entier strictement positif si s1>s2

rappel : majuscules, minuscules, lettre accentuées sont différentes ; l’ordre est lexicographique.

 

Longueur

strlen(s1)

rend la longueur de s1

char s1[40] = "Bonjour" ;

strlen(s1) rend 7

Le code ascci

 

 

5. Les nombres réels

 

Ce sont des nombres décimaux appelés aussi nombres flottants ou flottants.

La représentation interne

 

Se représentent avec mantisse et argument en base 2.

 

Trois types avec des champs de valeurs différents :

float         simple précision : 4 octets sur PC intel

double        double précision : 8 octets sur PC intel

long double   quadruple précision : 16 octets sur PC intel

 

A chaque type est associé une taille maximale de la mantisse et un nombre de chiffres significatifs.

Les constantes réelles

 

Représentation avec point décimal :       21.4      0.013    .41       3.

Représentation mentisse et argument :   2e4 pour 2*104             1.2e-2 pour 1.2*10-2

 

Cette représentation a le type double.

 

Pour indiquer le type float, on met f ou F ensuite. Pour indiquer le type long double, on met l ou L ensuite.

 

Il y a arrondi quand cela est nécessaire. Exemple : le nombre 0.1 en décimal a un développement binaire infini, il est arrondi et n’est donc pas représenté de façon exacte.

 

Les opérateurs réels

 

+          -           *          /           même priorité que sur les entiers

 

Attention : 2. / 5. vaut 0.4 (division décimale) et 2 / 5 vaut 0 (division entière)

 

Combinaisons d’entiers et de réels pour les opérateurs binaires :

Deux entiers : opération entière

Deux réels : opération décimale

Un entier et un réel : conversion de l’entier en réel et opération décimale.

 

Comparaisons

Les mêmes opérateurs de comparaison que les entiers, mais, du fait des erreurs de calcul, ne pas comparer les réels avec égal ou différent.

 

#define EPSILON 1e-5

/* au lieu de if (a == b) */

if (a > b - EPSILON && a < b + EPSILON)

EPSILON doit être bien choisi par rapport aux données traitées et à la précision utilisée (float, double ou long double).

Lecture écriture

Format avec virgule fixe « f » :

scanf("%f",&x);

printf("%f",x);

Format avec notation exponentielle « e » :

scanf("%e",&x);

printf("%e",x);

 

Mais pour scanf, « f » et « e » font la même chose.

Affectation mixte

 

Si on affecte un entier à une variable réelle ou un réel à une variable entière, il y a conversion (troncature dans le deuxième cas).

 

Exemple :

 

float u;

int i;

u = 12;

i = 1.3;

printf("u=%f  i=%d",u,i);

 

affiche u=12.000000  i=1

Calculs approchés

 

Les calculs réels se font de façon approchée, avec des erreurs d’arrondi. Il vaut généralement mieux contrôler les boucles avec des entiers.

 

Exemple :

 

int main()

{

      float u;

      int i;

 

      u = 0.;

      i = 0;

      while (u < 100.)

      {

            u = u + 0.1;

            i = i + 1;

      }

 

      printf("Controle avec le decimal : u=%f  i=%d\n\n",u,i);

 

      u = 0.;

      i = 0;

      while (i < 1000)

      {

            u = u + 0.1;

            i = i + 1;

      }

      printf("Controle avec l'entier : u=%f  i=%d\n\n",u,i);

}

 

Ce programme affiche :

Controle avec le decimal : u=100.099045   i=1001

Controle avec l'entier : u=99.999046  i=1000

 

Donc on est passé une fois de trop dans la première boucle.

 


Fonctions sur les réels

 

Ces fonctions sont dans math.h

Les arguments et le résultat sont des « double ». Il y a conversion si nécessaire.

 

Comparaison à epsilon près de a et b :

if ( fabs(a – b) < EPSILON )

 

6. Les structures

 

Les tableaux sont des regroupements d’informations de mêmes types, les structures regroupements d’informations de types différents. Structure est le terme du langage C pour ce qui est habituellement appelé enregistrement. Un enregistrement est composé de champs. En C, on parle de membres.

 

Exemple :

 

struct personne

{

      char nom[20] ;   

      char prenom[20] ;

      int age ;

      float taille ;

} ;

 

Déclaration de variables de ce type :

 

struct personne p1, p2 ;

 

Déclaration de variables en même temps que la déclaration de la structure :

 

struct personne

{

      char nom[20] ;   

      char prenom[20] ;

      int age ;

      float taille ;

} p1, p2;

 

Manipulation des champs :

p1.nom

est le champ nom, un char[20] qui se manipule comme tout autre char[20]

p1.nom[2]

est le 3e caractère du champ nom

p1.age

est le champ age, un entier qui se manipule comme tout autre entier

 

strcpy(p1.nom, "Dupont") ;

p1.age  = 34 ;

n = p1.age ;

 

Initialisation à la déclaration :

struct personne z = {"Dupont", "Jean", 34, 1.75} ;

 

Affectation :

p1 = p2

copie dans p1 la structure contenue dans p2.

 

Attention, ceci marche pour les structures et pas pour les tableaux. Ca marche même pour les structures contenant des tableaux, mais pas pour les tableaux (contrairement à d’autres langages).

 

Les comparaisons de structures avec == ou != ne marchent pas (contrairement à d’autres langages).

 

On peut composer structures et tableaux, exemple :

 

struct date

{

      int jour, mois, an ;

} ;

 

struct personne

{

      char nom[20] ;   

      char prenom[20] ;

      struct date date_nais ;

} ;

 

struct personne LesPersonnes[100] ;

 

LesPersonnes[i].date_nais.jour = 30 ;

 

Exemple, comparaison de dates :

 

struct date

{

      int jour, mois, an ;

} d1, d2 ;

 

if (d1.an < d2.an)

      r = -1 ;

else if (d1.an > d2.an)

      r = 1 ;

else if (d1.mois < d2.mois)

      r = -1 ;

else if (d1. mois > d2. mois)

      r = 1 ;

else if (d1.jour < d2. jour)

      r = -1 ;

else if (d1. jour > d2. jour)

      r = 1 ;

else r = 0 ;

 

7. Déclarations de type

 

typedef permet de déclarer des types.

On met derrière la même chose qu’une déclaration de variable, on déclare ainsi un type au lieu d’une variable.

 

Exemple :

typedef int TAB10[10] ;

déclare tab10 comme le type tableau de 10 entiers.

 

On peut ensuite déclarer des variables de ce type :

TAB10 ta, tb ;

 

Autre exemple :

 

typedef struct

{

      char nom[20] ;   

      char prenom[20] ;

      struct date date_nais ;

} PERSONNE ;

 

PERSONNE p1, p2 ;

           

8. Compléments

 

PlusPlus et MoinsMoins

 

++ et -- sont des opérateurs unaires qui s’appliquent de façon préfixée ou postfixée à une variable entière (y compris de type char). Priorité 14.

 

Préfixé : ++n augmente n de 1 et rend la valeur obtenue.

Postfixé : n++ augmente n de 1 et rend la valeur avant l’augmentation.

Préfixé : --n diminue n de 1 et rend la valeur obtenue.

Postfixé : n-- diminue n de 1 et rend la valeur avant la diminution.

 

Certains utilisent les termes incrémentation et décrémentation.

 

Afficher les éléments d’un tableau :

for (i = 0 ; i < NN ; i++) printf("%d ",tab[i]) ;

 

Calculer la longueur d’une chaîne :

for (lg = -1; a[++lg] != '\0';);

 

 

Les énumérations

 

enum {AVANT, PENDANT, APRES}

 

Déclare 3 constantes de type int et leur donne les valeurs 0, 1 et 2.

On peut choisir les valeurs :

enum {AVANT = 15, PENDANT = 25, APRES = 35}

 

L’instruction switch

 

Exemple :

 

enum {AVANT, PENDANT, APRES} ;

 

switch(moment)

{

case AVANT : a = b + c ; break ;

case PENDANT : a = 2 * b + 2 * c ; break ;

case APRES : a = 3 * b + 3 * c ; break ;

}

 

Si moment vaut AVANT, on effectue a = b + c  et, du fait du break qui suit, on quitte le switch.

 

Syntaxe :

switch(<expression>)

{

case <exp-const1> : <liste-d-instructions1>

...

case <exp-constN> : <liste-d-instructionsN>

default : <liste-d-instructionsD>

}

 

<exp-constx> est une expression constante (sans variable), exemple NN+4 dans laquelle NN est une constante.

 

default est facultatif.

 

On évalue <expression>, on cherche la première <exp-constx> égale à cette valeur. Si on trouve, on exécute les instructions qui suivent. Si on rencontre un break, on quitte le switch.

Si on ne trouve pas et qu’il y a un default, on exécute les instructions qui suivent le default.

Si on ne trouve pas et qu’il n’y a pas de default, on ne fait rien.

 

Attention, avec :

 

switch(i)

{

case 2 : a++ ;

case 4 : a++ ;

case 5 : a++ ;

}

 

Quand i vaut 2, a est augmenté de 3 car il n’y a pas de break. Quand i vaut 4, a est augmenté de 2.

 

L’instruction break

 

Elle permet de sortir d’une instruction for, while, do, switch.

 

Au lieu de :

      do

      {

            printf("Donner un nombre (999 quand fini) \n");

            scanf("%d",&nb);

            if (nb != 999) somme = somme + nb;

      }

      while (nb != 999);

 

on peut écrire :

      while (1)

      {

            printf("Donner un nombre (999 quand fini) \n");

            scanf("%d",&nb);

            if (nb == 999) break ;

somme = somme + nb;

      } ;

 

Dans les boucles imbriquées, cela concerne la boucle interne.

L’instruction continue

 

Elle arrête l’itération en cours d’une instruction for, while, do et passe à la suivante.

 

for (i = 1 ; i < 10 ; i++)

{

      if (tab[i]<0) continue ;

     

      …

}

 

Dans les boucles imbriquées, cela concerne la boucle interne.

 

Ligne suite

 

Une ligne se terminant par « \ » indique que la ligne suivante est la suite.

 

printf("C’est une chaîne un peu longue qui est écrite \

sur deux lignes");

 

Commentaire //

 

Avec de nombreux compilateurs (mais pas tous), // indique le début d’un commentaire se terminant à la fin de ligne, comme dans de nombreux langages.

 

while (1) // boucle infinie, sortie par break

{

}

 

La conditionnelle ? :

 

C’est un si alors sinon qui est une expression, qui rend une valeur.

 

Syntaxe :

<expression1> ? <expression2> : <expression3> 

 

Signifie :

Si <expression1> alors rendre la valeur de <expression2> sinon rendre la valeur de <expression3>

<expression1> est une expression entière prise pour une expression logique.

 

Exemple :

 

m = (a < b + c) ? x : y+3 ;