Un programme est une suite d'instructions à destination d'une machine. Pour que cette machine puisse interpréter le
programme, il faut que celui-ci soit en langage machine. Ce langage se compose de deux symboles le 0 et le 1 (langage
binaire donc).
Ils existent de très nombreux programmes : des logiciels de traitement de texte ( Word, OpenOffice.org, ... ), des jeux
(World of Warcraft, la Dame de Pique, ...) et bien d'autres. Mais il a bien fallu les créer ces programmes, pour cela il a fallu
les programmer.
Programmer ?
Programmer c'est le fait d'écrire sur une machine, (un ordinateur en l'occurrence), un programme. Nous savons que
l'ordinateur ne reconnait que le langage machine. Mais il apparait évident qu'écrire des lignes et des lignes de 0 et de 1 serait
très compliqué, voir impossible.
De plus la détection d'erreurs s'avèrent exclue.
C'est pour cela qu'il a été créé ce que l'on appel des langages de programmation. Ils ne servent ni plus ni moins qu'à rendre
humainement possible l'écriture de programme. Il existe de nombreux langage comme le JAVA, le C++, le Pascal, le Python,
le Ruby, le C, ...
Le programmeur écrit le code source ( ce terme sera expliqué prochainement ) de son programme dans le langage qu'il
souhaite puis, à l'aide d'un compilateur, ce code est traduit en langage machine.
Pourquoi le C ?
Vous l'avez donc compris il va nous falloir choisir un langage de programmation. Nous choisirons le C.
Le C est un langage assez simple, pour ses bases en tout cas ... Il est utilisé par de nombreux développeurs ( =
programmeurs). De plus il est possible de réaliser de nombreuses choses. Par exemple une partie de l'OS que vous utilisez
actuellement a été codée en C.
Il est possible d'écrire ses codes sources directement depuis le bloc-note de Windows, mais pour avoir un résultat direct, il
vaut mieux avoir ce que l'on appel un IDE. Voyons cela dans le prochain chapitre.
Avant de nous lancer dans la programmation, il est important de s'équiper de certains outils. Nous allons avoir besoin de 2
outils différents :
Un Compilateur : il transformera nos lignes de codes en programme exécutable
Un Editeur de Texte : il nous servira à écrire nos codes-sources.
Vous pouvez choisir d'utiliser ces deux outils séparément. Mais il existe ce que l'on appel des IDE (Integrated Development
Environment (Environnement de Développement Intégré)). Qui nous permettront de saisir notre code source et de le
compiler sans lancer deux programmes distincts. En effet un IDE contient tout les outils nécessaires au développement
d'applications.
Il en existe plusieurs pour Windows : Code::Blocks, Visual C++ Express sont les principaux.
Sous Linux on retrouve aussi Code::Blocks, mais ici je vous montrerai comment compiler grâce au terminal. C'est une
méthode rapide et tout aussi intéressante qu'utiliser un IDE.
A noter qu'il existe aussi Dev-C++ qui n'a rien à envier aux IDE ci-dessus. Seulement son développement semble être à
l'abandon, c'est pourquoi il est de moins en moins utilisé.
Personnellement j'utilise Code::Blocks car il est multi-plateforme, très souvent mis à jour et considéré comme l'un des
meilleurs IDE pour le développement d'applications C.
J'expliquerai cependant l'installation de Visual C++ Express.
Choisissez celui que vous souhaitez utiliser. N'hésiter pas à faire un tour sur les sites de ces différents logiciels. Une fois fait
rendez vous au paragraphe approprié en fonction de votre choix et de votre OS.
Ne connaissant pas MAC OS je ne pourrai malheureusement pas vous aider, mais sachez qu'il existe XCode pour le
développement d'applications C sous cet OS.
Une fois installer ouvrez le logiciel. Créer un nouveau projet. Fichier >> Nouveau >> Projet
Choisissez "Application Console Win32", donner lui un nom (ici "HelloWorld" et un répertoire (l'endroit ou sera stocker vos
fichiers sources ainsi que l'exécutable), comme ceci :
Une fois cela fait vous devriez revenir à l'écran d'accueil avec un menu créer sur la gauche. Sans plus attendre créons notre
fichier main, de cette manière :
On y est presque . Maintenant il faut juste cliquer sur le menu "Projet" puis "Propriétés de (nomDeVotreProgramme)".
Une nouvelle fenêtre s'ouvre. Cliquez dans le menu à gauche sur "Propriétés de Configuration" puis "C/C++" et enfin "Avancé"
et dans la ligne "Compilation sous" choisissez "Compiler comme Code C (/TC)". Comme ceci :
Voilà vous êtes fin prêt rendez vous donc au paragraphe "Premier programme C"
Sans plus attendre allez donc télécharger le logiciel à cette adresse : Code::blocks
Télécharger le fichier "codeblocks-8.02mingw-setup.exe"
Ensuite, installer le logiciel comme vous avez l'habitude, il s'installe assez rapidement et facilement.
Si vous avez bien installé, vous devez avoir cette Écran au démarrage :
Pour créer un nouveau allez dans File et choisir New Project, cette fenêtre s'ouvre :
Dans la fenêtre qui suit, mettez un titre au projet, choisissez un répertoire pour le projet, puis cliquez sur Next.
Enfin dans la dernière fenêtre décochez "Create Debug Configuration" mais laissez coché "Create release Configuration",
vérifiez aussi que dans compiler ce soit GNU GCC Compiler qui soit choisi.
Vous vous retrouvez sur votre fenêtre de travail avec dans le workspace, le nom du projet, cliquer dessus, puis Sources, et
enfin main.c.
L'environnement de Code::Blocks
Quand on commence tout juste à utiliser Code::Blocks on peut trouver tout ces menus et boutons assez envahissant c'est
vrai, mais pourtant seulement quelques uns d'entre eux vont nous servir au début. Ne vous inquiétez donc pas du reste pour
le moment
Voici les trois boutons que vous devrez connaitre pour le moment :
De gauche à droite :
<puce>Build : Ce bouton permettra de "transformer" notre code C en exécutable.
Run : Ce bouton permet de lancer l'exécutable qui vient d'être créé pour avoir un aperçu de ce qu'on fais par exemple
Build and Run : C'est ce bouton que vous utiliserez le plus souvent, il permet de faire les deux actions précédentes
Si vous êtes sous Linux et que vous ne souhaiter pas utiliser d'IDE il existe une alternative très intéressante qui consiste à
compiler directement depuis la ligne de commende. Pour cela assurez vous bien d'avoir mis à jour votre système et d'avoir le
compilateur gcc grâce à la commende :
Code console:
Ensuite créez un nouveau fichier dans votre éditeur de texte favori, personnellement j'utilise Gedit pour la colorisation
syntaxique du texte. Une fois votre code tapée, enregistrez le sous la forme nomDeMonFichier.c. Ouvrez ensuite le terminal
et rendez vous dans le dossier où est situé votre fichier grâce à la commande :
Code console:
cd chemin
Une fois cela fait appelez gcc puis donner lui 4 arguments, dans l'ordre :
Pour lancer votre programme il suffit juste de se trouver dans le répertoire de votre exécutable (par défaut celui où se
trouve vos sources) et de taper :
Code console:
./nomDuProgramme
Premier programme C
Code c:
#include <stdlib.h>
#include <stdio.h>
int main ()
{
printf("Hello world!\n");
return 0;
}
Si ce n'est pas le cas je vous demande d'effacer ce qui se trouve dans la zone d'écriture et d'y recopier le code ci-dessus.
Code c:
int main ()
{
...
}
Voila ce qu'on appel une fonction. Elle a pour tache de réaliser des instructions bien précises. "main" nous indique ici qu'il
s'agit de la fonction principal du programme.
A savoir qu'en langage C le programme débute toujours par la fonction "main". Il est donc obligatoire de nommer sa fonction
ainsi, car il peut y avoir un nombre quelconque de fonctions dans un code écrit en C.
Mais ne nous y intéressons pas pour le moment.
Code c:
{
printf("Hello world!\n");
return 0;
}
A noter que les instructions d'une fonction sont toujours entre crochet " { " lorsqu'elle débute et " } " lorsque le fonction se
termine. Chaque instruction se termine par un " ; ". Rappelez vous en car il s'agit d'une erreur extremmement courante.
Code c:
#include <stdlib.h>
#include <stdio.h>
On appel cela des directives de préprocesseurs ... Un nom barbare et une utilité que nous détaillerons plus tard.
Voila nous avons fait le tour du programme. Pour voir ce que va donner ce code vous n'avez plus qu'à appuyer sur la touche
F9 de votre clavier. Raccourcie du " build and run ".
Sous VC++ Express pressez F7 puis rendez vous dans le réperoire Debug ou Release du dossier où se trouve votre code source.
Code c:
printf("hello world!\n");
par :
Code c:
printf ("Bonjour\n Votrepseudo !\n");
ou encore :
Code c:
printf("Bonjour\n");
printf("je suis\n");
printf("Votrepseudo\n et je programme en C!\n");
Les caractères accentués ne sont pas affichés sur la console de Windows. Ne vous inquiétez pas pour autant c'est un
problème lié à Windows et non pas à nos petits programme
Les commentaires
Dans les petits programmes ci-dessus il n'était pas très utile de commenter ce que l'on a fait, mais lorsque vous commencerez
à écrire des programmes assez long, vous trouverez utile de retrouver la signification de ce que vous aviez codé.
Le C permet cela. En insérant les symboles " /* " au début et " */ " à la fin de ce que vous vouliez écrire. Prenons l'exemple
du programme que nous avons étudiez :
Code c:
#include <stdlib.h>
#include <stdio.h>
int main ()
{
/* Ceci est un commentaire */
Ceci n'est pas un commentaire !
printf("Hello world!\n");
return 0;
}
La ligne du commentaire n'est pas compilé et n'est visible que pour le programmeur, on ne la retrouve pas afficher en
message dans la console par exemple.
Les commentaire peuvent s'étendre sur plusieurs lignes :
Code c:
#include <stdlib.h>
#include <stdio.h>
int main ()
{
/* Ce commentaire
s'étend sur
plusieurs ligne */
printf("Hello world!\n");
return 0;
}
On peut aussi remplacer " /* " par " // " les deux slashs, le problème ici est que le commentaire ne devra se situer que sur
une seule ligne. C'est pour cela qu'il vous faut préférer
le " /* " au " // ".
Dans le prochain chapitre nous commencerons enfin à programmer, de tout petits programmes certes mais vous
programmerez !
Une variable sert à contenir des données, ces données peuvent Être des nombres (entier, relatif, décimaux, rationnel,
irrationnel, réel (après c'est un peu plus complexe à gérer ?)), une chaine de caractères (une lettre, un mot, une phrase), ou
bien le résultat d'une fonction que nous verrons bientôt. en C, ce sera surtout des nombres. Une variable en C sera stockée
dans la mémoire de votre ordinateur. Ainsi, on est limité en variable, c'est pourquoi il faudra en utiliser le moins possibles.
Imaginez que votre mémoire est un tableau avec l'adresse de la variable (on verra ce que c'est plus tard avec les pointeurs)
et la valeur de la variable, celle que vous lui donnerais, ce tableau a une limite, elle varie suivant les configurations de votre
ordinateur, c'est-À -dire la RAM (ou mémoire vive). A chaque déclaration de variable, votre système d'exploitation lui
attribuera une place dans la RAM.
Pas d'inquiétude, j' explique. Pour schématiser ce qu'est une variable nous allons nous baser sur un petit programme traitant
d'une variable. Recopiez le code ci-dessous :
Code c:
#include <stdio.h>
#include <stdlib.h>
int main ()
{
long ageUtilisateur;
return 0;
}
Donc déjà on remarque encore une fonction "main" à l'intérieur de laquelle on peut voir deux instructions. Jusque là vous
devez suivre ... Enfin j'espère sinon retournez lire la fin du chapitre précédent.
Etudions l'instruction :
Code c:
long ageUtilisateur;
Ici la variable est "ageUtilisateur", ageUtilisateur est son nom, son type est "long" nous détaillerons les types de variables
après.
Cette instruction est ce que l'on appel une déclaration de variable.
Là ça se complique, mais pas de soucis j'explique.
Chose importante : les noms de variables sont souvent source d'erreur. Leur nom ne peut être composé que de caractères
alphanumériques (a - A, b - B, ..., 8,9) et du caractère de soulignement " _ " la touche 8 de votre clavier. On ne doit en
aucun cas utiliser des espaces et d'autres caractères du genre : " ? ", " ; ", ...
De plus le nom ne doit pas commencer par un chiffre. Enfin préférez utiliser des noms compréhensibles ( par exemple :
vieMonstre vaut mieux que : vM )
Ainsi :
On remarque aussi dans ce code que la valeur de cette variable n'est pas visible. En fait la valeur que la variable contient est
quelquonque. (==> c.f annexe mémoire)
Code c:
printf("ageUtilisateur vaut %ld", ageUtilisateur);
Vous verrez sans doute un nombre qui ne peut pas représenter un age humain.
Dans cette case de mémoire il y avait déjà un nombre utilisé précédemment par un autre programme. Rappelez vous le
paragraphe sur la mémoire.
On peut remarquer "%ld" dans ce code, en fait il désigne la variables ageUtilisateur que l'on rajoute après les guillets. En gros
que se passe t'il ? Et bien lors de la compilation, le compilateur remplace "%ld" par la valeur contenue dans la variables
ageUtilisateur.
Dans ce programme aucune valeur n'est spécifiée et on l'a vu cela amène à des nombres improbables. C'est pour cela qu'il
faut initialiser les variables que l'on utilise, en les mettant à zero si on ne connait pas à l'avance leur valeur, et si on les
connait on initialise les variables à ces valeur .
UNE VARIABLE NE PEUT CONTENIR QU'UNE SEUL VALEUR !!!!
Si on a plusieurs valeurs a déclaré, on initialise autant de variable qu'il y a de valeur.
Code c:
#include <stdio.h>
#include <stdlib.h>
int main ()
{
long ageUtilisateur = 0;
printf("ageUtilisateur vaut %ld", ageUtilisateur);
return 0;
}
Compiler le programme. Il affiche 0, tant mieux; il affiche erreur ou autre chose, vérififiez vos " ; " et si il le faut faites un
copier coller du code ci-dessus.
Remplacer maintenant le zero par une autre valeur, entière ( pas de virgule ) et ne dépassant pas 2 milliards ( nous verrons
pourquoi plus tard ). Si vous compilez vous devez voir apparaitre la valeur que vous avez entré ... Magique ...
Code c:
const long ageUtilisateur = 0;
Les types
Nous avons vu qu'à chaque variable est associé un type. Toutes les données que vous utiliserez dans vos programmes vont
suivre cette typologie. Nous verrons ici une partie (et la plus simple) des différents types existants.
- les entiers
- les nombres a virgules flottantes
Les Entiers :
La plage de valeur d'un type dépend du nombre de combinaisons de nombres que l'on peut former sur le nombre d'octet
qu'utilise le type. Par exemple pour le type int :
Il stock sur deux octets donc 16 bits :
16 x 16 + 16 x 16 = 256 x 256 = 65 536 combinaisons possibles qu'on sépare en deux un coté allant aux nombres négatifs et un
autre aux positifs. Si vous n'avez absolument rien compris de ces deux paragraphes et du calcul ne vous inquiétez pas, il s'agit
là non plus de C mais de binaire ( donc pas au programme :p ).
float : il stock les nombres sur quatre octets, il permet de gérer des nombres allant de 3,4 x 10 puissance -38 à 3,4 x 10
puissance 38. Le type float nous sera utile pour gérer les nombres à virgule.
double : il stock les nombres sur huit octects, il permet de gérer des nombres allant de 1,7 x 10 puissance -308 à 1,7 x
10 puissance 308.
La plage des nombres des types de données à virgule flottante est beaucoup plus complexe que pour les types de nombres
entiers. C'est pour cela qu'il ne vaut mieux pas en parler.
Mise en pratique
Maintenant que vous savez créer et afficher une variables nous allons pouvoir commencer à coder nos petits programmes. Et
pour commencer le classique : " Quel âge as-tu ? "
Ce programme demandera l'âge de l'utilisateur, stockera la valeur rentrée par l'utilisateur dans une variable et réaffichera
cette âge dans un printf.
Mais il va nous falloir récupérer la saisie de l'utilisateur. Pour cela nous allons utiliser " scanf ".
scanf marque une pause dans le programme, le temps que l'utilisateur rentre sa donnée. Puis après qu'il est appuyé sur
entrée, cette valeur va être stockée dans une variable.
Syntaxe de scanf :
Code c:
scanf ("%ld", &nomDeLaVariable );
Détaillons :
%ld représente le nombre qui va être saisie. ld car il s'agit d'une variable de type long. Chaque type à un % ** spécifique. Par
exemple si notre variable aurait été du type double on aurait mis %lf.
Il est inutile à ce stade de vous faire la liste de ces % ** nous y reviendrons en temps voulu.
Ensuite on peut voir &nomDeLaVariable. En fait ça signifie que la valeur saisie va être stockée dans cette variable.
Code c:
#include <stdio.h>
#include <stdlib.h>
Mais on doit impérativement les retrouver dans les deux premières lignes de vos programmes. Elles sont essentiels au bon
déroulement du programme. Leur signification et leur rôle étant un peu complexe nous verrons cela par la suite.
A vous de jouer
...
Code c:
int main ()
{
/* On initialise la variable à zéro */
long ageUtilisateur = 0;
/* On demande l'âge à l'utilisateur */
printf("Quel âge avez vous ? ");
/*L'utlisateur rentre son âge */
scanf("%ld", &ageUtilisateur);
/*et le programme l'affiche */
printf("Vous avez %ld ans", ageUtilisateur);
return 0;
}
Dans beaucoup de programmes C, il y a, à un moment ou un autre, besoin d'effectuer des calculs plus ou moins importants.
C'est pour cela qu'il me semble nécessaire que nous apprenions a faire des maths depuis notre programme. Nous ne ferons
pas de la grosse trigonométrie, pour le moment nous nous en tiendrons à ce que vous avez appris en CP/CE1 ...
Expressions
2 + 3
ageUtilisateur
Voila deux expressions. Fondamentalement toutes représentations de valeur en C est une expression La variable
ageUtilisateur ( pour reprendre l'exemple du dessus ) représente bien une valeur : cette valeur sera sans doute un âge.
Quand à 2 + 3, elle représente aussi une valeur ( 5 [besoin d'expliquer pourquoi ... 2 + 3 ... ]).
Code c:
int main ()
{
printf(" 2 + 3 = %ld", 2 + 3);
return 0;
}
On suppose ici que le résultat est de type long ( le %ld rappelez vous ).
Code console:
2+3=5
Les additions
Vous savez tous, enfin j'espère, comment fonctionne une addition. Et bien en C, c'est pareil.
On additionne deux nombres, deux variables, grâce à l'opérateur arithmétique " + ". Et de la même manière qu'au dessus on
affiche le résultat dans un printf.
Comme un bon code vaut mieux qu'un long discours, voici un code dans lequel on trouve en premier :
- une variable dont la valeur est le résultat d'une addition toute simple
- une autre variable dont la valeur vaut celle de la précédente à laquelle on ajoute deux.
- une variable dont la valeur vaut la somme des valeurs des deux variables précédentes.
Code c:
int main ()
{
long chiffre = 1 + 1;
long chiffre2 = chiffre + 2;
long chiffre3 = chiffre + chiffre2;
printf ("Chiffre vaut : %ld, chiffre2 vaut : %ld et l addition des deux
vaut : %ld", chiffre, chiffre2, chiffre3);
return 0;
}
Attention il est important d'initialiser en premier " chiffre ", puis " chiffre2 " et enfin " chiffre3 " sinon le compilateur plante
... Je tenais à vous faire écrire ce code pour vous faire part de cette erreur assez répandue chez les débutants en C.
On peut aussi faire une addition de variables directement dans le printf. Mais j'avoue ça devient illisible quand on utilise trop
de valeur. Il vaut donc mieux faire le calcul en dehors du printf.
Un petit code pour montrer ça :
Code c:
int main ()
{
long chiffre = 1 + 1;
long chiffre2 = chiffre + 2;
printf ("L addition vaut %ld", chiffre + chiffre2);
return 0;
}
Tiens ...
Maintenant que nous savons additionner pourquoi ne pas créer une petite calculette ?
Voila comment on va se dérouler le programme
- On demande deux nombres entiers à l'utilisateur.
- On les stocke dans deux variables
- On additionne ces variables et on stocke le résultat dans une troisième variable
- On affiche le résultat
Voici la solution :
Code c:
int main ()
{
long premierNombre = 0;
long deuxiemeNombre = 0;
long resultat = 0;
Code console:
Resultat : 77
Les soustractions
Et bien il s'agit exactement du même principe que l'addition si ce n'est qu'on utilise l'opérateur " - " et que le programme
réalise une soustraction ... Que dire d'autre ? Rien ... Un petit code quand même pour illustrer :
Code c:
int main ()
{
long chiffre = 2;
long chiffre2 = 3;
long chiffre3 = chiffre - chiffre2;
long chiffre4 = 10 - 8;
Code console:
Les multiplications
Toujours le même principe que l'addition, sauf que l'opérateur n'est pas " x " mais " * ". Et bien entendu il s'effectue non plus
une addition mais une multiplication. Le code fournie avec le produit
( jeu de mot ... ... Oula ! il est tard dis donc ).
Code c:
int main ()
{
long chiffre = 2;
long chiffre2 = 4;
long chiffre3 = chiffre * chiffre2;
long chiffre4 = 10 * 0;
Code console:
Toujours le même principe que l'addition sauf que l'opérateur de le division est " / " et celui du modulo est " % ".
Et bien la division est un peu complexe, en effet on ne prend pas en compte la possible virgule, ce qui fait que le résultat
d'une division telle que 2 / 4 ne sera pas égale à 0.5 ( tout le monde avait trouvé hein ? ) mais à 0 ! C'est un petit peu le
principe des divisions à reste. On ne s'occupe que du quotient et pas du reste.
Le modulo quand à lui s'occupe du reste. Si vous tapez dans un programme 2 % 4 alors le résultat sera égale au reste ( 2 ).
Code c:
int main ()
{
long chiffre = 2 % 4;
long chiffre2 = 2 / 4;
printf("chiffre vaut : %ld, chiffre2 vaut %ld.", chiffre, chiffre2);
return 0;
}
Code console:
Le résultat étant automatiquement un nombre entier, on a pas besoin d'un type de variable qui gère les nombres à virgule
(double, ...). En revanche si vous vouliez gérer les virgules, il ne faudrait non plus utliser un long mais un float ou un
double
Dans le prochain chapitre nous parlerons des conditions, points essentiel en programmation.
Si je vous dis :
Vous vous êtes surement rendu compte que la condition ici était :
" si la table est ramassée "
Et la conséquence est :
" tu iras voir tes amis "
Et bien ça marche exactement pareil. On a des conditions, et si elles sont vraies alors le programme exécute l'(es)
instruction(s) rattaché(s) à cette condition.
Nous allons voir cela en détail, mais avant il est important pour vous que vous connaissiez quelques opérateurs essentiels au
fonctionnement des conditions.
||ou
&&et
!non
Les booléens
A savoir : le terme booléen vient du nom du mathématicien et logicien anglais George Boole ( 1815 - 1864 ) qui développa ce
qu'on appel, en son honneur : l'algèbre de Boole.
- Une expression est logiquement fausse ( FALSE ), lorsque sa valeur numérique est 0.
- Une expression est logiquement vrai (TRUE ), lorsque sa valeur numérique est différente de 0.
Toute expression en C peut donc être testée sur sa valeur logique et sur sa valeur numérique. L'expression :
Code console:
2+1
à la valeur numérique 3 et est logiquement vrai car sa valeur diffère de 0. En revanche les expressions :
Code console:
0 x = 05 - 5 y * 0
ont toutes la valeur numérique 0. De ce fait, elles sont fausses et possèdent la valeur logique FALSE.
Les opérateurs de comparaisons vérifient l'existence d'une certaine relation entre les valeurs qui lui sont associés ( =
opérandes ). Le résultat de cette vérification est une de deux valeurs : 0, si la condition est logiquement fausse et 1 si en
revanche elle est vraie.
x == y
si x est réellement égal à y alors l'expression x == y vaut TRUE. L'opérateur de compraison, dans ce cas, donne la valeur 1 à
cette expression.
Si x n'était pas égal à y ( si x = 4 et y = 10 par exemple ) alors l'opérateur de comparaison donnerait la valeur 0 à cette
expression car elle est logiquement fausse.
Code c:
long x;
et l'affectation :
Code c:
x = ( 5 == 10 );
Résumé :
0 alors la relation à vérifier n'existe pas, l'opérateur de comparaison ayant donc le résultat logique FALSE.
1 alors la relation existe, l'opérateur de comparaison ayant donc le résultat logique TRUE.
Code c:
int main()
{
long x = 0, y = 0;
printf("Ce programme compare la valeur de 2 nombres.\n");
printf("Entrez deux entiers : \n");
printf("x = ");
scanf ("%ld", &x);
printf("y = ");
scanf("%ld", &y);
return 0;
Code console:
x=y?0
x different de y ? 1
x plus petit que y ? 0
x plus grand que y ? 1
If
L'avantage d'une condition est qu'elle permet de ne pas réaliser systématiquement toutes les instructions mais seulement
dans certains cas prévus par le programmeur. Dans ce contexte nous allons commencer par étudier l'instruction If.
L'instruction de test ou instruction If ( if = si en anglais ) permet de ne faire exécuter certaines instructions que dans le cas
où une condition est remplie. Voici la syntaxe de If :
If simple :
La valeur entre parenthèse représente la condition du If. C'est d'elle que dépend ou non l'éxécution de l'instruction qui suit.
Si la valeur de la condition est supérieur à zéro alors l' instruction qui lui est associée sera éxécutée. En revanche si la valeur
est nulle ( = 0 ) alors l'instruction ne sera pas éxécutée.
Code c:
int main ()
{
long x = 5;
long y = 3;
/* si x est supérieur à y */
if ( x > y)
printf("X est superieur a Y");
return 0;
}
On initialise deux variables x et y. On remarque que x et bien supérieur à y. On fait ensuite appel à un test if : si la variable x
et supérieur à la variable y alors affiche " X est supérieur à Y ".
Ici la variable x est belle et bien supérieur à y donc le message s'affichera. Mais maintenant si vous remplacez la valeur de la
variable x par 2, le message ne s'affichera plus car la condition sera fausse.
Code c:
int main ()
{
long x = 2;
long y = 3;
return 0;
}
On remarque l'opérateur de négation " ! ". En gros que signifie cette condition ?
Et bien vu qu'on a " ! ", on pourrait traduire cela par :
Le " ! " sert à insérer une négation dans notre condition. Cela peut s'avérer très utile ...
if complexe :
Jusqu'ici on a vu comment réaliser une instruction à partir d'une condition. Mais imaginez qu'on veuillent réaliser plusieurs
instructions à partir de cette condition. Et bien il faudra rassembler ces conditions dans un block. En effet pour l'expression
suivante :
Code c:
if ( variable == 4 )
printf("variable = 4\n");
printf("instruction de la condition");
L'instruction :
Code c:
printf("variable = 4\n");
Code c:
printf("instruction suivant celle de la condition");
Code c:
printf("instruction suivant celle de la condition");
s'affiche seulement si la condition est vraie voila la syntaxe à respecter :
Code c:
if (variable == 4)
{
printf("variable == 4\n");
printf("instruction suivant celle de la condition");
}
Comme dit plus haut, on regroupe toutes les instructions a réaliser en fonction de la valeur de la condition dans un seul et
même block. Voila à quoi pourrait ressembler ce programme :
Code c:
int main ()
{
long variable = 4;
if (variable == 4)
{
printf("variable = 4\n");
printf("instruction suivant celle de la condition");
}
return 0;
}
If / else
Nous avons vu comment réaliser une instruction en fonction de sa valeur logique maintenant voyons comment permettre une
alternative à nos programmes. Pour cela nous allons nous baser sur un code qui demande l'âge de l'utilisateur. Si il a plus de
18 ans alors on affichera : vous êtes majeur. Sinon on afichera : vous êtes mineur.
Pour réaliser ce code il va nous falloir voir l'instruction "else" ( = sinon en anglais ). Voici sa syntaxe :
else
{
<instructions>
}
Plus simple que le if car il n'y a pas d'expression à vérifier. Et oui "else" pourrait se traduire en C par :
A noter qu'à partir de maintenant toutes les instructions de nos conditions seront à mettre entre crochet. je vous demande
de le faire afin d'éviter les erreurs.
Demande l'âge
si l'âge est supérieur ou égal à 18 alors affiche " Vous êtes majeur "
sinon affiche " Tu es mineur "
Et maintenant à vous de jouer, réaliser ce programme, et vérifier votre code avec la solution qui suit :
Code c:
int main ()
{
long age = 0;
else
{
printf("Tu es mineur");
}
return 0;
}
Code console:
Simple, non ?
Else If
En français else if se traduit par Sinon Si et bien en C, c'est pareil. Si la condition vaut cette valeur alors réalise ses
instructions sinon si la condition vaut cette autre valeur réalise ses instructions, sinon fait cela.
Voila un code pour éclaircir les choses ( il doit vous rappelez des choses ... ) :
Code c:
int main ()
{
long age = 0;
if (age < 18 )
{
printf("Tu es mineur");
}
else if ( age == 18 )
{
printf("Tu es tout juste majeur");
}
else
{
printf("Tu dois etre tres age ");
return 0;
}
switch, l'alternative
On vient de voir à l'instant que le test Else If nous permet d'étendre à volonté le nombre de choix. L'inconvénient de ce test
se fait ressentir lorsque son apparition se fait trop régulière. De plus le manque de place pour une indentation conforme de
diverses alternatives peut très vite rendre le code source illisible.
En fait, il existe une instruction spécifique pour le cas où il faudrait choisir plusieurs alternatives. Cette instruction se
nomme " switch " et voici sa syntaxe :
L'instruction switch doit toujours être suivie d'une expression de type entiere mise entre parenthèse. En général on y met le
nom d'une variable. Le bloc qui suit contient un nombre quelconque de branches case. Chacune de ces branches se compose
du mot clé case, et d'une valeur constante obligatoirement différente des autres, suivi ensuite du symbole " : ". Après le " : "
on retrouve les instructions à exécuter si la valeur de l'expression située après le switch concorde avec une des constantes
placés après le mot clé case.
Après cela on remarque le mot clé break. Il sert à sortir du switch afin d'éviter que le programme effectue toutes les autres
instructions qui le suivent.
Enfin on peut voir défault, il sert uniquement si aucunes valeurs ne corresponds aux valeurs des constantes suivant les case.
Code c:
int main ()
{
long nombre = 0;
printf("1, 2, 3 ou 4 ? : ");
scanf("%ld", &nombre);
switch (nombre)
{
case 1 :
printf("Vous avez tape 1\n");
break;
case 2 :
printf("Vous avez tape 2\n");
break;
case 3 :
printf("Vous avez tape 3\n");
break;
case 4 :
printf("Vous avez tape 4\n");
break;
default :
printf("Vous devez rentre 1,2,3 ou 4 !");
break;
}
return 0;
}
Voila ...
Entrainez vous à réaliser de petits programmes utilisant des conditions, en effet les conditions sont souvent utilisées dans les
programmes. Il faut savoir les manipuler ...
Les boucles, dans un programme, permettent de répéter certaines instructions plusieurs fois sans avoir à recoder plusieurs
fois ces instructions. En C il existe trois types de boucles, nous parlerons de chacune d'elle. Les voici :
for
while
do / while
La boucle for
La boucle for teste une condition avant d'exécuter les instructions qui lui sont associées. Voilà sa synthaxe :
Code c:
for (expression1 ; expression2 ; expression3)
{
instructions à réaliser
}
expression1 sera une initialisation d'une variable dit de contrôle qui servira lors du test de condition de réalisation des
instructions de la boucle.
Voyons maintenant son fonctionnement à travers un programme qui se chargera d'afficher 3 fois le terme "Hello world!"
Code c:
int main()
{
int i = 0; /* voilà notre variable de contrôle */
return 0;
}
Hello World!
Hello World!
Hello World!
Code c:
for (i = 0 ; i < 3 ; i++)
i = 0 : On commence par initialiser notre variable de contrôle à 0 ( ne pas oublier de la déclarer avant dans le
programme )
i < 3 : C'est la condition pour que la boucle s'exécute, tant que i sera inférieur 3 les instructions à l'intérieur de la boucle
continuerons de s'exécuter
i++ : (équivalent à i + 1 [dorénavant préférer le ++ plutôt que le + 1 sur une variable ou le -- plutôt que le - 1]) Cette
expression signifie qu'on ajoutera 1 à la variable i à chaque passage de boucle.
Commence avec i = 0 ;
Faire tant que i < 3 ;
Rajoute 1 à chaque passage de la boucle ;
Il n'y a pas de ";" a la fin du for c'est une erreur assez répandu chez ceux qui débute donc faites y attention
La boucle while
La boucle while, tout comme la boucle for ne permet l'exécution d'instructions que si une condition vérifiée, avant
l'exécution des instructions, est vrai (TRUE). Voici sa synthaxe :
Code c:
while ( condition )
{
instructions(s)
}
voyons son fonctionnement à travers le même programme que tout à l'heure à savoir : afficher trois fois le message "Hello
World !"
Code c:
int main()
{
int i = 0;
while ( i < 3 )
{
printf("Hello World !\n");
i++;
}
return 0;
}
Détaillions :
On commence comme d'habitude par initialiser notre variable de contrôle (i). Ensuite on rentre dans la boucle car la
condition est vérifiée ( i vaut 0 donc est bien < à 3 ) Puis on affiche le fameux hello world!. On ajoute 1 à la variable i. Le
programme retourne au début, recommence à exécuté les instructions car àa ce moment i vaut 1 ... et ainsi de suite jusqu'à
ce que i soit égal à 3 lors du test de condition, ce qui fera quitter la boucle au programme.
La boucle do / while
La boucle do / while diffère des autres dans le sens où les instructions qui lui sont rattachées s'exécutent au moins une fois.
Cela étant du à sa synthaxe :
Code c:
do
{
instruction(s) à réaliser
}while (condition);
Comme vous pouvez le voir la condition pour que la boucle se réalise se situe à la fin de la boucle. Or comme vous le savez
déjà peu être, votre ordinateur lit le programme de bas en haut ce qui fait que les instructions d'une boucle do / while
s'exécute au moins une fois
Utiliser des boucles dans un programme c'est bien, mais si on ne fait pas attention à ce que l'on écrit on peut vite arriver à ce
que l'on appel une boucle infinie, c'est à dire une boucle dont la condition est toujours vrai, donc qui ne s'arrêtera jamais et
bloquera votre programme. Heureusement les systèmes d'exploitation actuel savent faire face à ce genre de problème et
vous n'aurez pas de mal à arrêter votre programme.
Code c:
while (1)
{
printf("Boucle infinie !");
}
do
{
printf("Boucle infinie !");
}while (4 < 5);
Conclusion
Voilà vous savez maintenant comment faire une boucle dans un programme C.
Pourquoi ne pas vous entrainer en créant un petit programme qui fera autant de tour que l'utilisateur voudra ? et qui
affichera le nombre de tours effectués ?
Code console:
Sortie de la boucle...
Ou vous pouvez tout aussi bien tenter de créer une calculette multi-fonctions ou encore des petits programmes de révisions
des dates historiques par exemple.
Dans le prochain chapitre nous parlerons des fonctions, éléments majeurs dans la programmation.
Jusque là nous n'avons vu qu'une fonction dans nos programmes. Il s'agissait de la fonction main présente dans TOUT les
programmes C et qui est toujours exécutée en première. Cependant, depuis le début, tout nos programme ne font que
quelques dizaines de lignes et donc on pouvait écrire, sans problème majeur, l'intégralité de notre programme dans la
fonction main. Mais il faut savoir qu'en C, il est fortement déconseillé de faire cela, c'est pourquoi il existe la possibilité de
créer des fonctions.
Le but principal d'une fonction est de retourner 1 résultat. Après avoir exécutée plusieurs instructions qui lui sont associées.
Par exemple une fonction peut s'occuper de renvoyer différence de deux nombres, ...
Pour qu'une fonction puisse s'exécuter convenablement il faut qu'elle reçoive, ce que l'on appel des arguments (ou
paramètres).
Une fois ces paramètres reçues la fonction s'exécute et renvoie un résultat final.
Les fonctions nous serviront donc pour ne pas surcharger notre fonction main et donc garder le maximum de lisibilité pour
repérer d'éventuels bugs ou erreurs (et oui ça arrive )
Au fait savez vous que vous avez déjà fait appel à des fonctions sans le savoir dans votre code ?
Hein ?
Oui, lorsque vous utilisez printf et bien c'est une fonction à laquelle on envoyait des arguments pour la faire fonctionner, on
appel cela un appel de fonction, cependant le fonctionnement de printf étant un peu compliqué pour les novices que nous
sommes, nous n'allons pas nous attarder dessus, sachez juste que pour utiliser une fonction on l"appel" dans le programme et
que tout programme C comporte au moins 1 fonction : la fonction main.
Nous allons maintenant apprendre à créer nos propres fonctions et à les utiliser dans nos programmes.
Code c:
type nom(parametres)
{
/* ... */
}
Le type de la fonction : C'est en fait le type de nombre que renverra la fonction à la fin de son exécution (int, long,
float, double, ...)
Son nom : pour pouvoir l'appeler dans un programme il faut au préalable lui avoir donner un nom par exemple : addition
Les paramètres : ce sont par exemple les nombres que vous allez envoyer à la fonction , elles peut avoir un nombre
quelconque de paramètres. Il 'écrire le type des paramètres lorsqu'on créer une fonction.
Je vous ai dit tout à l'heure que le but principal d'une fonction était de retourner une valeur. Et bien on fait cela dans une
fonction à l'aide du mot-clé return situé la plupart du temps à la fin des instructions nécessaires pour l'envoie de la valeur
voulue par l'utilisateur. En gros lorsqu'on fait un appel de fonction , on demande à cette fonction de nous renvoyer une
valeur à l'aide des paramètres qu'on lui envoie et elle rnous les renvoie à l'aide de return
Enfin sachez une fonction doit se trouver en dehors du bloc main et tout comme dans notre fonction main les instructions à
l'intérieur d'une fonction doivent impérativement se trouver entre accolades! Il faut également créer sa fonction avant
le main car si vous la créez après le compilateur peu ne pas "savoir" à quelle fonction vous faites références lorsque vous
l'appelez dans le main (ou ailleurs). Voici donc à quoi peut ressembler une fonction :
Code c:
#include <stdlib.h>
#include <stdio.h>
int fonction(int parametre1 , int parametre2) /* N'oubliez pas les types des
paramètres ;) */
{
/* ...*/
return resultat
}
int main ()
{
/* code du main */
fonction(parametre1, parametre2);
/* appel de la fonction à laquelle on envoie les paramètres nécessaires au bon
fonctionnement de notre fonction, ici : parametre1 et parametre2 */
/*Code du main */
Voilà maintenant que vous savez créer des fonctions, nous allons donc faire un petit exemple pour nous entrainer.
Imaginons que dans votre programme C vous souhaitez créer une fonction qui additionne deux nombres que vous envoyez en
tant que paramètres. Voici donc comment vous devrez procéder :
Code c:
int fonction (int nombre1, int nombre2)
{
return nombre1 + nombre2;
}
int main()
{
int nombre1 = 1;
int nombre2 = 2;
int resultat = 0;
return 0;
}
Code console:
1+2=3
Le cas void
Il est possible en C de créer des fonctions sans paramètres ou ne renvoyant aucune valeur. Pour cela on utilise un type prévu
à cette effet : void
On utilise ce type pour des fonctions censées affichées uniquement des messages par exemple.
Code c:
void afficherBonjour(void) /* pas de paramètres donc void */
{
printf("Bonjour !\n");
}
int main ()
{
afficherBonjour();
return 0;
}
Code console:
Bonjour !
Remarque : pour gagner du temps on peut ne pas mettre void dans la parenthèses d'envoie des paramètres et donc avoir
afficherBonjour() au lieu de afficherBonjour(void). En revanche n'oubliez pas de le mettre lorsque vous précisez le type de
votre fonction
Vous pouvez aussi avoir une fonction de type int par exemple mais ne prenant aucun paramètres.
Exemple :
Code c:
int maFonction () /* pas de paramètres ici */
{
return 3;
}
Cette fonction renverra bien un int mais on ne lui envoie pas de paramètres lorsqu'on l'appel.
Tout à l'heure je vous ai dit de placer vos fonctions avant le bloc main. Pour certains cette solution va vite devenir pénible.
Si vous souhaitez placer vos fonctions après le main, il va falloir placer ce qu'on appel, un prototype de fonction en début de
code pour signaler au compilateur que votre fonction est bien dans le programme. Pour cela rien de plus simple, il vous suffit
de reprendre, à la lettre près, la déclaration de votre fonction et d'y ajouter un point-virgule.
exemple :
Code c:
int maFonction ();
Quand on est débutant on fait très souvent des erreurs avec les types de fonctions, ainsi on envoie comme paramètres des
variables de type double mais votre fonction est de type int, donc le résultat que vous recevez est sans virgule. Il alors vous
essayer de renvoier une variable de type long, par exemple, dans une fonction de type void (qui n'est censé ne rien renvoyé !
[pas de return machin donc !])
Au début tout ça est assez compliqué mais vous verrez que les fonctions sont essentiels dans un programme !
Entrainez vous et si vous avez des questions n'hésitez pas à les poser sur le forum
Dans le prochain chapitre nous attaquerons un point sensible en C, les pointeurs. Il est nécessaire d'être au point avec les
fonctions avant d'attaquer ce chapitre car à partir de maintenant l'essentiel de nos programmes en comportera !
Chapitre 7: Les pointeurs - Langage C
Pointeur, ce mot, qui parait pourtant inofensif, a fait trembler des générations de cerveaux de programmeurs.
En effet, le problème avec les pointeurs c'est que leur fonctionnement est assez difficile a assimilé pour les débutant, mais
qu'il reste la clé de nombreux programmes. Le systèmes d'exploitation que vous utiliser actuellement en est constitué !
Concrètement, un pointeur est une variable contenant l'adresse d'une autre variable stockée en mémoire
Dis comme cela c'est un peu barbare et ça doit surtout vous embrouillez, c'est pourquoi avant de détaillé ma définition du
pointeur , il me semble important que vous soyez au clair avec le fonctionnement de la mémoire vive.
Si ce n'est pas le cas je vous invite à allez lire mon tutoriel sur la mémoire d'un ordinateur, sans quoi la compréhension de la
suite du tutoriel va s'avérer très compliquée
Code c:
int maVariable = 10;
Vous savez donc que la valeur "10" est stockée dans une "case" de la mémoire et qu'on peut y accéder facilement en
l'identifiant dans le programme par son nom. Le problème c'est que ceci ne marche que dans la fonction dans laquelle est
déclarer la variable. Ainsi le programme :
Code c:
#include <stdio.h>
#include <stdlib.h>
void maFonction();
int main()
{
int maVariable = 10;
void maFonction()
{
printf("Valeur de maVariable dans maFonction : %d", maVariable);
}
Nous donnes une belle erreur de compilation en nous indiquant que la variable maVariable n'est pas déclarée dans le fonction
maFonction. Car en fait la "portée" d'une variable ne se situe que dans la fonction où celle ci est déclarée, ainsi maVariable
étant déclarée dans la fonction main on ne peut avoir accès à la valeur qui lui est associé que dans la fonction main.
On ne peut donc pas modifier directement la valeur d'une variable depuis une autre fonction que celle de sa
déclaration
Code c:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int maVariable = 10;
Code console:
Valeur de maVariable : 10
Valeur de maVariable dans maFonction : 16
Valeur de maVariable apres le passage dans maFonction : 10
Les pointeurs vont donc nous servir à faire face à ce problème. En effet nous allons en fait créer une variable contenant
comme valeur l'adresse d'une autre variable. Ainsi imaginons que nous ayons une variable contenant la valeur 25 et stockée à
l'adresse 5000. Et bien nous allons créer une autre variable, appelé pointeur, qui contiendra comme valeur l'adresse de la
première variable et stockée à l'adresse 4130, ce qui schématiquement donne :
Enfait un pointeur n'est donc rien de plus qu'une variable contenant EXCLUSIVEMENT l'adresse d'une autre variable.
Cependant il nous faudra utiliser une synthaxe spécial.
Voyons donc comment créer un pointeur et l'utiliser dans un programme.
Pour créer un pointeur, on utilise le symbole de l'astérisque devant le nom du pointeur( " * "). En revanche son initialisation
ne se fait pas en lui donnant la valeur zéro, mais plutôt avec le mot-clé NULL, ce qui nous donne :
Code c:
int *monPointeur = NULL;
Il va maintenant falloir lui envoyer en valeur l'adresse d'une variable. Voilà comment on va procédé :
Code c:
int main()
{
int *monPointeur = NULL;
int maVariable = 10;
monPointeur = &maVariable;
/* Suite du code */
On envoie donc l'adresse de maVariable grâce au signe "&" devant son nom. En fait ce "&" permet de signaler au sytème
d'exploitation que l'on utilise, non pas la valeur de la variable maVariable, mais son adresse en mémoire. Vous vous rappelez
sans doute de cette synthaxe qu'on retrouvait dans la fonction scanf
Maintenant que le pointeur monPointeur contient l'adresse de la maVariable nous pouvons en faire, ce que l'on veux .
Voyons déjà comment afficher la valeur de la variable sur laquelle pointe notre pointeur :
Code c:
int main()
{
long maVariable = 10;
long *monPointeur = NULL;
monPointeur = &maVariable;
return 0;
}
Les commentaires parlent d'eux mêmes, il n'y a pas grand chose d'autre à rajouter.
Lorsqu'on débute, il est vrai qu'on ne trouve pas vraiment l'intérêt de se compliquer la vie avec des pointeurs alors que la
variable maVariable nous suffisait amplement pour nos manipulations. C'est une réaction légitime, mais le gros intérêt des
pointeurs c'est qu'ils vont nous permettre de modifier la valeur d'une variable depuis une autre fonction que celle dans
laquelle, elle était déclarée (ce qui était impossible auparavant ).
int main(void)
{
int maVariable = 10;
return 0;
}
Dans ce petit programme, la variable maVariable est donc initialisée à 10. On envoie ensuite son adresse (en tant que
paramètre) à la fonction maFonction. Le pointeur pointeur dans ma fonction reçoit donc l'adresse de maVariable. Ensuite il
modifie la valeur de celle ci pour la mettre à 5.
Code c:
void maFonction(int *pointeur);
int main(void)
{
int maVariable = 10;
int *monPointeur = &maVariable;
return 0;
}
Que se passe t'il concrètement ici ? Et bien on envoie non plus l'adresse de maVariable, mais un pointeur (ici monPointeur)
qui contient l'adresse de maVariable.
Rappelez vous pour avoir la valeur d'une variable dont l'adresse est contenu dans un pointeur, il suffisait de rajouter le
symbole de l'astérisque devant le nom de ce pointeur. Mais si on souhaite avoir l'adresse de cette variable, il suffit
simplement d'indiquer le nom de ce pointeur
pointeur reçoit donc comme valeur l'adresse de maVariable et peut donc modifier directement celle-ci en mémoire.
Vous savez maintenant comment fonctionne les pointeurs en C. Ils sont très utiles malgrés ce qu'on a pu voir dans ces petits
exemples. Je vous recommande bien vous entrainer en réécrivant de petit programme les utilisant. Tiens essayer donc
d'envoyer deux pointeurs à une fonction pour modifier la valeur de 2 variables . Si vous avez un quelconques
Dans le prochain chapitre nous verrons comment créer une table de données en C (appelés aussi tableau) et comment
l'utliser dans nos petits programmes
Il arrive en C qu'on est besoin, à un moment ou à un autre, de stocker des valeurs dans ce qu'on appel une table de donnée
(ou encore plus simplement : tableau). Le langage C permet cela voyons maintenant comment déclarer un tableau.
Les tableaux Statiques : ce sont des tableaux dont la taille est connue à la compilation
Les tableaux Dynamiques : ce sont des tableaux dont la taille n'est connue qu'à l'exécution.
Pour le moment nous ne verrons que les tableaux statiques, nous aborderons les tableaux dynamiques lorsque nous parlerons
de la gestion de la mémoire ou encore d'allocation dynamique.
Syntaxe :
Code c:
Type nomDuTableau[nombreDElements];
Exemple :
Code c:
int tableau[4];
On déclare ici un tableau de type int contenant 4 valeurs de type int. "[4]" représente le nombre de cases du tableau, on
aura donc ici un tableau de type int de 4 cases, ces cases étant remplies de données de type int uniquement .
De plus la taille du tableau doit être connue à la compilation, et on évitera par dessus tout de définir sa taille à partir d'une
variable. Ainsi :
Code c:
int variable = 4;
int tableau[variable];
Utiliser un tableau
Maintenant que notre tableau est créé, il va falloir le remplir de valeurs. Pour initialiser toutes les cases du tableau à 0 on
peut utiliser la méthode qui suit :
Code c:
int tableau[4] = {0};
Cependant, il se peut que dès la déclaration du tableau, on connaisse certaines valeurs, on peut donc remplir notre tableau
avec celle-ci.
Rappel : Toutes les valeurs du tableau sont du même type que le tableau ... (mieux vaut trop que pas assez )
Code c:
int tableau[4] = {2, 23, 25, 92};
Chaque case du tableau (ici 4) est donc initialisée à une valeur de type int donnée. Ici tableau[0] vaudra 2; tableau[1] vaudra
23; etc.
Il faut savoir que si on indique pas toutes les valeurs du tableau, alors les valeurs non définies prendrons la valeur 0.
Par exemple :
Code c:
int tableau[4] = {2};
Code c:
int tableau[] = {2, 23, 25, 92};
Vous voyez ici qu'on indique plus le nombres de cases du tableau, enfait le compilateur se chargera pour nous de calculer la
taille du tableau.
Maintenant que notre tableau est rempli, il peut être intéressant d'exploiter les valeurs qui lui sont rattachées.
il faut savoir que la première valeur se situe dans la case 0 du tableau et non dans la case 1. Ce qui peut porter à confusion
car on serait tenter de récupérer la valeur situer dans tableau[4] mais si on fait cela, on essaye de d'accéder à une case en
mémoire qui n'est pas accordée au tableau et très certainement pas non plus à notre programme (ce qui à le dont d'énerver
particulièrement votre OS qui vous le signalera par sa belle fenêtre d'erreur prévue à cet effet ), soyez vigilant donc
et n'oubliez pas que la dernière valeur de votre tableau se situe dans la case tailleTableau - 1 donc dans notre cas tableau[3]
Pour récupérer les valeurs d'un tableau, une boucle for peut faire l'affaire ainsi si on souhaite retrouver les valeurs du
tableau, on utilise la méthode suivante :
Code c:
for (i = 0; i < 4; i++) {
printf("Valeur contenu dans tableau[%d] = %d\n", i, tableau[i]);
/* A chaque tour de boucle on incrémente (= i + 1) notre variable i, ce qui fait
qu'on accédera à toute las cases du tableau, on arrête la boucle quand i est égal à
trois pour éviter d'accéder dans un bloc mémoire qui ne nous est pas réservé */
}
Code console:
Valeur de tableau[0] = 2
Valeur de tableau[1] = 23
Valeur de tableau[2] = 25
Valeur de tableau[3] = 92
Pour résumer ce paragraphe je vous propose de concevoir ensemble un programme qui calcul la moyenne de toutes les
valeurs de notre tableau.
Code c:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i = 0;
double tableau[4] = {2.0, 16.5, 58.56, 19.92};
/* On initialise notre tableau avec 4 valeurs de type double */
moyenne = sommeTotale / 4;
return 0;
}
Code console:
Pour envoyer un tableau à une fonction, il suffit simplement de lui envoyer son adresse à une variable du même type que
notre tableau. C'est aussi simple que ça
Code c:
#include <stdio.h>
#include <stdlib.h>
return 0;
}
Code console:
Tableau[0] = 2
Tableau[1] = 23
Tableau[2] = 25
Tableau[3] = 92
On suppose ici qu'on connait la taille du tableau car sinon il vous faudra aussi envoyer la taille de celui ci pour éviter les
erreurs
Faites attention donc à ce que la lecture et l'écriture des données d'un tableau soit dans les limites de celui-ci !
Code c:
void afficherTableau(int *tableau);
int main(void)
{
int tableau[4] = {2, 23, 25, 92};
afficherTableau(tableau);
return 0;
}
Vous voyez ici qu'on a simplement remplacer les crochet par une étoile symbolisant un pointeur, c'est autorisé car un tableau
est considéré comme un pointeur. Vous pouvez accéder aux éléments du tableau de la même manière en respectant les
limites de celui-ci.
Entrainez vous à réaliser de petits programmes envoyant des tableaux à des fonctions, c'est le meilleur moyen de
progresser
Les tableaux à deux dimensions
Pour le moment nous avons vu des tableaux à une seule dimension. Mais il est possible en C de créer des tableaux à deux
dimensions, aussi appeler matrice (toute référence à un film américain est à proscrire )
Ce style de tableaux est assez complexe et déroutants pour les débutants cependant leur utilité n'est plus à démontrer et il
est probable qu'un jour où l'autre vous en ayez besoin.
Avant de vous montrer la syntaxe d'un tableau à deux dimensions, il me semble essentiel d'en rappeler le principe.
Deux dimensions signifient qu'on a deux entrées dans notre tableau. Ainsi voilà à quoi ressemblerait un tableau de 2 cases sur
2 :
Ainsi la valeur 10 se trouve dans la colonne 1 à la ligne 1 et la valeur 15 dans la colonne 2 à la ligne 1.
En C, on commence d'abord par la colonne puis par la ligne, de plus la premières colonnes se situé aussi à la case 0 et non à
1, ainsi on dira la valeur 10 est dans la colonne 0 à la ligne 0.
Code c:
int tableau[2][2];
Maintenant nous allons initialisée notre tableau avec les valeurs ci-dessus, en commençant donc par remplir chaque colonne
une par une.
Code c:
int tableau[2][2] = {{10, 20}, {15, 35}};
On délimite ici chaque colonne par des accolades, ce n'est pas obligatoire mais ça permet de clairement voir ce que l'on fait
sans être embrouillé avec les différentes valeurs. On commence donc par la colonne 0 et on rempli chaque ligne de cette
colonne, dans l'ordre jusqu'à ce qu'elle soit pleine, ensuite on passe à la colonne suivante.
Voyons comment utiliser nos tableaux dans des fonctions.
Envoyer un tableau à deux dimensions à une fonction n'est pas très compliqué, puisqu'on utilise la même syntaxe que pour un
tableau à une dimension, si ce n'est qu'on rajoute bien évidemment la deuxième paire de crochets pour signaler qu'on
utilisera une matrice.
Contrairement à un tableau à une dimension, il faut écrire la taille de votre tableau à deux dimensions.
Code c:
#include <stdio.h>
#include <stdlib.h>
return 0;
}
void afficherTableau(int tableau[2][2])
{
/* ... */
}
Maintenant si on souhaite récupérer les valeurs du tableau (pour les afficher par exemple, deux boucles for suffisent :
Code c:
#include <stdio.h>
#include <stdlib.h>
En oubliant pas qu'on lis les valeurs colonnes par colonnes et non pas lignes par lignes ! Ici ce code nous affiche donc :
Code console:
Tableau[0][0] = 10
Tableau[0][1] = 20
Tableau[1][0] = 15
Tableau[1][1] = 35
Voilà vous savez l'essentiel à savoir sur les tableaux. Si vous avez la moindre question n'hésitez pas à la poser sur le forum.
Dans le prochain tutoriel nous verrons les types avancées du langage C : structures, typedef, unions et énumérations.
Le langage C nous permet de créer nos propres types de variables. Cela peut devenir essentiel lorsque l'on souhaite
programmer de gros programme par exemple. Nous verrons donc comment faire ceci.
Nous apprendrons tout d'abord à créer une structure et à l'utiliser dans nos programmes, puis nous ferons de même avec les
énumérations et les unions. Nous parlerons aussi de typedef
Une structure est en fait un regroupement de variables, de n'importe quels types, ainsi une structure peut contenir des
variables de type int, char, double, ...
Contrairement aux tableaux qui eux obligent aux éléments de ce tableau d'être tous du même type.
Sans plus attendre voyons comment créer une structure.
Tout d'abord il faut savoir qu'il est préférable de créer une structure en dehors d'une fonction car l'avantage des structures
c'est qu'elles permettent un accès à leurs attributs (= sous-variables qu'elles contiennent) qui s'étend sur toutes les fonctions
du programme.
Ainsi si vous créez une structure dans une fonction, seule celle-ci y'aura accès.
Code c:
struct MaStructure {
int var1;
long var2;
double varN;
};
On utilise le mot-clé struct suivi du nom que l'on souhaite donnée à notre structure (ici MaStructure [par convention, les
noms données aux structures commencent par une majuscule afin de ne pas les confondre avec une variable]), ensuite on
ouvre une accolade on remplie la structure des différentes sous-variables qu'on souhaite utilisées. Puis on referme l'accolade
et on n'oublie surtout pas de mettre un point-virgule !
Vous voyez ici qu'on créer une structure composée de 3 sous-variables de types différents.
Maintenant que notre structure est créer il va falloir qu'on initialise nos sous-variables.
Il va donc falloir qu'on initialise cette structure dans une fonction de notre programme. Dans le main par exemple.
Pour cela il va nous falloir créer une variable de type MaStructure, car oui, en fait MaStructure est un type de variable.
Pour créer cette variable, il nous suffira juste de faire comme si il ne s'agissait que d'une simple variable, à la différence
qu'on ajoute quand même le mot-clé struct pour bien signaler qu'on utilise une structure.
Voilà donc ce que ça nous donne :
Code c:
#include <stdio.h>
#include <stdlib.h>
struct MaStructure {
int var1;
long var2;
double varN;
};
int main()
{
struct MaStructure maStructure;
/* On a bien créer une variable de type MaStrcture se nommant maStrcture */
A noter qu'on peut assi déclarer des variables directement après la déclaration de la structure de cette manière :
Code c:
struct MaStructure {
int var1;
long var2;
double varN;
}var3;
On aura ici une variable globale, (= dont la portée s'étend à tout le programme) var3 de type MaStructure.
Cependant nos variables ne sont pas encore initialisées et leurs valeurs est donc aléatoires. Pour les mettre à 0, il suffit
simplement de faire comme ceci :
Code c:
struct MaStructure maStructure = {};
}
Pour en avoir le coeur net, nous allons voir comment accéder aux attributs d'une structure grâce à la variable maStructure
que nous avons créer juste avant suivi d'un point ("."), puis du nom de la variable contenue dans MaStructure à laquelle on
souhaite accéder. De cette manière ci :
Code c:
struct MaStructure {
int var1;
long var2;
double varN;
}var3;
int main()
{
struct MaStructure maStructure = {};
return EXIT_SUCCESS;
}
Code console:
0
0
0.000000
Maintenant si l'on souhaite définir les variables de MaStructure avec d'autres valeurs, il existe plusieurs manières :
Code c:
struct MaStructure maStructure = {10, 40000, 12.5};
avec cette méthode, on initialise les variables dans l'ordre. Si on en oublie (qu'on oublie le 12.5 de varN par exemple), les
variables non initialisées seront mises à 0.
Code c:
struct MaStructure maStructure;
maStructure.var1 = 10;
maStructure.var2 = 40000;
maStructure.varN = 12.5;
Ainsi toutes les variables seront bien définis, par contre si là encore on oublie de déclarer une variable elles ne seront pas
mises à zéro et auront une valeurs aléatoires. De plus si une des variables à déjà été définie alors sa valeur sera remplacée
par la nouvelle.
Il est aussi possible de créer, en langage C, des variables de types pointeurs vers structures. Pour cela rien de plus simple
puisse qu'on peut en créer un comme n'importe quel pointeur d'un tout autre type.
Code c:
struct MaStructure *maStructure = NULL;
On crée donc donc ici un pointeur maStructure" de type MaStructure, qu'on initialise a NULL pour éviter une erreur.
Le principal atout d'un pointeur de strcutures c'est qu'il va nous permettre de modifier les attributs de notre structures
depuis une autre fonction.
Ainsi pour envoyer notre structure dans une fonction, il va simplement falloir faire comme on le ferait avec un simple
pointeur :
Code c:
struct MaStructure {
int var1;
long var2;
double varN;
}var3;
int main()
{
struct MaStructure maStructure;
fonction(&maStructure);
/* On envoie l'adresse de maStrcture comme paramètre */
printf("%d\n", maStructure.var1);
printf("%ld\n", maStructure.var2);
printf("%lf\n", maStructure.varN);
return EXIT_SUCCESS;
}
Code c:
maStructure.var1 = 10;
Mais avec un pointeur ça ne marche plus comme ça (ç'aurait été trop beau )
Code c:
(*maStructure).var1 = 10;
Expliquons un peu tous ça. On utilise l'étoile pour bien montrer qu'on veut accéder à la variable et non à l'adresse contenue
dans le pointeur. Enfin on met des parenthèses autour de ce pointeur pour signaler au "." qu'il doit s'appliquer a *maStructure
et non pas à maStructure. C'est assez obscure je le reconnais mais c'est essentiel.
Cependant les développeurs avant vous on aussi remarqué que cette notation n'était pas très évidente c'est pourquoi ils ont
créé un symbole ( une flèche ->)qui permet de palier à ce problème, ainsi au lieu de faire :
Code c:
(*maStructure).var1 = 10;
Nous ferrons :
Code c:
maStructure->var1 = 10;
C'est à dire que lorsque nous aurons à faire à un pointeur, il suffira juste de remplacer le point par le symbole de la flèche.
Vous devriez donc maintenant être capable d'initialiser les attributs de notre structure :
Code c:
struct MaStructure {
int var1;
long var2;
double varN;
}var3;
int main()
{
struct MaStructure maStructure;
fonction(&maStructure);
/* On envoie l'adresse de maStrcture comme paramètre */
printf("%d\n", maStructure.var1);
printf("%ld\n", maStructure.var2);
printf("%lf\n", maStructure.varN);
return EXIT_SUCCESS;
}
Code console:
10
40000
12.500000
Dans la prochaine partie nous verrons le typedef, les énumérations et les unions.
Voici donc la suite de la première partie, nous verrosn ici à utiliser les typedef et à créer des énumérations.
typedef
En langage C, il est possible de créer des synonymes de types. Cela peut nous éviter d'avoir à recoder une partie de code
répétitive. On peut faire cela grâce au mot-clé typedef de cette manière ci :
Code c:
typedef Type SynonymeDuType;
En fait on crée ici un synonyme du type Type, les deux deviennent alors interchangeable. Ainsi si l'on souhaite créer un
synonyme du type int (sans gros intérêt certes mais c'est pour l'exemple ), et bien il faudrait faire comme cela :
Code c:
typedef int synonymeDeInt;
Code c:
synonymeDeInt variable = 10;
Code c:
int variable = 10;
Mais là ou le typedef devient intéressant c'est qu'il nous permet de créer un synonyme d'une structure, ce qui évite d'avoir
sans cesse à réécrire le mot clé struct.
Ainsi le code de la première partie deviendra :
Code c:
struct MaStructure {
int var1;
long var2;
double varN;
}var3;
typedef struct MaStructure MaStructure;
/* On créer notre synonyme */
int main()
{
MaStructure maStructure;
/* On utilise le synonyme donc plus besoin du mot-clé struct */
fonction(&maStructure);
printf("%d\n", maStructure.var1);
printf("%ld\n", maStructure.var2);
printf("%lf\n", maStructure.varN);
return EXIT_SUCCESS;
}
Il faut bien penser à créer le synonyme juste après la déclaration de la structure pour ne pas avoir à rajouter le mot
clé struct.
Voilà vous savez maintenant utiliser typedef pour créer des synonymes.
Les énumérations
Le langage C nous permet aussi de créer ce que l'on appel des énumérations. En fait il s'agit simplement de créer des
constantes qui prendront des valeurs définies (entières si on ne le précise pas). Ces valeurs pourront être ensuite utilisée
dans notre programme. Voici comment créer une énumération.
Code c:
enum nomDeLEnumeration {Constante1, Constante2, ConstanteN};
Ces constantes seront donc remplacées par des valeurs à la compilation. Si on ne précise pas ces valeurs alors la premières
constante prendra la valeur 0, la deuxième la valeur 1 et ainsi de suite.
Dans notre énumération Constante1 sera donc égal à 0, Constante2 = 1 et ConstanteN = N-1 (ici 2). Si l'on souhaite définir
nous-même les valeurs il suffit de l'indiquer à l'aide du signe égal.
Code c:
enum Plan {X, Y = 3, Z};
Ici X prendra la valeur 0 car on n'a pas spécifié de valeurs, Y prendra la valeur 3 et Z prendra la valeur 4 et non 1 ou 2. Car
une constante non-défini suivant une qui est définie dans une énumération prend comme valeur celle de la constante qui la
précède à laquelle on ajoute 1. Donc ici Z sera bien égal à 4. (car 3+1).
Utilisons maintenant ces constantes dans notre programme, mais avant créer un synonyme de votre énumération car tout
comme pour une structure, il faut utiliser un mot-clé pour utiliser une énumération (enum)
Code c:
enum Plan {X, Y = 3, Z};
int main()
{
Plan var1 = X;
Plan var2 = Y;
Plan var3 = Z;
return EXIT_SUCCESS;
}
On peut aussi utiliser nos constantes dans un switch par exemple :
Code c:
enum Plan {X, Y = 3, Z};
int main()
{
Plan var4 = Z;
switch(var4)
{
case X : printf("var4 vaut X"); break;
case Y : printf("var4 vaut Y"); break;
case Z : printf("var4 vaut Z"); break;
default : printf("Erreur !"); break;
}
return EXIT_SUCCESS;
}
Code console:
var4 vaut Z
Auteur ppierro