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 :
gcc -o essai essai.c -lmDans le tableau 14.1, vous trouverez quelques fonctions mathématiques très utiles.
| 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 :
#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 :
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 :
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 :
int i=123;
printf("%d",i);int i=123;
fprintf(stdout,"%d",i);XV-E. Utilité des prototypes▲
#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 :
#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.
main () {
...
}plutôt que comme cela :
int main () {
...
}

