Le C en 20 heures


précédentsommairesuivant

XV. En deuxième lecture…

XV-A. Quelques fonctions mathématiques

Pensez à inclure le fichier d'en‐tête math.h et compilez en tapant :

 
Sélectionnez
gcc -o essai essai.c -lm

Dans le tableau 14.1, vous trouverez quelques fonctions mathématiques très utiles. 

Table 14.1 - Quelques fonctions mathématiques
Fonction Explication Exemple
exp(x) fonction exponentielle y=exp(x)
log(x) logarithme naturel y=log(x)
log10(x) logarithme à base 10 y=log10(x)
pow(x,y) xy z=pow(x,y)
sqrt(x) racine carrée de x y=sqrt(x)
fabs(x) valeur absolue y=fabs(x)
floor(x) arrondir en moins floor(1.9) renverra 1
ceil(x) arrondir en plus ceil(1.4) renverra 2
sin(x) sinus de x y=sin(x)
cos(x) cosinus de x y=cos(x)
tan(x) tangente de x y=tan(x)

XV-B. Pointeurs et structures

Voici un programme qui utilise un pointeur sur une structure :

 
Sélectionnez
#include <stdio.h> 
typedef struct {
   char  nom [40];
   char  prenom [20];
   int   age;
} personne;
int main () {
   personne p;
   personne * pointeur_sur_une_personne;
   printf("Veuillez entrer le nom de la personne:");
   scanf("%s",p.nom);
   printf("Veuillez entrer le prénom de la personne:");
   scanf("%s",p.prenom);
   printf("Veuillez entrer l'âge de la personne:");
   scanf("%d",&p.age);   /* ne pas oublier le '&' !!! */
   pointeur_sur_une_personne=&p;
   printf("Voici les caractéristiques de cette personne:\n");
   printf("nom=%s\n",(*pointeur_sur_une_personne).nom);
   /* autre façon de l'écrire */
   printf("nom=%s\n",pointeur_sur_une_personne->nom);
   return 0;
}

Notez que cette seconde écriture (plus pratique à l'usage) repose sur une flèche qui est construite avec le signe moins (-) et le signe supérieur (>).

XV-C. En finir avec les warnings du gets

En première lecture, nous pourrions dire que ce type de warning est « normal ». Prenons un exemple :

 
Sélectionnez
char chaine[10];
gets(chaine);

Supposons que votre programme soit utilisé sur Internet et qu'un utilisateur malveillant entre une chaîne de caractères plus grande que 10 caractères, par exemple « ABCDEFGHIJKLMNOPQR ». Dans ce cas, à l'exécution, votre programme va recopier à partir de l'adresse de la variable chaine les caractères A, B…… jusqu'à R. Dès lors, les zones mémoires qui suivent la variable chaine seront écrasées. Ceci explique que le compilateur vous indique un warning.

Pour y remédier, vous pouvez utiliser :

 
Sélectionnez
char buffer[128];
fgets(buffer, 128, stdin);

en sachant que stdin (mis pour standard input c'est-à-dire entrée standard) désigne le plus souvent le clavier.

fgets présente une particularité que n'avait pas gets : elle place un \n à la fin de la chaîne qui a été lue (juste avant l'\0).

XV-D. Sortie standard : stdout

Nous venons de voir que stdin désignait la plupart du temps le clavier.

De la même façon, stdout (mis pour standard output c'est-à-dire sortie standard) désigne le plus souvent l'écran du terminal.

Les deux programmes suivants sont équivalents :

 
Sélectionnez
int i=123;
printf("%d",i);
 
Sélectionnez
int i=123;
fprintf(stdout,"%d",i);

XV-E. Utilité des prototypes

Rappelez‐vous qu'il est plus prudent de placer tous les prototypes de fonctions que vous appelez juste en dessous des #include. Un prototype est l'en-tête d'une fonction.
 
Sélectionnez
#include <stdio.h> 
float mystere (int i); // prototype de la fonction mystère
int main () {
   int j;
   printf("Entrez une valeur:");
   scanf("%d",&j);
   printf("Résultat de la fonction mystère:%f\n",mystere(j));
}
float mystere (int i) {
   return i*i;
}

Voyons ce qui se produit si nous omettons le prototype :

 
Sélectionnez
#include <stdio.h> 
int main () {
   int j;
   printf("Entrez une valeur:");
   scanf("%d",&j);
   printf("Résultat de la fonction mystere:%f\n",mystere(j));
}
float mystere (int i) {
   return i*i;
}

Au moment où le programme rencontre l'appel à la fonction mystere, le compilateur découvre pour la première fois cette fonction. Or il ne sait pas ce que fait cette fonction et a fortiori il ignore le type du résultat qui sera renvoyé. Dans ce cas, le compilateur suppose (à tort dans notre exemple) que ce résultat sera du type int (qui est le type par défaut). Ceci risque de poser des problèmes dans la suite (et provoquera l'émission d'un avertissement) quand le compilateur s'apercevra qu'en fait, la fonction renvoit un float.

Le fait que int soit le type par défaut explique pourquoi nous pouvons nous permettre d'écrire un main comme ceci :
 
Sélectionnez
main () {
   ...
}

plutôt que comme cela :
 
Sélectionnez
int main () {
   ...
}

précédentsommairesuivant

  

Licence Creative Commons
Le contenu de cet article est rédigé par Eric Berthomier et Daniel Schang et est mis à disposition selon les termes de la Licence Creative Commons Attribution 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2013 Developpez.com.