You are on page 1of 50

http://www.mysti2d.

net/polynesie/SIN/08/LangageC/p
rogrammationlangagec.html?
LesBasesDuDebutant.html
Les variables
La Mémoire Vive
Avant de s'intéresser aux variables, un minimum de connaissances est requis sur
la mémoire vive.
Je pense que tout le monde sait ce qu'est cette mémoire vive, vous pouvez toujours
faire une recherche pour vous éclaircir l'esprit. Bon voici quand même la mémoire
vive en photo :

On appelle ça une barrette de mémoire.
C'est donc avec ça que nous allons travailler (pas directement, c'est avec
la mémoire vive que nous allons travailler, mais tout est lié).

Il existe d'autres types de mémoire que nous ne verrons pas dans ce chapitre car
inutiles pour comprendre les variables.
Alors la mémoire vive (que j'abrégerai maintenant la RAM), c'est quoi ?
C'est une grande commode composée de plusieurs tiroirs ayant chacun
une adresse et une valeur.
Vous suivez ? On peut donc représenter la mémoire vive comme ceci :
Adresses

Valeurs

0

15

1

-2589

2

153.2586

3

-2.2

4

100201

...

...

1288995126

-56

Pour information, le tableau se lit ligne par ligne.
Et les 3 petits points représentent beaucoup d'autres lignes.
Les programmeurs ont l'habitude de nommer ces fameuses lignes, cases mémoire,
retenez donc bien ce terme, je risque de l'utiliser fréquemment.
Je vais donc moi aussi employer le mot case mémoire pour désigner et l'adresse
mémoire et la valeur correspondant à cette adresse.
Bien une variable, c'est un tiroir (une case mémoire), c'est tout ce que vous avez à
retenir.
Ce schéma est très simplifié, mais si vous le retenez, c'est déjà très bien.

Les adresses permettent à l'ordinateur de se repérer dans la mémoire vive.
On commence à l'adresse 0 et on fini à une adresse variable en fonction de
l'ordinateur.
En réalité, les ordinateurs n'ont pas tous le même nombre d'adresses, ça
dépend de la quantité de mémoire vive de l'ordinateur.

A chaque adresse on trouve une seule valeur, un nombre.
La RAM ne peut stocker que des nombres.
On verra un peu plus loin comment stocker des lettres, des mots ou des
phrases. Bien oui, s'il peut stocker que des nombres, comment fait-il pour
stocker des lettres ?

Une petite définition de la variable vous tente ? C'est parti !
Une variable est une information stockée dans la mémoire vive comportant une
adresse et une valeur, voilà.
On dit qu'elle est variable car elle peut varier au cours du temps, donc de
l'utilisation du programme.

Les Types De Variables

Nous avons vu une première définition d'une variable en nous aidant du
fonctionnement de la RAM.
Je vous ai dit qu'une variable est typée, nous allons voir les différents types de
variables les plus courants.
Chaque type peut stocker ses propres nombres, voyons ensemble les
types principaux.
char qui permet de stocker des lettres,

int qui permet de stocker des nombres entiers.

double qui permet de stocker des nombres décimaux, donc avec une virgule.
Attention, en programmation, la virgule est représentée par un point (.).
Déclarer Une Variable
Bon, on va enfin programmer, maintenant que vous savez ce qu'est une variable
typée.
Pour pouvoir utiliser une variable, il faut la déclarer, la mettre en mémoire à une
adresse.
int maVariable;
Voilà, c'est tout, ma variable de type int est déclarée. Elle est créée en mémoire à
une adresse libre.
On peut nommer sa variable n'importe comment. Il faut cependant que ça reste
lisible et ne pas utiliser de caractères spéciaux.
Voici d'autres noms possibles :
int maVariable;
double MASUPERVARIABLE;
double mapetitevariable;
float variable;
char MA_MEGA_SUPER_VARIABLE_QUI_TUE_CEUX_QUI_LA_LIRA;
Ici, la première écriture est la meilleure, elle est aux normes.
J'utiliserai donc toujours la première écriture pour ces types de variables
(effectivement, nous verrons d'autres types qui nécessiteront d'autres écritures).
Je commence par une minuscule et je mets une majuscule à chaque fois que je
rajoute un mot dans le nom de la variable.
A la compilation, le nom de la variable est remplacé par son adresse ce qui
permet à l'ordinateur de s'organiser, donc pas besoin de s'occuper des
adresses pour le moment (oui, pour le moment).
Retour dans le main (j'ai retiré les directives du préprocesseur), déclarons une
variable de type int.
int main()
{
int maVariable;
return 0;
}

Si vous faites une simple compilation, le compilateur vous indique warning:
unused variable `maVariable'.
Cela signifie que la variable n'est pas utilisée, elle est juste déclarée en mémoire,
elle existe donc et peut être utilisée.
Pour information, les variables que nous déclarons actuellement sont détruites
automatiquement à la fin du programme, nous ne gâchons donc pas
de mémoire !
Pour être précis, notre variable déclarée dans le main est détruite à la fin de la
fonction (donc de la fonction main).
Revenons à nos moutons, il faut utiliser cette variable ! printf permet
heureusement d'utiliser des variables, donc de les afficher !
int main()
{
int maVariable;
printf("maVariable = %d", maVariable);
return 0;
}
Heu ? Tu peux me donner un petit tuyau là ?
Ah oui pardon, vous ne comprenez pas.
En fait, vous pouvez comprendre. Le caractère spécial %d informe la
fonction printf qu'on veut afficher un int, mais il faut ensuite indiquer quelle variable
de type int on veut afficher, il faut donc l'écrire après une virgule comme ci-dessus.
C'est la fonction printf qui l'exige, moi j'y suis pour rien.
Notez aussi que si vous voulez afficher un double, il ne faut pas utiliser le caractère
spécial %d mais %f.
Alors si on compile et exécute notre programme on obtient...
maVariable = 2147348480
Oui c'est nul, je suis d'accord avec vous. Lorsque l'on déclare notre variable, elle se
place en mémoire à une adresse libre mais la valeur correspondante peut
être n'importe quoi (même 0).
En fait, c'est sans doute un ancien programme qui a laissé quelques résidus derrière
lui.
Donc je fais comment ?
Il faut changer la valeur de la variable !
C'est parti !

Modifier Une Variable
Comme vous l'avez vu précédemment, il est important d'initialiser une
variable pour qu'elle ne contienne pas n'importe quoi ! Comment ? En utilisant
l'opérateur d'affectation = pardi !
int main()
{
int maVariable;
maVariable = 5;
printf("maVariable = %d", maVariable);

return 0;
}
Voilà, c'est tout bête, il ne faut plus remettre le type de la variable ici, le nom suffit,
il veut tout dire.
On obtient alors le résultat attendu.
maVariable = 5
Pour rendre notre programme plus propre et aux normes, il est
préférable d'initialiser la variable dès sa déclaration, elle n'aura même pas le
temps de prendre une valeur hasardeuse.
int main()
{
int maVariable = 5;
printf("maVariable = %d", maVariable);
return 0;
}
On obtient le même résultat, 5, il est fortement recommander d'initialiser vos
variables comme ceci.
Utilisons maintenant des nombres décimaux et entiers dans un printf pour bien
comprendre.
int main()
{
int monEntier = 5;
double monDecimal = 5.;
printf("monEntier = %d\nmonDecimal =
%f", monEntier, monDecimal);
return 0;
}
Pour indiquer à printf que l'on affiche un double il faut utiliser %f et %d pour un int.
Ensuite, on met le nom des variables dans l'ordre sans oublier les virgules.
monEntier = 5
monDecimal = 5.000000
Les 0 inutiles ne sont pas très gênants, on n'utilise pas trop la puissance du
type double ici.
Je voulais juste vous dire qu'ici le 5. (avec le point) permet de dire au compilateur
que c'est bien un double que l'on veut mettre dans monDecimal et non pas un int,
sinon le compilateur aurait fait une conversion implicite (c'est une
conversion automatique) de int à double car il aurait considéré 5 comme un int (ce
n'est pas très grave mais quand on peut éviter, il faut éviter c'est tout).
On aurait tout à fait pu mettre 5.6895 à la place de 5. :
monDecimal = 5.689500
Pourquoi faut-il éviter les conversions ?

c'est tout pour les conversions. } Le compilateur va ajouter une virgule avec des 0 pour la conversion du int au double et il va tronquer les chiffres après la virgule pour la conversion du double au int. maConstante = 5. monDecimal). elle n'est donc pas faite automatiquement.85.85. Si vraiment vous devez réaliser une conversion. return 0. Le compilateur nous sort une erreur nous demandant pourquoi on essaie de . return 0. double monDecimal = 5. il y a deux conversions implicites qu'effectue le compilateur (double à int et int à double) : int main() { int monEntier = 5. le code source sera par la suite plus clair. monEntier = 5 monDecimal = 5. printf("MA_CONSTANTE = %d". évitez les conversions à outrance. vérifiez bien que ce nombre soit du même type que la variable sinon le compilateur effectue une conversion implicite (s'il en est capable bien entendu). lorsque vous stockez un nombre dans une variable. Voici comment réaliser une conversion contrôlée explicitement : int monEntier = (int)5. Il suffit d'ajouter le mot clé const devant le type de la variable lors de la déclaration pour rendre la variable constante (sa valeur ne peut pas être modifiée). Je vais maintenant vous parler du mot clé const. MA_CONSTANTE). monEntier. printf("monEntier = %d\nmonDecimal = %f". J'insiste avec ça pour bien vous montrer l'utilité d'initialiser les variables dès la déclaration. mais il ne faut pas en abuser. ce n'est pas propre.Regardez cette exemple. j'utilise les majuscules et un underscore (_).000000 Voilà. qui permet de rendre inchangeable la valeur d'une variable dès sa déclaration. Une dernière fois. regardez ce code provoquant une erreur : int main() { const int MA_CONSTANTE. prenez l'habitude de déclarer vos constantes avec des majuscules. le compilateur est capable de faire des conversions. } Ici. j'ai changé le type d'écriture du nom de la variable. utilisez la conversion explicite qui consiste à contrôler la conversion. plutôt d'utiliser la conversion implicite.

n'oubliez pas & un point c'est tout . printf("Ho ! Tu as %d ans !". n'essayez pas de comprendre (vous n'y arriverez pas). Prenez une pause et on se rejoint tout de suite dans le prochain chapitre. age). Les opérateurs . Il serait bien de pouvoir entrer un nombre au clavier (par exemple son âge) pour ensuite la stocker dans une variable (int age par exemple) et pouvoir l'utiliser par la suite ! Voici comment utiliser scanf : int main() { int age = 0. C'est une information que scanf a besoin pour fonctionner correctement. vous pouvez faire des programmes intéressants ! Voilà. après la virgule. enfin un programme qui a un intérêt (du moins presque). il faut écrire le nom de la variable dans laquelle on veut récupérer la saisie de l'utilisateur mais il faut précéder le nom de la variable par un &. Voilà comment créer des constantes. proche de printf. parlons un peu de scanf ! C'est une fonction. Avec printf et scanf. const int MA_CONSTANTE = 5. c'est un peu différent. On obtient donc un programme qu'on ne pourrait pas réaliser sans cette variable age. on utilise le caractère spécial %d pour informer la fonction scanf que l'utilisateur va entrer un int au clavier mais pour un double. Ne soyez donc pas surpris si vous en rencontrez un jour ! Pour finir. Quel age avez-vous ? 26 Ho ! Tu as 26 ans ! Voilà. La variable MA_CONSTANTE comporte une valeur dès sa déclaration (qui peut être n'importe quoi). qui permet d'interagir avec l'utilisateur. il faut utiliser %lf et non pas %f.modifier la valeur d'une constante (logique). il faut donc l'initialiser dès sa déclaration pour lui assigner une valeur de notre choix. scanf("%d". return 0. &age). printf("Quel age avez-vous ? "). vous en savez assez pour les variables ! Si nous faisons quelques calculs avec les variables pour encore mieux comprendre son intérêt ? Bien on verra ça dans le prochain chapitre car les opérateurs sont nombreux en C et méritent quelques explications. Ensuite. } Comme pour printf.

/* maVariable vaut 4 */ printf( »%d ».. Ils sont très simples à utiliser. /* maVariable vaut 12 */ printf( »%d ». Regardez cet exemple pour bien comprendre : int main() { double nombre1 = 0. les évaluer. 12 / 3). / division int maVariable = 12 / 3. c'est comme les mathématiques à l'école . On distingue plusieurs types d'opérateurs :   Opérateurs De Calcul Opérateurs D'Accumulation  Opérateurs Relationnels  Opérateurs Logiques  les opérateurs logiques Opérateurs De Calcul   Les opérateurs de calcul arithmétique permettent d'effectuer des opérations mathématiques entre deux valeurs et seulement deux valeurs. /* maVariable vaut 17 */ printf( »%d ». 5 + 12).. Opérateurs Descriptions Exemples + addition int maVariable = 5 + 12..12. /* maVariable vaut -7 */ printf( »%d ». c'est-à-dire effectuer des opérations. Je pense que ces opérateurs sont simples à comprendre malgré le modulo qui reste nouveau pour vous. %   modulo (reste de la division entière) int maVariable = 20 % 3.Le opérateurs sont des elements du langage C lui permettant de traiter les données en effectuant modifiant les variables. 5 – 12).. 20 % 3). - soustraction int maVariable = 5 . /* maVariable vaut 2 (car 20 = 3 * 6 + 2) */ printf( »%d ». 3 * 4). nombre2 = 0. . . * multiplication int maVariable = 3 * 4.

nombre1 printf("%d %% %d = %d". double nombre2 = 0. nombre2.500000 La particularité ici. c'est que les opérations sont effectuées directement dans les fonctions printf. nombre1. printf("Entrez un second nombre : ")..nombre2). voici le même programme écrit d'une autre façon :  int main() { double nombre1 = 0.000000 * 13. nombre1 printf("%f / %f = %f\n".000000 = = = = 15.%f = %f\n". * nombre2). nombre1 printf("%f * %f = %f\n". nombre2. on utilise %lf (même s'il entre un entier. }   On travaille avec deux variables double qui sont déclarés sur une même ligne ! En effet. &nombre1). nombre1.000000 11. (int)nombre2. (int)nombre1 %(int)nombre2). return 0. scanf("%lf". (int)nombre1. Dans le printf du modulo. printf("\n%f + %f = %f\n". nombre1. double resultat = 0. / nombre2). scanf("%lf". n'oubliez pas les conversions implicites). &nombre2). + nombre2).printf("Entrez un premier nombre : "). Pour demander à l'utilisateur d'entrer un double.000000 26. nombre1. nombre2.000000 13.000000 2.. on peut déclarer plusieurs variables d'un même type sur une même ligne en utilisant la virgule comme ci-dessus. . nombre2. nombre1 printf("%f .000000 / 13 % 2 = 1   2.000000 2.000000 6. on utilise %% pour afficher un simple % et on convertie les deux variables double en int pour pouvoir utiliser le modulo. le modulo s'utilise seulement avec des nombres entiers. On a donc un bon exemple de l'utilisation des conversions ! On obtient un super résultat révolutionnaire ! Entrez un premier nombre : 13 Entrez un second nombre : 2 13.000000 + 13. .. en effet.000000 2.

on convertie nombre1 et nombre2 en int pour faire le calcul et on convertie le résultat en double pour le stocker ensuite dans la variable resultat qui est un double. Il existe également deux opérateurs spécifiques pour l'incrémentation (++) et la décrémentation (--) unitaire. printf("%f . nombre1. /* i vaut 9 */ ++ incrémentation unitaire i++. printf("\n%f + %f = %f\n".  Opérateurs Descriptions Exemples (i = 4) += addition i += 5. nombre1. (int)nombre2. retenez bien ces opérateurs principaux. (int)resultat). printf("%d %% %d = %d". return 0. resultat = nombre1 + nombre2. /* i vaut 5 */ -= soustraction i -= 3. Opérateurs D'Accumulation Pour chacun des opérateurs de calcul. vous avez tout compris et pouvez passer à la suite. nombre2. &nombre2). }       Lors de l'opération avec le modulo. &nombre1). resultat = nombre1 . scanf("%lf". resultat = nombre1 / nombre2.%f = %f\n".nombre2. nombre1. Si vous avez compris que ces deux codes sont identiques. printf("%f / %f = %f\n". nombre2. resultat = nombre1 * nombre2. il existe un opérateur d'accumulation permettant d'alléger l'écriture en évitant les opérations de la forme maVariable = maVariable + 2. resultat). resultat). resultat). scanf("%lf". resultat = (double)((int)nombre1 % (int)nombre2). printf("%f * %f = %f\n". printf("Entrez un second nombre : "). nombre2. /* i vaut 3 */ *= multiplication i *= 4. /* i vaut 1 */ -- décrémentation unitaire i--. (int)nombre1. nombre1. Ce n'est pas les conversions le plus important ici. nombre2.printf("Entrez un premier nombre : "). resultat). /* i vaut 16 */ .

i = i * 2. c'est important de comprendre ce code source. // On retire 5 14. les chiffres après la virgule sont ignorés donc 10 / 4 = 2. En programmation.  /= division %= modulo i /= 2. i = i + 8. // On divise par 4 // On retire 1 5. i -= i += i %= // On ajoute 1 2. si vous avez réussi. ces opérateurs. . /* i vaut 1 (car 4 = 3 * 1 + 1) */ Pour comprendre. réessayez ! N'oubliez pas que 10 / 4 = 2 ! On travaille sur des entiers. // On conserve le reste de la division entière par 3 printf("%d". // On ajoute 14 3. je vous ai concocté un exemple identique au précédent pour vous aider à mieux comprendre ces opérateurs d'accumulation : int main() { int i = 0. un bon exemple bien commenté suffit je pense : int main() { int i = 0. je vous affiche quand même le résultat pour vérifier votre réponse ! 1   J'espère que vous avez réussi. i = i + 1. }   Je vous conseille fortement. // On ajoute 8 4. vous avez tout compris une fois de plus. // On affiche le résultat final return 0. d'essayer de calculer le résultat final. // On multiplie par 2 8. Bon. ça ne sert à rien de tricher. /* i vaut 2 */ i %= 3. i). si vous n'avez pas réussi. // On déclare un entier valant 0 i++. i *= i += i /= i--.5 ! Comme pour les opérateurs de calcul. il faut pratiquer pour s'améliorer.

14. /* monBooleen vaut 1 */ >= supérieur ou égal int monBooleen = 5 >= 5. i). printf("%d". return 0. il n'y a pas de type consacré aux booléens. le symbole = est l'opérateur d'affectation.i i i i i = = = = = i i i i i / + % 4. Un booléen est une variable auquel on fait prendre les valeurs 0 et 1 (0 pour faux et 1 pour vrai). Le résultat d'une opération relationnelle est une valeur booléenne. /* monBooleen vaut 0 */ < inférieur int monBooleen = 4 < 5. Tout d'abord. 3. vous devez avoir compris pas mal de choses. /* monBooleen vaut 0 */ != différent int monBooleen = 3 != 4. 5. un bon programmeur est un programmeur fainéant ! Opérateurs Relationnels Passons aux choses sérieuses. }         En C. Vous en avez fini avec les opérateurs d'accumulations. ils permettent juste d'alléger l'écriture mais sont à connaître obligatoirement. 1. voilà le tableau : Opérateurs Descriptions Exemples == égal int monBooleen = 8 == 7. /* monBooleen vaut 1 */ <= inférieur ou égal int monBooleen = 5 <= 4. /* monBooleen vaut 1 */ > supérieur int monBooleen = 5 > 5. l'instruction i = i + 1. on utilisera donc un int qui peut prendre les valeurs 0 et 1 pour simuler un booléen. En réalité. /* monBooleen vaut 0 */   Avec les exemples du tableau. Pour finir. . peut être traduite par i prend la valeur de i + 1. je tiens à vous préciser que je n'ai pas appelé ma variable i par hasard. toutes les valeurs différentes de 0 valent vrai mais on va éviter de compliquer les choses. En C. une variable dont sa valeur a tendance à varier à l'aide d'opérateurs d'accumulation est généralement appelée i.

// majeur vaut 1 (est vrai) si age est supérieur ou égal à 18 printf("\nage = %d\nmajeur = %d".  Quel age avez-vous ? 17 age = 17 majeur = 0    On aura l'occasion d'en reparler au chapitre des conditionnelles. l'utilité de ces opérateurs ne doivent pas vous paraître évident tout de suite. On passe tout de suite à la suite ! Opérateurs Logiques Une opération logique est une opération booléenne qui renvoie une valeur booléenne. . b et c. majeur = age >= 18. /* monBooleen vaut 1 */ Ca se complique maintenant ! Voyons ensemble des exemples avec 3 variables. majeur). int main() { int age = 0. Si b vaut 0 (est faux) ou c vaut 0 (est faux). a. a est le résultat d'une opération booléenne de b et c. retenez juste que 1 veut dire vrai et 0 veut dire faux. &age).Voici un code source que j'ai écrit pour tester si l'utilisateur du programme est majeur. Sans plus attendre. a vaut 0 (est faux). le tableau ! Opérateurs Descriptions Exemples && et int monBooleen = 1 && 1. majeur = 0. /* monBooleen vaut 0 */ ! non int monBooleen = !0. je n'insiste donc pas.  a = b && c : a vaut 1 (est vrai) si et seulement si b et c valent 1 (sont vrais). /* monBooleen vaut 1 */ || ou int monBooleen = 0 || 0. return 0. }   Cet exemple beaucoup plus concret nous affiche l'âge de l'utilisateur et la valeur du booléen majeur (vaut 0 si age est inférieur à 18 et vaut 1 sinon). age. printf("Quel age avez-vous ? "). scanf("%d".

Que voulez-vous boire ? 1. a = b || c : a vaut 1 si b vaut 1 ou si c vaut 1. printf("\nQue voulez-vous manger ?\n\n1. obese = viande == 1 && boisson == 2. printf("Que voulez-vous boire ?\n\n1. Eau\n2. . // obese vaut 1 (est vrai) si viande est égal 1 (Hamburger) et si boisson est égal 2 (Soda) printf("\nobese = %d". obese). ce n'est pas une partie de plaisir. } C'est un peu compliqué mais avouez que c'est terriblement logique non ? Si on a choisi le Soda (choix 2) et le Hamburger (choix 1) bien on est obèse.  a = !b : a vaut 1 si b vaut 0. scanf("%d". vous verrez dans le prochain chapitre que tout cela a un sens incroyable (oui je vous jure). Si b vaut 0. Soda\n\n"). scanf("%d". Hamburger 2. Porc 1 obese = 1 Je le reconnais. on demande à l'utilisateur une boisson et une viande. a vaut 1. le booléen obese vaut 1 (est vrai). &boisson). int main() { int boisson = 0. Eau 2. return 0. Hamburger\n2. a vaut 0. &viande). obese = 0. Soda 2 Que voulez-vous manger ? 1. viande = 0. Porc\n\n"). Un exemple pour bien comprendre. Si b et c valent 0.

. Mais ça serait dommage de ne pouvoir tester que l'égalité ! Il faudrait aussi pouvoir tester si la variable est inférieure à 50. vous avez vu les principaux et c'est l'essentiel. faits ceci".Retenez juste les descriptions de ces opérateurs.. .. je vous présente tout de suite dans un code source son mode d'emploi : if (/* Votre condition */) { // Instructions. je n'insiste pas plus sur les opérateurs. supérieure ou égale. bon. else if.. supérieure. il existe les opérateurs bit à bit qui sont plus complexes à assimiler pour un débutant alors on va s'en passer. terriblement logique non ? Commençons par le mot clé if. c'est tout. else Nous allons à présent donner un sens aux opérateurs logiques et relationnels ! La conditionnelle est un test réalisé avec des mots clés comme if et else. Voilà.. if qui peut se traduire par si et else par sinon. Les conditionnelles Qu'est-ce qu'une structure conditionnelle ? Les conditions servent à "tester" les variables.. sinon si. sinon. c'est un mixte des mots clés if et else qui signifie donc sinon si.. on exécute les instructions entre des accolades. if.. else if n'est pas un mot clé. notez qu'ils s'utilisent fréquemment avec les opérateurs relationnels et ce sera suffisant pour le moment. } Si (if) la condition est vraie.... inférieure ou égale à 50. Voici les mots clés les plus utilisés pour gérer une conditionnelle que je vous demande de connaître par coeur : if else if else si.. nous allons maintenant donner un sens aux opérateurs logiques et relationnels tout de suite dans le prochain chapitre. on peut par exemple dire "Si la variable machin est égale à 50.

je vous recommande de toujours mettre des accolades pour aérer votre code source.Notez que s'il y a une seule instruction dans un bloc (un bloc d'instructions est un ensemble d'instructions délimité par une accolade ouvrante ({) et fermante (})). La condition est fausse ! Modifiez la valeur du booléen et la condition sera vraie .. } else { printf("La condition est fausse !"). Modifions donc notre code source précédent. Néanmoins. soit 1 (vrai).. Écoutez bien ce que je vais vous dire. majeur = 0. qui permet d'exécuter des instructions si la condition est fausse. soit 0 (faux). } Comme monBooleen vaut 0. les accolades deviennent alors facultatives... Ca vous ne rappelle pas quelque chose ? Moi si . } return 0. . if (/* Votre booléen */) { // Instructions. c'est à dire. entre les parenthèses du if (où j'ai écrit Votre condition) vous devez mettre un booléen. if (monBooleen) { printf("La condition est vraie !"). la condition est fausse ! Vous comprenez maintenant l'utilité de else. } Observez ce code : int main() { int monBooleen = 0. Vous vous rappelez comment on obtient un booléen ? Avec les opérateurs logiques et relationnels pardi ! Vous souvenez-vous de ce code ? int main() { int age = 0.

// majeur vaut 1 (est vrai) si age est supérieur ou égal à 18 printf("\nage = %d\nmajeur = %d". majeur = age >= 18. Vous avez réussi ? Bravo. on peut directement effectuer l'opération relationnel entre les parenthèses du if : int main() { int age = 0. . Quel age avez-vous ? 17 age = 17 majeur = 0 Essayez maintenant d'afficher du texte à l'écran en fonction de l'âge de l'utilisateur. majeur = age >= 18. } return 0. &age). il faut éviter de déclarer le booléen majeur. scanf("%d". &age). par exemple. dites à l'utilisateur qu'il est majeur si (if) il a plus de 18 ans et qu'il est mineur sinon (else). ce n'est pas la bonne méthode. } Cependant.printf("Quel age avez-vous ? ").")."). return 0. scanf("%d". printf("Quel age avez-vous ? "). age. if (majeur) { printf("Tu es majeur. majeur). voici mon code source : int main() { int age = 0. } Le booléen majeur variait en fonction de la valeur de age. } else { printf("Tu es mineur. elle n'est pas claire. printf("Quel age avez-vous ? "). majeur = 0.

} else { printf("\nTon alimentation est correcte. tu risques de devenir obese !". Eau\n2. pour le fun. } else { printf("Tu es mineur. sinon (else). Porc\n\n"). printf("Que voulez-vous boire ?\n\n1. Le code source est alors beaucoup plus clair est peut être traduit comme ceci.. &viande). viande = 0.. } return 0."). &age). Soda\n\n"). printf("\nQue voulez-vous manger ?\n\n1. } return 0. obese). une autre instruction printf est exécutée pour afficher Tu es mineur. scanf("%d". Correction ! Oui déjà int main() { int boisson = 0. Les accolades ({ et }) du if et du else sont inutiles dans ce cas mais il vaut mieux ne pas les oublier pour rendre le code source plus clair. si (if) age est supérieur ou égal (>=) à 18. essayez de modifier le code source du chapitre précédent ou on demandait à l'utilisateur une boisson et une viande afin de lui signaler (via un printf) s'il va être obèse ou pas.").."). scanf("%d". &boisson). Hamburger\n2. Tenez. } . l'instruction printf est exécutée pour afficher Tu es majeur.. if (viande == 1 && boisson == 2) { printf("\nAttention.scanf("%d". if (age >= 18) { printf("Tu es majeur. soit 0 pour faux). } L'opération relationnel age >= 18 sera remplacé par un booléen à l'exécution (soit 1 pour vrai. C'est parti on ne triche pas.

&pays). Suisse\n\nChoix : "). nous allons imaginer un menu (oui encore). Canada\n3. l'utilisateur va être obèse seulement s'il a choisi le Soda et (&&) le Hamburger. Je ne vais pas m'amuser à décrire ce menu mot par mot. France\n2. on a un bon exemple de l'utilisation du else if ici. Le else if se place après le if et avant le else (s'il y en a un). nous allons demander à l'utilisateur son pays ! On pourrait très bien lui demander d'écrire son pays mais on ne sait pas encore le faire (et oui. int main() { int pays = 0. donc une liste de choix. les instructions entre ses accolades sont exécutées. Belgique\n4. France Canada Belgique Suisse Choix : 1 Tu es francais. si ce booléen vaut 1. Passons au mixte else if qui signifie sinon si. Si vous avez du mal. on ne fait que manipuler des nombres depuis le début). c'est presque tout à fait normal. . mais avec else if. c'est différent vous allez voir ! En plus. J'essaie de mettre la barre plus haute pour que vous compreniez mieux le principe des conditionnelles.  Si ce booléen vaut 0 et qu'il existe un else (qui se traduit par sinon) à la suite de ce if. Vous pouvez essayer de rédiger le code source en utilisant simplement des if. Il s'utilise en insérant un booléen entre ses parenthèses. Vous pouvez traduire booléen par condition et 0 et 1 par vrai et faux . 2. voilà donc le menu en console qui vaut beaucoup mieux : ||| VOTRE PAYS ||| 1. 3. on va donc se contenter d'afficher un menu comme ci-dessous. printf("||| VOTRE PAYS |||\n\n1. 4. Pour comprendre l'utilité du else if. scanf("%d". dites-vous que dans les parenthèses d'un if. Pour faire simple. essayez alors d'oublier les booléens. on met une condition remplacée par un booléen lors de l'exécution.Voilà. les opérateurs relationnels et caetera. Ce que vous devais retenir pour le moment sur le if et le else :  Le mot clé if se traduit par si. les instructions entre ses accolades sont exécutées.

j'ai découvert plus tard que c'était une condensation de ce code source : if (pays == 1) { printf("\nTu es francais. } else { if (pays == 3) { printf("\nTu es belge. 2) es belge.if (pays == 1) { printf("\nTu } else if (pays == { printf("\nTu } else if (pays == { printf("\nTu } else if (pays == { printf("\nTu } else { printf("\nTu } es francais."). 2) es canadien. } Personnellement.").")."). } else { if (pays == 4) { printf("\nTu es suisse. 4) es suisse."). return 0. } else { if (pays == 2) { printf("\nTu es canadien. j'avais un peu du mal à comprendre au début. } else ."). es un extraterrestre.").").").

Notez aussi que dans chaque bloc d'instructions (ici. on aurait eu plusieurs conditionnelles. tout est donc condensé dans un ordre logique. en plus il est plus clair.").{ printf("\nTu es un extraterrestre. Voici le même code que tout à l'heure en utilisant le switch."). entre accolades). vous n'êtes pas obligé de la respecter mais encore une fois. c'est que le else est exécuté si le if et les else if sont faux. non ce n'est pas propre. } } } } Après avoir vu ce code source ci-dessus. le switch est bien mieux ! switch Un switch permet de tester des égalités et seulement des égalités ! C'est donc un mot clé moins puissant qu'un if. rapide à écrire et propre. prenez l'habitude d'aérer votre code source ! Vous voyez donc bien que le else if condensé est plus simple à utiliser. on a une seule conditionnelle (du if au else). on écrit nos instructions ou nos blocs d'instructions une tabulation plus loin. c'est une norme. pour le cas d'un menu. j'espère pour vous aussi. c'est faux (c'est cependant une bonne question) ! Ici. ce n'est pas le plus important rassurez-vous . case 2 : printf("\nTu es canadien. Si on avait utiliser que des if. Il permet généralement de gérer un menu pour éviter d'avoir plein de else if de partout comme précédemment. Enfin. donc sans les else if : switch(pays) { case 1 : printf("\nTu es francais. l'avantage principal ici. break."). C'est beaucoup plus clair. break. . j'ai tout de suite tout compris pourquoi else if était un mixte de if et else. Comment auriez-vous fait le else en utilisant uniquement des if ? Avec encore un if comme ça : if (pays != 1 && pays != 2 && pays != 3 && pays != 4) Avouez que rien ne vaut quelques else if ici. alors pourquoi s'en priver ! Mais c'est carrément nul ! On peut faire la même chose avec plusieurs if ! Non.

vous pouvez utiliser default qui équivaut au bon vieux else.. break. on ne sait pas bien la syntaxe. } Plus court non ? Mais plein de nouveautés. break. permettent de répéter certaines instructions plusieurs fois sans avoir à recoder plusieurs fois ces instructions."). Voilà en gros l'important. Grave erreur ! Retenez bien cette syntaxe justement.    On commence par écrire le mot clé switch avec entre parenthèses la variable que l'on veut tester. elle est difficile à assimiler pour un débutant je le reconnais. Pour finir. dans un programme. Ensuite on utilise autant de case que d'égalités à tester et on n'utilise pas d'accolades mais le mot clé break qui permet de sortir d'un bloc. En C il existe trois types de boucles. nous parlerons de chacune d'elle. alors on utilise les else if. Bon. c'est comme les conditionnelles. on trouve ça compliqué.case 3 : printf("\nTu es belge."). le switch est vraiment utile croyez-moi. retenez bien la syntaxe d'un switch. on arrête là pour les conditions. nous allons commencer par étudier la boucle while qui a besoin d'un booléen pour fonctionner. le else. default : printf("\nTu es un extraterrestre. while (monBooleen) ."). le mixte else if et le switch et vous pouvez continuer ! Les boucles Les boucles. case 4 : printf("\nTu es suisse.. Au début on a vraiment pas le réflexe d'utiliser le switch. retenez bien le if. Les voici : * while * do / while * for * goto while Les boucles enfin ! Vous allez voir. int main() { int monBooleen = 1. on a besoin de booléens ! Il existe plusieurs types de boucles. break.

tant que (tant que est la traduction de while) monBooleen est vrai. c'est comme le if. Mais alors Vive Tetdoss ! est affiché à l'infini ? Vous avez tout compris ! J'obtiens ça en console : Vive Vive Vive Vive Vive Vive Tetdoss Tetdoss Tetdoss Tetdoss Tetdoss Tetdoss ! ! ! ! ! ! Je n'ai pas écrit Vive Tetdoss ! à l'infini pour une simple raison de mise en page. Vive Tetdoss ! Voilà. on rend faux monBooleen pendant l'exécution de la boucle au premier tour. la boucle continue. Si on rend faux monBooleen. monBooleen = 0. Notez tout de même que les boucles infinies sont utilisées quelques fois (pour afficher une fenêtre à l'écran par exemple).{ printf("Vive Tetdoss !\n"). c'est à dire que toutes les instructions entre les accolades sont exécutés. } return 0. donc la fonction printf est appelée une seule fois. les programmes n'aiment pas ça . int main() { int monBooleen = 1. Le but est d'éviter les boucles infinis. } Ici. } Voici comment s'utilise while. . il serait plus intéressant je vous l'accorde. while (monBooleen) { printf("Vive Tetdoss !\n"). de choisir le nombre de tours de la boucle et non pas 1 ou l'infini comme tout à l'heure. } return 0. sinon la boucle sert à rien en fait . la boucle s'exécutera une seule fois. Ici.

i est incrémenté (++) à chaque tour. Comme i est initialisé à 0. je trouve ce code source très intuitif. i i i i i i i i i i = = = = = = = = = = 0 1 2 3 4 5 6 7 8 9 Voilà. on répète la boucle. Ce code source affiche la valeur de i à chaque tour de boucle.. break. } Vive Tetdoss ! est affiché 10 fois ! Tant que i est strictement inférieur (<) à 10. } return 0. . int main() { int i = 0.. continue On peut utiliser un while pour faire un simple test comme un if ? Oui mais ça ne sert à rien. i++. while (i < 10) { printf("Vive Tetdoss !\n").Vous souvenez-vous de la variable i dont sa valeur a tendance à varier à l'aide d'opérateurs d'accumulation ? C'est le moment de découvrir toute sa puissance. la boucle est bien répétée 10 fois ! Pour mieux comprendre. mais pour votre culture voici un code source (à ne jamais copier évidemment) : int main() { int age = 0. autant utiliser un if franchement. je vous modifie le printf : printf("i = %d\n". i).

do { printf("i = %d\n". le compilateur plantera ! Retenez juste que do permet d'utiliser while après un tour de boucle et ce sera bien croyez-moi . C'est tout pour la boucle while. i comme itérateur ). celle-ci sera donc exécutée au moins une fois. } Le mot clé break permet de sortir d'un bloc d'instructions. break. Un exemple sans plus attendre. c'est une erreur fréquente chez les débutants sinon. continue s'utilise de la même façon que break. C'est presque la même chose que while à la différence près que le test est effectué à la fin de la boucle. c'est le contraire du mot clé continue qui permet de passer directement à la prochaine itération (une itération est un tour de boucle. qui s'utilise avec while bien entendu.. Il permet ici de stopper la boucle et donc d'y sortir. Le code source ci-dessus affichera donc la valeur de i une seule fois puisque la condition est toujours fausse. elle est très facile à utilisée mais il existe d'autres types de boucles. while (age >= 18) { printf("\nTu es majeur !"). return 0. continue. i). &age). do/while Parlons de la boucle do/while. i = 0 . il ne faudra donc pas toujours utiliser while. } return 0. scanf("%d". } N'oubliez pas le point-virgule.printf("Quel age avez-vous ? ").. } while (i > 0). int main() { int i = 0.

for (i = 0. la syntaxe est le point le plus difficile à assimiler sur cette boucle. Mais pourquoi ? Telle est la question ! Reprenons le code source affichant 10 fois Vive Tetdoss !. pour ensuite commencer la boucle. i++) { printf("Vive Tetdoss !\n"). } Figurez-vous qu'une boucle for est beaucoup plus adaptée pour faire ce genre d'opérations. . int main() { int i. i++. for Le boucle for est très utilisée en programmation. } Non non. } return 0. L'initialisation s'effectue une seule fois et non pas à chaque tour de boucle (heureusement d'ailleurs). autant que while. int main() { int i = 0. C'est en partie pour cette raison que je n'ai pas initialisé ma variable i dès sa déclaration.C'est tout pour do/while. il faut juste que je vous explique ces 3 instructions :  i = 0. même plus. i < 10. la boucle for s'utilise comme la boucle while. while (i < 10) { printf("Vive Tetdoss !\n"). permet d'initialiser la variable compteur. i. 2 initialisations me semblent inutiles. je vais vous expliquer ! Il y a 3 instructions condensées entre les parenthèses du for. } return 0. restez. à part ça. ce n'est pas si terrifiant que ça.

Voilà donc toute la puissance du for ! Dans le code source. est la condition. . &nombre). nombre = 0. if (nombre < 1 || nombre > 3) // Si le nombre n'est pas compris entre 1 et 3 goto debut. il est source d'erreur. ce n'est donc pas une boucle. Dans notre cas.   i++ est l'incrémentation qui est effectuée à la fin de chaque tour de boucle et non pas au début. il y a une seule instruction entre les accolades du for.. Je ne plaisante pas ! Pour fêter ça. Cette condensation de 3 instructions est vraiment pratique. scanf("%d". c'est une incrémentation mais ça peut être d'autres opérations comme la décrémentation (--). debut : // debut est une étiquette printf("Entrez un nombre entre 1 et 3 : "). les accolades sont donc facultatives. Vive Vive Vive Vive Vive Vive Vive Vive Vive Vive Tetdoss Tetdoss Tetdoss Tetdoss Tetdoss Tetdoss Tetdoss Tetdoss Tetdoss Tetdoss ! ! ! ! ! ! ! ! ! ! Vous avez fini votre apprentissage basique du C..i < 10. un bloc d'une seule instruction est peu utile. je vais vous parler de goto et on fera un TP juste après ! goto Tout d'abord je tiens fortement à vous préciser une chose : Il est très très déconseillé d'utiliser goto car il rend le code source moins lisible. c'est comme pour while. Je pense qu'un exemple bien commenté suffit pour vous expliquer son utilisation : int main() { int i. et la plupart du temps on peut le remplacer par une boucle. // On saute à l'étiquette debut printf("\nBravo ! Tu as entre un nombre entre 1 et 3 !"). rien à dire. Un goto est un saut à une étiquette.

voici la fonction main constituée de deux instructions : int main() { printf("Salut tout le monde !"). return 0.return 0. l'ordinateur la connaît par coeur. . Rappelez-vous que chaque fonction est composée d'instructions. } Mon code source peut être écrit sans goto. le résultat : Entrez un nombre entre 1 et 3 : 0 Entrez un nombre entre 1 et 3 : 4 Entrez un nombre entre 1 et 3 : 2 Bravo ! Tu as entre un nombre entre 1 et 3 ! Comprendre Les Fonctions Jusqu'à présent. Pour clore ce chapitre. comme la gestion d'erreurs). nous avons travaillé à l'intérieur de la fonction main mais c'est une mauvaise habitude à ne surtout pas prendre ! Plus tard. C'est donc principalement pour cette raison que les fonctions existent. il faut donc toujours une fonction main dans votre projet sinon il ne compilera pas. les fonctions sont la base de la base ! On distingue 3 étapes importantes : * On envoie des informations en entrée à la fonction pour qu'elle puisse travailler par la suite. vous écrirez sûrement des codes sources beaucoup plus complets et tout serait concentré dans cette fonction main. on ne pourrait donc plus s'y retrouver. } Je vous rappelle également que main est la fonction qui est exécutée automatiquement par l 'ordinateur lors de l'exécution d'un programme. avec une simple boucle. Je vous présente en image le mécanisme d'une fonction : Ce schéma est à connaître. N'utilisez donc jamais le saut (goto) sauf dans certains cas (très rares. c'est déjà un élément important à retenir sur la fonction.

On reconnaît bien les 3 étapes d'un appel d'une fonction. vous avez tout compris . une fonction est nommée. j'ai déjà évoqué ce terme précédemment. Il est à connaître par coeur bien entendu. somme Imaginez maintenant une autre fonction calculant la somme de 2 nombres (6 et 2) : . triple D'autres exemples pour mieux comprendre ? Imaginez une fonction calculant le triple d'un nombre (4). * Enfin. Ce mécanisme est appelé en programmation un appel d'une fonction ! Ce n'est pas si nouveau que ça. Si vous avez compris ça.    Tehina appelle Mme Pujol et lui demande le triple de 4. C'est exactement le même principe que les cours de mathématiques avec f(x) (si vous les suivez ).* La fonction exécute un tas d'instructions à l'aide des informations qu'elle a reçu. Mme Pujol lui répond enfin fièrement 12. elle nous renvoie le résultat 12 en sortie. On peut donc dire que Pierre est l'utilisateur et Brigitte la fonction. Je vais vous raconter une petite histoire concrète pour bien comprendre. Mme Pujol calcule alors dans sa tête le triple de 4. Pierre a fait appel à Brigitte pour calculer le triple de 4. la fonction renvoie un résultat en sortie. on parle aussi de retour (return en anglais). la fonction effectue des opérations avec 4 et une fois qu'elle a fini. la professeur de mathématiques. vous allez voir c'est très très rigolo . je l'ai donc appelée triple : On envoie 4 en entrée. Tehina est un élève de la classe de Mme Pujol.

2 et 6 sont donc des paramètres de la fonction somme. imaginez une fonction qui affiche toujours la même chose à l'écran. On peut donc dire que la fonction printf ne prend qu'un paramètre en entrée. le texte. Elle se contente d'effectuer des opérations avec le texte. qui affiche du texte à l'écran : Elle est un peu particulière ! D'abord. Nous verrons qu'elles peuvent par contre ne rien renvoyer du tout. on lui envoie en entrée le texte à afficher à l'écran.. elle affiche tout bêtement le texte à l'écran. on envoie 2 informations en entrée et la fonction nous renvoie 8. Retenez bien ce terme. j'ai nommé. iaorana : Elle ne prend pas de paramètres en entrée. .Ici. c'est qu'elles ne peuvent en aucun cas renvoyer plusieurs informations. Notez que toutes les informations envoyées en entrée lors d'un appel d'une fonction sont appelées en programmation des paramètres. La particularité des fonctions. La fonction ne renvoie aucune valeur. rien. iaorana Pour finir. il est donc inutile d'en renvoyer une. Mais que voulez-vous qu'elle renvoie en sortie ? Bah. ici. je vais dès maintenant l'utiliser fréquemment ! printf Regardez maintenant la fonction printf.. Elle pourrait renvoyer une valeur mais elle serait toujours la même. et ne renvoie rien en sortie.

que dis-je de centaines de fonctions.. ces fonctions peuvent être utilisées par exemple pour afficher un message d'erreur. et si vous les mettez toutes dans un même fichier celui-ci va finir par être super long ! C'est pour cela que l'on a inventé ce qu'on appelle la programmation modulaire. Le principe est tout bête : plutôt que de mettre tout le code de votre programme dans un seul fichier (main.  Les fonctions qui prennent des paramètres en entrée mais ne renvoient aucun résultat en sortie. En effet.  Les fonctions monotones qui ne prennent pas de paramètres en entrée et donc qui renvoient rarement un résultat en sortie. Les Prototypes . que l'on compile séparemment. mais bientôt vos programmes vont être composés de dizaines.c).C'est bien gentil mais elles servent à quoi ces fonctions alors ? Elles sont utilisées pour éviter de répéter du code source.. La programmation modulaire Vous savez désormais qu'un vrai programme en C est composé de plusieurs fonctions. facile à maintenir et à modifier. Dès que l'on écrit un programme de taille importante ou destiné à être utilisé et maintenu par d'autres personnes. Ces règles d'écriture ont pour objectifs de rendre un programme lisible. C'est en assemblant toutes ces fonctions entre elles que l'on parvient à créer n'importe quel programme :) Seulement jusqu'ici nous n'avons travaillé que dans un seul fichier appelé main. Nous allons étudier précisément chaque fonction pour bien comprendre. triple et somme. En résumé. l'heure. portable. réutilisable. la date.. En particulier. Ici. nous avons distingué ces fonctions :  Les fonctions qui prennent des paramètres en entrée et renvoient un résultat en sortie. Chaque fonction sert à faire un travail précis et renvoie généralement un résultat. Ici. nous le "séparons" en plusieurs petits fichiers.. Pour le moment c'était acceptable car nos programmes étaient tous petits. Ici. il est indispensable de se fixer un certain nombre de règles d'écriture.c. il est nécessaire de fractionner le programme en plusieurs fichiers sources. iaorana. printf.

Maintenant. // Appel de la fonction triple printf("Le triple de ce nombre est %d.c ! Vous voyez bien que la compilation est tout de suite interrompue ! C'est un avantage monstrueux qui vous serait utile chaque jour.. imaginez la fonction triple sous la fonction main : int main() { . Quelques tests Nous allons dans cette partie réaliser quelques tests. observer les résultats puis conclure au fur et à mesure. Comme je suis un bon. deuxiemeNombre). le compilateur va connaître la fonction lors de l'appel à la fonction. En exemple. deuxiemeNombre = 2. nombre = triple(nombre. je vous propose d'envoyer trop de paramètres à la fonction triple du chapitre précédent : int triple(int nb) { return 3 * nb. je vais vous expliquer le pourquoi du comment ! En plaçant nos fonctions au-dessus de la fonction main. } Appuyez sur F9 et observez l'erreur de compilation. } int main() { int nombre = 4. il pourra donc nous dire par exemple si on a bien mis le bon nombre de paramètres et qu'ils sont du bon type.. return 0. nombre).Dans le chapitre précédent je vous avais demandé d'implémenter vos fonctions audessus de la fonction main.". je vous traduis l'erreur : Le compilateur nous indique qu'il y a trop de paramètres envoyés à la fonction triple à la ligne 14 dans la fonction main du fichier main.

5. Mais je vois pas d'erreurs donc c'est bon ! Non. } F9 et le programme se compile en nous renvoyant un simple warning ! Le programme fonctionne mais ce warning est très très déconseillé. nombre). int triple(int nb) { return 3 * nb. Si on envoie par exemple 5. nombre = triple(nombre). // Appel de la fonction triple printf("Le triple de ce nombre est %f.int nombre = 4.5 * 3 vaudra 15. nombre = triple(nombre. nombre). Il nous indique que la déclaration de la fonction est implicite ! Ca veut dire que la fonction est quand même déclarée. mais à la fin de la compilation.. return 0. Le compilateur pourra juste nous dire si la fonction triple existe ou pas mais en aucun cas nous aurons des informations sur ses paramètres etc. deuxiemeNombre). return 0.5 à la fonction triple. } int main() { double nombre = 5.5 sera ignoré et donc 5. // Appel de la fonction triple que le compilateur ne connaît pas ! printf("Le triple de ce nombre est %d.". deuxiemeNombre = 2. non. } .".. non et non ! Il y a beaucoup d'opérations ignorées comme les conversions implicites. } int triple(int nb) { return 3 * nb. le .

} int triple(int nb) { return 3 * nb. les programmeurs ont pensé à ça avant vous et ont inventé les prototypes . // Appel de la fonction triple que le compilateur ne connaît pas ! printf("Le triple de ce nombre est %f. Je vous en ai déjà parlé implicitement dans le chapitre 3. le compilateur ne bronche pas mais on a un résultat incompréhensible : Le triple de ce nombre est 0.000000.. La déclaration d'une fonction se nomme donc le prototype. return 0. donc le compilateur saura que la fonction attend un int. Je parlais de mode d'emploi dans le chapitre 3. Retenez seulement l'essentiel :   Des erreurs incompréhensibles sont évitées. nombre = triple(nombre). int main() { double nombre = 5. On n'oublie pas le %f et on obtient le résultat attendu : Le triple de ce nombre est 15. } Evidemment. Déclarer une fonction Moi je ne veux pas m'embêter à implémenter chaque fonction avant leur appel ! Rassurez-vous. vous pouvez donc oublier ça et retenir prototype.La fonction triple est placée au-dessus de la fonction main. Voilà une des raisons du pourquoi le compilateur doit toujours connaître les fonctions avant leur appel.".000000. donc si on lui envoie un double. on peut donc imaginer une grosse erreur bizarre.. il effectuera une conversion implicite. Nouveau terme à connaître par coeur bien entendu. Des informations sur l'appel des fonctions sont affichées s'il y a erreur. . nombre). Mais si le compilateur ne connaît pas la fonction triple au moment de son appel.5. Testons donc avec triple au-dessous de main.

Le compilateur saura qu'il existe une fonction nommée triple qui renvoie un int et qui attend un int en entrée. nombre = triple(nombre). C'est bien beau la théorie mais vous n'avez pas encore vu un prototype ! Regardez la fonction triple : int triple(int nb) { return 3 * nb. } int triple(int nb) { return 3 * nb.". vous avez juste à mettre son prototype avant l'appel de la fonction triple (je vous conseille de toujours mettre vos prototypes avant toutes les fonctions après les directives du préprocesseur. son prototype est la première ligne en ajoutant un point-virgule à la fin. c'est tout ! int triple(int nb). un prototype n'alourdie en aucun cas l'exécutable final.Qu'est ce qu'un prototype ? Bien c'est une information qu'on donne au compilateur pour pouvoir implémenter nos fonctions n'importe où dans notre code source. int main() { int nombre = 4. // Appel de la fonction triple que le compilateur connaît grâce au prototype ! printf("Le triple de ce nombre est %d. de la fonction main). // Prototype de triple Voilà. . int triple(int nb). } Vous êtes maintenant libre de placer vos fonctions où vous voulez dans le code source sans engendrer d'erreurs. return 0. Il faut donc toujours mettre le prototype au-dessus de chaque appel. le compilateur va reconnaître tous les appels et ça aura donc le même effet que de mettre la fonction au-dessus de chaque appel (ici. on peut donc dire qu'ils sont ignorés à la fin de la compilation. } Bien. nombre). Grâce à ça.

// Appel de la fonction triple et somme printf("Le resultat est %d. int main() { int nombre = 4. on aurait très bien pu mettre un prototype de ce style (cette méthode n'est pas très recommandée) : int triple(int). Conclusion. int b) { return a + b. n'oubliez jamais les prototypes des fonctions ! Pour finir. } Combien fera le résultat ? 3 * 4 + 4 vaut 16 donc resultat vaudra 16 ! Le resultat est 16. nombre = somme(nombre. triple(nombre)). int). } int triple(int nb) { return 3 * nb.". le compilateur se fiche du nom des paramètres. un exemple complet avec 2 fonctions pour bien comprendre les prototypes : int triple(int). return 0. } int somme(int a. Les Headers Rappels importants du chapitre 3 : .Vous l'aurez remarqué. int somme(int. nombre).

H). les prototypes des fonctions doivent toujours se trouver dans des headers ! Evidemment.. C'est une convention.a). retenez bien ce qui suit. il permet en fait au compilateur de s'organiser.C et *.La fonction printf est incluse à la fin grâce à la bibliothèque standard (libc. Rendre son code source modulaire ça veut dire le diviser (avec plusieurs *. pour créer un nouveau fichier. On a généralement un header pour un fichier *. comment diable arrivons-vous à compiler un programme faisant appel à printf sans engendrer de warnings ? Vous n'avez pas une petite idée ? Son header comporte son prototype ! Vous comprenez maintenant pourquoi je disais qu'un header c'est le mode d'emploi de plusieurs fonctions .. on peut faire des exceptions mais ce sera rare à partir de maintenant. le rendre le plus clair possible.C. cliquez sur New file : . si votre code source est tout petit. Nous allons rendre notre code source avec la fonction triple plus modulaire.

le fichier ne sera pas compilé..Commençons par ajouter un fichier *.C qui contiendra seulement la fonction triple comme ci-dessous..c j'ai l'habitude de garder que la fonction main. N'oubliez pas de cocher un mode de compilation. . si vous ne cochez rien. Notez que dans main.

Faites la même opération pour le header. comme ce sera le header de triple.c. implémentez-les ! Le prototype dans le header triple. les includes ! Il faut donc inclure notre prototype devant l'appel à la fonction triple ! . appelons-le triple : Une fois vos deux nouveaux fichiers créés.c. c'est pour ça que l'on a inventé les directives de préprocesseur. Vous obtenez ceci : Si vous compilez.h et la fonction triple dans triple. il y aura toujours le warning de la fonction déclarée implicitement.

Dans main. en effet.h. * Utilisez les chevrons pour inclure les headers du dossier include de MinGW comme <stdio.C sont compilés un par un automatiquement mais pas les headers. } Vous voyez. triple(4)). Je vous rappelle que chaque fichier *.C ayant un rapport avec la fonction triple. Il faut donc inclure le prototype de triple dans chaque fichier *.c : #include "triple.c. notre header est dans le même dossier que main. donc il faut utiliser les guillemets.h.c.h> #include "triple. par exemple. return 0. ici.C est compilé séparément. retenez bien cette idée) : . nous n'avons pas inclus triple. il faut donc les inclure dans les fichiers *. Incluez triple.h".En effet. ici.c.h pour que le compilateur sache si on a bien appelé la fonction.h>.C. } Votre code source est maintenant modulaire (certes.h" int main() { printf("Le triple de 4 est %d. il est tout petit mais l'idée est là. on inclue triple. dans triple. j'ai utilisé des guillemets pour inclure triple. les chevrons s'utilisent pour inclure des headers du dossier include de MinGW.h dans triple.". il faut justement l'inclure pour que le compilateur sache si on a bien implémenté la fonction.h> #include <stdlib. En résumé : * Utilisez les guillemets pour inclure les headers du projet comme "triple. tous les fichiers *.h" int triple(int nb) { return 3 * nb. #include <stdio.

J'ai déclaré dans ce code source plusieurs variables locales (donc dans différents blocs) : // Aucune variable déclarée int main() { int a. la phrase qui suit est plus qu'importante. // Une variable déclarée : a . c'est la phrase clé de cette partie. je suppose que cette question vous brule les lèvres. En d'autres termes. lorsque vous déclarez une variable entre deux accolades. la portée des variables et des fonctions ! Bon. elle est supprimée à l'accolade fermante.c ? Ou alors dans la fonction main ? Ou dans tous les fichiers du projet ? Nous allons donc voir ensemble dans cette partie.Ce code source n'est pas parfait. je me trompe ? En fait ça répond tout bêtement à la question suivante : Quand est-ce qu'une variable ou fonction est accessible ? Quand est-elle déclarée dans main. patience... on appelle ces variables des variables locales.. si si je vous jure . vous avez tout compris. une variable déclarée dans un bloc d'instructions est supprimée automatiquement à la fin de ce bloc ! Si vous avez compris ça. on commence par quoi ? bah les variables ! La portée des variables Attention. mais alors la portée c'est quoi. Voyons ensemble quelques exemples. il vous manque quelques directives de préprocesseur que nous verrons un peu plus loin. La Portée Intéressons-nous à la portée..

Comme le bloc est répétée 10 fois. .{ int b. pour ceux qui n'auraient pas encore très bien compris. et puis si vous compilez. // Déclaration d'une variable globale int main() { printf("%d". c'est tout ce que vous devez comprendre pour le moment. } // Aucune variable déclarée Ce n'est pas très difficile à comprendre. la variable nombre est déclarée puis supprimée 10 fois. for (i = 0. i < 10. // Deux variables déclarées : a et d return 0. } Ce code source ne sert à rien du tout. // Trois variables déclarées : a. autant vous prévenir tout de suite. On ne déclare pas ici 2 fois la même variable puisqu'elle est supprimée juste après sa déclaration. i++) { int nombre = 52. b et c } // Deux variables déclarées : a et b } // Une variable déclarée : a int d. } return 0. une variable a une durée de vie. variable). j'ai concocté un autre exemple : int main() { int i. Ca fait quoi si je déclare une variable dans aucun bloc ? Qu'attendez-vous pour essayer ! N'oubliez pas qu'une fonction est un bloc d'instructions ! int variable = 10. Tenez. // Deux variables déclarées : a et b { int c. vous verrez bien que le compilateur ne bronche pas.

Pour en déclarer. elle est accessible partout dans tous les fichiers du projet ! Il faut éviter les variables globales. C'est tout pour la portée des variables. il ne faut pas oublier d'ajouter le mot clé static comme ci-dessous : int variable = 10. la variable aura conservé sa valeur. return 0. } . Cette dernière ne sera plus supprimée à la fin de la fonction. } Ca marche ! Vous avez déclaré ce qu'on appelle en programmation une variable globale (à retenir. mais comme vous risquerez d'en rencontrer plus tard j'ai voulu vous en parler. } Méfiez-vous.return 0. Si vous voulez rendre une fonction globale accessible uniquement dans un fichier. rien de plus simple il suffit de déclarer une simple variable globale mais attention. Ca n'a donc pas le même sens que les simples variables globales statiques.c { printf("Salut !"). // Déclaration d'une variable globale accessible uniquement dans main. c'est un peu le même principe que les variables vous allez voir ! Lorsque vous créez une fonction. la prochaine fois qu'on appellera la fonction. il est très rare (et très très très très déconseillé) d'implémenter une fonction dans une autre ! Je considérerai donc que les fonctions sont toujours globales. elles sont plus rares mais peuvent s'avérer très utiles dans certains cas. La portée des fonctions Passons aux fonctions. il vous suffit d'utiliser le mot clé static comme tout à l'heure ! Traduction maintenant en image (suspense) : static void salut() // Fonction accessible uniquement dans main. vous venez de découvrir l'existence des variables globales qui sont à éviter le plus que possibl . Il existe aussi les variables globales accessibles uniquement dans un fichier. elle est généralement globale. si vous déclarez une variable statique (mot clé static) à l'intérieur d'une fonction. En effet. c'est le contraire de locale). donc accessible dans tous les fichiers du projet.c int main() { printf("%d". variable).

return 0. } C'est aussi simple que ça ! Je vous affiche le résultat pour vous prouver que je ne vous raconte pas de conneries depuis tout à l'heure .int main() { salut(). elle s'utilise à peu près de la même façon. Nombres Aléatoires . on peut facilement comparer une fonction à une variable. Salut ! Rien d'autres à dire sur les fonctions.

mais elle est forcément d'au moins 32767. pour notre jeu il va nous falloir tirer un nombre au sort.h> On peut maintenant utiliser la fonction rand qui génère un nombre aléatoire entier et positif ! En réalité. Alors. rand() Pour commencer. #include <stdlib.Avant de commencer. . Le hasard n'existe que dans la nature et n'a pas de sens en informatique. pour nous fournir des données aléatoires. Ce point important est (comme l'indique le titre). toutes les informations qu'il nous fournit sont calculées. qui est une constante définie dans stdlib.h pour pouvoir appeler des fonctions afin de résoudre notre problème. fermez la console et recommencez l'exécution ! La valeur ne change pas ! Si vous faites une boucle. On parlera alors de données pseudo-aléatoires. printf("%d". l'ordinateur ne sait pas faire ça. La valeur de RAND_MAX peut varier suivant les compilateurs. rand renvoie des entiers entre 0 et RAND_MAX. nombre). ce n'est pas à apprendre par coeur. le tirage d'un nombre aléatoire. Scoop du jour. n'oubliez pas d'inclure stdlib. moi j'obtiens 41. int main() { int nombre = rand(). return 0. } Je vous laisse exécuter votre programme. la valeur changera mais la suite de nombres sera toujours la même ! int main() { int i. nous allons étudier un point difficile. En effet. l'ordinateur doit simuler le hasard.h. 41 Maintenant. vous pourrez y revenir plus tard mais je tiens quand même à l'expliquer (comme ça le TP est complet). Cette fonction ne prend aucun paramètre (donc rien à mettre entre les parenthèses lors de l'appel de la fonction rand).

224 On peut dire que rand et srand communiquent entre eux. la suite de nombres sera toujours la même. on va lui envoyer la valeur NULL (c'est une constante valant 0. i < 3. return 0. i++) printf("%d\n". 41 18467 6334 Heureusement. on peut appeler rand dans un autre appel (ici. L'idée est donc d'initialiser cette donnée avec une valeur toujours différente.h. rand()). à chaque démarrage du programme. rand()). il existe la fonction time qui renvoie le nombre de secondes entre l'instant où elle est appelée et le 01/01/1970. la fonction printf). on ne va pas s'embêter.for (i = 0. } Avec ce code. // 57 est la donnée seed printf("%d". . Ma console m'affiche donc bien toujours la même suite de nombres. Pour l'appeler.. } En C. j'ai tout prévu ! srand() Les suites de nombres pseudo-aléatoires que peut nous fournir la fonction rand sont calculées à partir d'une donnée seed (graine).h> La fonction time renvoie un entier mais nous oblige à lui envoyer un paramètre. avec quelle valeur peut-on initialiser la donnée seed ? Avec la date actuelle ! Ca tombe bien. il faut inclure le fichier d'en-tête time. Si cette dernière n'est pas modifiée. à l'aide de la fonction srand ! int main() { srand(57).. j'obtiens bien une valeur différente (224) mais elle sera encore toujours la même à chaque exécution du programme puisque la donnée seed ne sera pas initialisée avec une valeur toujours différente. Dites-moi. // rand renvoie un nombre calculé à partir de la donnée seed return 0. #include <time. que nous verront plus tard).

x sera variable et c sera constant. 8745 % 37).int main() { srand(time(NULL)). on aura maintenant toujours une valeur différente ! Ouf ! Mais si je veux une valeur entre 0 et 100 ? Bonne question ! Nous allons pour ça reprendre quelques points sur le modulo ! Modulo Vous souvenez-vous du modulo ? L'opérateur arithmétique calculant le reste de la division entière ? Je vais vous parler uniquement de divisions entières. // rand renvoie un nombre calculé à partir de la donnée seed return 0. printf("8745 %% 37 = %d". On vérifie maintenant le résultat qui nous donne bien 13 : 8745 % 37 = 13 Soit c et x. Voici un exemple d'une division entière. Commencez par lire cet exemple bien commenté pour comprendre le modulo : . // Initialisation de la donnée seed printf("%d". deux entiers positifs que nous allons utiliser. Le reste est 13 donc 8745 % 37 vaut 13. rand()). } Voilà. oubliez le reste.

* c % x ne peut pas être égal à c. printf("c %% x = %d".(A * x) B = 7 . on peut dire que par exemple. /* Etape A : A = Il y a combien de fois x dans c ? A = Il y a combien de fois 2 dans 7 ? A = 3 Etape B : B = Il manque combien pour que A multiplié par x soit égal à c ? B = a . 482185 % 2812 sera compris entre 0 et 482185 + 1. Finalisation Nous voulons maintenant tirer au sort un nombre entre 0 et 100. } Le reste de la division de x par c est toujours compris entre 0 et c (exclu). c % x). srand(time(NULL)). int main() { int nombre = 0. il y a combien de fois 1 dans 4 ? Le quotient (résultat) est 4 et le reste 0. Exemple.(3 * 2) B = 1 Conclusion : c % x = 1 */ return 0. En conclusion. Démontrons cette affirmation ! * Un reste d'une division est toujours positif et peut être facilement égal à 0. 5 % 5 vaut 0 puisqu'il y a 5 fois 1 dans 5. // Initialisation de la donnée seed .int main() { int c = 7. Un reste est forcément inférieur au dividende puisqu'une division par 1 ne donne pas de reste. Il suffit d'utiliser le modulo ! Ce n'est pas pour rien si j'en ai parlé . Exemple. x = 2.

je vais utiliser des entiers constants pour stocker le maximum (MAX) et le minimum (MIN). srand(time(NULL)).1).. // rand partir de la donnée seed renvoie un nombre calculé à return 0. il fallait donc faire attention principalement aux priorités des opérations. on ne pourra donc pas tomber sur 0 int main() { int nombre = 0. // rand renvoie un nombre calculé à partir de la donnée seed return 0. Il faut alors retirer 1 dès la première opération avec le modulo.nombre = rand() % (100 + 1). Mais moi je veux que ce soit 1 le minimum pas 0 ! Il suffit d'ajouter 1 après l'opération. Si vous avez oublié pourquoi je fais ça. nombre). 0 + 1 vaut 1. nombre). // Initialisation de la donnée seed nombre = rand() % (100 + 1 . on tire alors au sort un nombre entre 0 et 99 puis on ajoute 1. nombre += 1. } Pour le code source final. si on tire au sort 0. par exemple. . J'ai raccourci un peu le code source pour le rendre plus clair. srand(time(NULL)).. // rand partir de la donnée seed renvoie un nombre calculé à return 0. relisez la partie sur le modulo. } Je n'ai pas oublié d'ajouter 1 pour pouvoir tirer 100 au sort. 1 et 100. nombre). printf("%d". } Oui c'est cool mais on peut tomber sur 101 ! J'attendais cette remarque ! Effectivement on peut tomber sur 101. on a réussi ! int main() { int nombre = 0. // Initialisation de la donnée seed nombre = rand() % (100 + 1). Comme ça. printf("%d". printf("%d". nombre += 1.

} Voilà. // rand renvoie un nombre calculé à partir de la donnée seed return 0. // MIN <= nombre <= MAX printf("%d". il va vous servir pendant la suite de ce TP.MIN)) + MIN. on a réussi à tirer au sort un nombre entre 1 et 100. nombre). MAX = 100. const int MIN = 1. srand(time(NULL)). c'est très important ! .int main() { int nombre = 0. // Initialisation de la donnée seed nombre = (rand() % (MAX + 1 . gardez ce code précieusement. et la pratique. Il faut dire que vous n'avez pas encore beaucoup pratiqué.