Tutoriels >> Nos tutoriels sur la programmation Nos tutoriels sur la programmation >> Langage C Langage C >> Cours sur le langage C - Apprendre la programmation en C - Le langage C - Programmer en C Cours sur le langage C - Apprendre la programmation en C - Le langage C - Programmer en C

Cours sur le langage C - Apprendre la programmation en C - Le langage C - Programmer en C






Chapitre 1: Une histoire de programme - Langage C



Qu'est ce qu'un programme




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.




Chapitre 2: Les bons outils et les bases



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.


Installation et Configuration de Visual C++ Express



Rendez vous sur ce site.
Dans le petit cadre "Download Now!" Choisissez votre langue "French" pour la plupart d'entre vous puis cliquez sur "Download".
Vous allez télécharger un petit utilitaire qui s'occupera du téléchargement de VC++ Express et de l'installer sur votre ordinateur. N'installez aucuns des produits additionnels dans "Options d'Installations". Ensuite cliquez sur suivant, vous allez télécharger tout le nécessaire au bon fonctionnement du logiciel. A noter que l'installation peut prendre un certain temps.

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 :

Nouveau projet en langage C dans Visual Studio

Puis cliquez sur suivant et remplissez la fenêtre suivante comme ceci :

Paramètres du projet dans Visual C

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 :

Ajouter un nouveau fichier source dans Visual Studio

Enfin créer votre fichier comme ceci :

Créer une source Cpp dans Visual Studio

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 :

Compilation du projet en C

Voilà vous êtes fin prêt rendez vous donc au paragraphe "Premier programme C" ?

Installation et Création d'un projet Code::Blocks sous Windows



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 :

écran démarrage d'un projet en langage C avec Codeblocks

Pour créer un nouveau allez dans File et choisir New Project, cette fenêtre s'ouvre :

Créer un nouveau projet dans Code::Blocks et choisissez Console Application

Choisissez Console Application, puis appuyer sur GO.

Une fenêtre s'ouvre, appuyer sur Next.
Ensuite, choisir comme langage le C

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.

Cliquez sur Finish

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 :

Boutons de raccourci pour la compilation

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


Rendez vous maintenant au paragraphe "Premier programme C"

Compilation en ligne de commande sous Linux



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:
sudo apt-get install gcc


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 :

  • -Wall : Permet de repérer et d'afficher tout les avertissements
  • nomDeMonFichier.c : le fichier qui contient votre code.
  • -o : permet de dire à gcc que nous voulons un fichier binaire
  • nomDuProgramme : le nom de votre programme


Ce qui au final nous donne ceci :

Compilation du projet en ligne de commande sous Linux

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


Ce qui nous donne ceci :

Exécution du programme


Premier programme C



Vous devriez avoir sous les yeux :

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.

Bien, maintenant détaillons tout ça :

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.

A l'intérieur de cette fonction nous pouvons lire :

Code c:
{
 	printf("Hello world!\n");
	return 0;
}


Il s'agit d'instructions. C'est ce que va réaliser la fonction.

printf sert à afficher du texte à l'écran.
\n permet de sauter une ligne
return 0 est un peu plus complex. En fait on renvoie au programme une valeur, ici 0, pour dire au programme que la fonction s'est correctement réalisée. Nous verrons cela en détail plus tard.

On pourrait donc traduire ce code par :
  • affiche le message " Hello world!", grâce à printf
  • saute une ligne, grâce au \n
  • renvoie la valeur 0 car tout s'est bien passé, grâce au 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.

Enfin en haut on peut voir :

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.

Vous pouvez tester autre chose par exemple remplacer

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 !




Chapitre 3: Variables et opérations - Langage C



Qu'est ce qu'une variable?



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.

Hein ? O_o J'ai pas compris là ...


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 :

sont justes : vieMonstre, vie_du_monstre, vie_monstre1, VIE_MONSTRE
sont faux : 1vie, viedepart-5, vie0,005
sont problématiques : a, A2, B2, b2, e, b


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)

Comment afficher la valeur de cette variable ?
Avec un printf tout bête rajoutez cette ligne juste après la déclaration de la variable ageUtilisateur :

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.

Du code pour illustrer tout cela :

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 ...

Il existe un autre genre de variable : les constantes.
Comme leur nom l'indique, la valeur de ces variables ne peut pas changer au cour du déroulement du programme et si vous avez bien suivi, c'est là le contraire avec une variable " ordinaire" qui, elle, peut changer de valeur au cour du programme.

Pour définir une constante, on écrit :

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.

Ce type décide de l'occupation en mémoire de cette donnée.

Ces types se divisent en deux groupes :

- les entiers
- les nombres a virgules flottantes

Les Entiers :

Les types stockant des nombres entiers sont :
  • int : il stocke le nombre sur deux octets, il permet de stocker des nombres entiers allant de - 32 768 à 32 767. On l'utilisera en priorité pour des petits nombres entiers.
  • long : l stocke un nombre sur quatre octets, il permet de stocker des nombres entiers allant de - 2 147 843 648 à 2 147 843 647. On l'utilisera en priorité, il permet surtout de gérer les erreurs de saisie d'un utilisateur (oui il y a toujours ceux qui tapent un nombre improbable pour tester le programme).


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 ).

Les nombres à virgule :

  • 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.

A partir d'ici je ne met plus :

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 ?

...

Voici la solution pour ceux qui n'aurait pas réussi

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;
}

2ème partie : Opérations



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



Qu'est ce qu'une expression ?

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 ... ?]).

D'ailleurs on peut afficher cela avec un code tout simple :

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 ? ).
Normalement on voit apparaitre :

Code console:
2 + 3 = 5


Compliqué ? Non je sais ;)

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. Mais pas de panique on comprend très vite.

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


Un jeu d'enfant ... A vous de jouer ...D

Voici la solution :

Code c:
int main ()
{
	long premierNombre = 0;
	long deuxiemeNombre = 0;
	long resultat = 0;

	/* \t équivaut à une tabulation */
	printf("\t\tMa super calculette\n\n");
	printf("Ce programme additionne 2 nombres entiers !!!\n");
	printf("Entrez le premier nombre svp : ");
	scanf("%ld", &premierNombre);
	printf("Deuxieme ombre svp : ");
	scanf("%ld", &deuxiemeNombre);

	resultat = premierNombre + deuxiemeNombre;

	printf("\nResultat : %ld", resultat);
	return 0;
}


Ce qui nous donne :

Code console:
Entrez le premier nombre svp : 21
Deuxieme nombre svp : 56

Resultat : 77


C'est simple, c'est simple ...
Maintenant passons aux soustractions ?


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;

	printf("chiffre3 vaut : %ld, chiffre4 vaut %ld.", chiffre3, chiffre4);
	return 0;
}


Code console:
chiffre3 vaut : -1, chiffre4 vaut 2.


Passons aux multiplications

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 gne ).

Code c:
int main ()
{
	long chiffre = 2;
	long chiffre2 = 4;
	long chiffre3 = chiffre * chiffre2;
	long chiffre4 = 10 * 0;

	printf("chiffre3 vaut : %ld, chiffre4 vaut %ld.", chiffre3, chiffre4);
	return 0;
}


Code console:
chiffre3 vaut : 8, chiffre4 vaut 0.


Passons à la division et au modulo.

Les divisions et modulos



Toujours le même principe que l'addition sauf que l'opérateur de le division est " / " et celui du modulo est " % ".

Quel différence entre les deux ?

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 ).

!!!!!!! ATTENTION !!!!!! UNE DIVISION PAR 0 EST INTERDITE !!!!

Le code qui résume :

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:
chiffre vaut : 2, chiffre2 vaut 0.


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.




Chapitre 4: Les conditions



Qu'est ce qu'une condition ?

Si je vous dis :

Tu n'iras voir tes amis que si la table est ramassée.

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 "

C'est du programme de français au collège ... ?

Quel rapport avec le C ?


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.

Les signes indispensables



Voici la liste des opérateurs dit de comparaison, à retenir :

<strictement inférieur à ...
<=inférieur ou égal à ...
>strictement supérieur à ...
>=supérieur ou égal à ...
==égal à ...
!=différent de ... (non égal à ...)

Maintenant la liste des opérateurs dit logiques,à retenir également ? :

||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.

En C, l'évaluation logique des expressions obéit à la règle suivante :

- 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.

Prenons comme exemple :

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.

Si nous avons une variable :

Code c:
long x;


et l'affectation :

Code c:
 x = ( 5 == 10 );


alors la variable reçoit la valeur 0.

Résumé :

si la valeur de l'expression de comparaison vaut :

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.

Petit programme pour illustrer les booléens :

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);

	printf("Resultat pour x = %ld et y = %ld :\n", x, y);
	printf("( 1 = TRUE     0 = FALSE )\n\n");

	printf("x = y ? \t\t\t%ld\n", x == y);
	printf("x different de y ? \t\t%ld\n", x != y);
	printf("x plus petit que y ? \t\t%ld\n", x < y);
	printf("x plus grand que y ? \t\t%ld\n", x > y);

	return 0;

}


Ce qui nous donne pour x = 5 et y = 2 :


Code console:
Ce programme compare la valeur de 2 nombres.
Entrez deux entiers :
x = 5
y = 2
Resultat pour x = 5 et y = 2 :
( 1 = TRUE 0 = FALSE )

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 :

If ( < expression >)
< instruction >;

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.

Voila un petit code pour illustrer If dans un programme :

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.

Maintenant essayez ce code source :

Code c:
int main ()
{
	long x = 2;
	long y = 3;

	if (!(x > y))
		printf("X  est inferieur a Y\n");

	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 :

Si x n'est pas supérieur à y.

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");


ne s'affichera que si la condition est vraie. En revanche :

Code c:
printf("instruction suivant celle de la condition");


s'affichera peu importe la valeur de la condition. Si nous voulons que :

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;
}


Voilà ... à retenir car essentiel

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 :

si l'expression du if est fausse alors fait ça.

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.

Voyons maintenant le schéma du programme :

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;

	printf("Quel est votre age ? ");
	scanf("%ld", &age);

	/*Si age = 18 ou ( d'où l'opérateur || ) si age est > à 18 */
	if (age == 18 || age > 18 )
	{
		printf("Vous etes majeur");
	}

	else
	{
		printf("Tu es mineur");
	}
	return 0;
}


Code console:
Quel est votre age ? 16
Tu es mineur

Quel est votre age ? 18
Vous etes majeur

Quel est votre age ? 77
Vous etes majeur


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;

	printf("Quel est votre age ? ");
	scanf("%ld", &age);

	if (age < 18 )
 	{
		printf("Tu es mineur");
 	}

	else if ( age == 18 )
	{
		printf("Tu es tout juste majeur");
	}

	/*si age est > 18 et ( && ) age est < à 130 */
	else if (age > 18 && age < 130 )
	{
		printf("Vous etes majeur");
	}

	else
	{
		printf("Tu dois etre tres age ? ");
	}

	return 0;
}


Voila pour le else if.

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 :

switch < expression >
{
case valeur_1 : <instructions>;
break;
case valeur_2 : <instructions>;
break;
.
.
.
case valeur_n : <instructions>;
break;
default : <instructions>;
}

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.

Voici un code pour illustrer cela :

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 ...


Chapitre 5: Les boucles - Langage C



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.

expression2 ce sera justement la condition pour que la boucle s'exécute.

expression3 permettra de modifier la valeur de la variable de contrôle à chaque passage de la boucle.

N'oubliez pas de séparer ces 3 expressions par un " ; "


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 */

         for ( i = 0 ; i < 3 ; i++)
             {
                  printf("Hello World !\n");
             }

         return 0;
  }


En testant ce code vous devriez avoir quelque chose comme :

Code console:
Hello World!
Hello World!
Hello World!


Détaillons maintenant le code que nous venons de créer :

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.


Voilà comment on pourrait traduire cette boucle en français :

Commence avec i = 0 ;
Faire tant que i < 3 ;
Rajoute 1 à chaque passage de la boucle ;

Afficher le message "Hello World!"
Reviens au début
Rajoute 1
i = 1 donc < 3 On peux recommencer
Afficher le message "Hello World!"
Reviens au début
Rajoute 1
i = 2 donc < 3 On peux recommencer
Afficher le message "Hello World!
Rajoute 1
i = 3 donc i < 3 est validé Quitte la boucle
Fin du programme.

Voilà sommairement ce que fait notre programme. ?

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 ?


Continuons maintenant avec la boucle while


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.

Il n'y a pas non plus de ";" à la fin du while


Vous commencez à comprendre le principe des boucles ?
C'est bien ?

Il ne nous en reste plus qu'une à voir : la boucle do / while

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

Ici ne pas oublier le " ; " à la fin du while


petite mise en garde sur les boucles infinie



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.

Voici des exemples de boucle infinie (à éviter de reproduire donc ?)

Code c:
while (1)
{
     printf("Boucle infinie !");
}

/* 1 est toujours vrai */

for ( i = 0 ; i < -1 ; i++)
{
     printf("Boucle infinie !");
}

/* i vaut 0 au départ donc sera TOUJOURS supérieur a -1 dans cette boucle ! */

do
{
     printf("Boucle infinie !");
}while (4 < 5);

/* 4 est toujours supérieur à 5 */


Soyez attentif et pensez votre code avant de le compiler ?

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 ?

Essayer d'avoir un rendu comme celui ci :

Code console:
Combien de tour SVP : 3

Nombre de tours dans la boucle : 1
Nombre de tours dans la boucle : 2
Nombre de tours dans la boucle : 3

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.



Chapitre 6: Les fonctions - Langage C



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.


Qu'est ce qu'une fonction




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 ? gne


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.


Créer une fonction et l'utiliser




Pour créer une fonction, il faut préciser plusieurs choses :

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 */


} /* fin du bloc 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;
    
    /* On donne pour valeur a la variable resultat, la valeur renvoyée par la fonction */
    resultat = fonction(nombre1, nombre2);

    printf("%d + %d = %d",nombre1, nombre2, resultat);

    return 0;
}



Ce qui nous affiche normalement :

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.

Comme par exemple :

Code c:
void  afficherBonjour(void) /* pas de paramètres donc void ? */
{
    printf("Bonjour !\n");
}

int main ()
{
    afficherBonjour();

    return 0;
}


Ce qui doit nous donner :

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.


Astuces et mise en garde



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 ();


Vous pourrez ensuite placer votre fonction en dessous du main.

Attention avec les types !

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é !

Mais alors, qu'est ce donc que cette chose là ?


Qu'est ce qu'un pointeur ?




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 ?


Lorsque vous créez une variable par exemple :

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;

    printf("Valeur de maVariable : %d\n", maVariable);
    maFonction();
    return 0;
}

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

Pour exemple vous pouvez tenter ce programme :

Code c:
#include <stdio.h>
#include <stdlib.h>

void maFonction(int maVariable);

int main()
{
    int maVariable = 10;

    printf("Valeur de maVariable : %d", maVariable);
    maFonction(maVariable);
    printf("\nValeur de maVariable apres le passage dans maFonction : %d\n\n", maVariable);
    return 0;
}

void maFonction(int maVariable)
{
    maVariable = maVariable + 6;
    printf("\nValeur de maVariable dans maFonction : %d", maVariable);
}


Qui nous donne :

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 :

Tableau de variables dans la RAM

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.


Utiliser les pointeurs




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;


On a donc ici un pointeur de type int se nommant "monPointeur";

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;
    
    /* Affiche l'adresse de ma Variable grâce au "&"*/
    printf("Adresse de maVariable : %ld\n", &maVariable);
    
    /* Affiche la valeur de maVariable */
    printf("Valeur de maVariable : %ld\n", maVariable);
    
    /* On affiche l'adresse contenu dans notre pointeur en utilisant la syntaxe
    classique pour afficher une variable */
    printf("Adresse contenue dans le pointeur monPointeur : %ld\n", monPointeur);
    
    /* On affiche la valeur de la variable se trouvant a l'adresse contenu par monPointeur
    en rajoutant une symple étoile ( " * ") devant le nom du pointeur */
    printf("Valeur de la variable se trouvant a l'adresse contenu par monPointeur : %ld", *monPointeur);

    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 ).

Voyons donc comment envoyer et utiliser un pointeur dans une fonction.

Envoyer et utiliser un pointeur dans une fonction



On peut envoyer de plusieurs manières un pointeur à une fonction.

  • En envoyant directement l'adresse d'une variable à un pointeur.
  • En envoyant un pointeur (qui contiendra donc l'adresse d'une variable) a la fonction.


Code c:
#include <stdio.h>
#include <stdlib.h>

void maFonction(int *pointeur);

int main(void)
{
    int maVariable = 10;
    
    /* Avant l'appel de la fonction maVariable vaut 10 */
    printf("Valeur de maVariable avant l'appel de fonction : %d\n", maVariable);

    /* On envoie l'adresse de maVariable à maFonction */
    maFonction(&maVariable);

    /* La valeur de maVariable a été modifiée elle vaut maintenant 5 ! */
    printf("Valeur de maVariable apres l'appel de fonction : %d", maVariable);


    return 0;
}

void maFonction(int *pointeur)
{
    /* Ce pointeur va directement modifier la valeur de maVariable pour la mettre à 5 */
    *pointeur = 5;
}


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.

Mais on peut envoyer d'une autre manière un pointeur à une fonction :

Code c:
void maFonction(int *pointeur);

int main(void)
{
    int maVariable = 10;
    int *monPointeur = &maVariable;

    printf("Valeur de maVariable avant l'appel de fonction : %d\n", maVariable);
    maFonction(monPointeur);
    printf("Valeur de maVariable après l'appel de fonction : %d", maVariable);


    return 0;
}

void maFonction(int *pointeur)
{
    *pointeur = 5;
}


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 problèmes de compréhensions ou autres n'hésitez pas à allez poster sur le forum.

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 ?




Chapitre 8: Les tableaux



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.

Il existe deux types de tableaux :

  • 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.




Déclaration d'un tableau



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]; 


N'est valable qu'en C99.

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};


On initialise ici toutes les cases du tableau à zéro.

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};


Alors seulement tableau[0] aura la valeur 2.


A notée qu'on peut aussi remplir le tableau de cette façon :

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é */
}


Ce qui nous donne après compilation :

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 */

     double moyenne = 0.0;
     double sommeTotale = 0.0;


     for (i = 0; i < 4; i++) {
         printf("Valeur de tableau[%d] = %lf\n", i, tableau[i]);
         sommeTotale += tableau[i]; // Revient à écrire sommeTotale = sommeTotale + tableau[i]
         /* On affiche les valeurs contenues dans le tableau et on les additionne à la variable sommeTotale */
     }

     moyenne = sommeTotale / 4;

     printf("\nMoyenne des valeurs du tableau : %lf", moyenne);

    return 0;
}



Ce qui nous donne :

Code console:
Valeur de tableau[0] = 2.000000
Valeur de tableau[1] = 16.500000
Valeur de tableau[2] = 58.560000
Valeur de tableau[3] = 19.920000

Moyenne des valeurs du tableau : 24.245000


Utiliser un tableau dans une fonction



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 ?

Voilà un petit code source qui nous présente cela :

Code c:
#include <stdio.h>
#include <stdlib.h>

void afficherTableau(int tableau[]);
int main(void)
{
    int tableau[4] = {2, 23, 25, 92};
    afficherTableau(tableau);

	return 0;
}

void afficherTableau(int tableau[])
{
    int i = 0;

    for (i = 0; i < 4; i++)
        printf("Tableau[%d] = %d\n", i , tableau[i]);
}


Ce qui nous donne :

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 !

Il est aussi possible d'envoyer un tableau à une fonction de cette manière :

Code c:
void afficherTableau(int *tableau);
int main(void)
{
    int tableau[4] = {2, 23, 25, 92};
    afficherTableau(tableau);

	return 0;
}

void afficherTableau(int *tableau)
{
    int i = 0;

    for (i = 0; i < 4; i++)
        printf("Tableau[%d] = %d\n", i , tableau[i]);
}


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 :

Matrice sur les variables à tableau en C

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.


Voici donc comment déclarer notre tableau de 2 colonnes sur 2 lignes en C :

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.

Utiliser un tableau à deux dimensions dans une fonction



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.


Ainsi il faut donc suivre le code suivant :

Code c:
#include <stdio.h>
#include <stdlib.h>

void afficherTableau(int tableau[2][2]);
int main(void)
{
    int tableau[2][2] = {{10, 20} , {15, 35}};
    afficherTableau(tableau);

	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>

void afficherTableau(int tableau[2][2]);
int main(void)
{
    int tableau[2][2] = {{10, 20} , {15, 35}};
    afficherTableau(tableau);

	return EXIT_SUCCESS; /* Equivalent à return 0 sous Windows, permet un code portable */
}

void afficherTableau(int tableau[2][2])
{
    int i = 0;
    int j = 0;

    for (i = 0; i < 2; i++) {
        for(j = 0; j < 2; j++) {
            printf("Tableau[%d][%d] = %d\n", i, j, tableau[i][j]);
        }
    }
}



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.


Chapitre 9: Les types avancées [Partie I] - Langage C



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


Créer et utiliser une structure



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.

Voici la syntaxe utilisée pour définir une structure :

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.

Attention on ne peut pas faire comme cela :
Code c:
struct MaStructure {
   int var1 = 10;
   long var2 = 40000;
   double varN = 12.5;
};

Initialiser des variables directement dans la structure est interdit !


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 */

    return EXIT_SUCCESS; /* Equivalent à return 0 sous Windows */
}



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 = {};
}


Toutes les variables de la structure MaStructure sont donc initialisées à 0.

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 = {};

    printf("%d\n", maStructure.var1); /* Accès a var1 de MaStructure */
    printf("%ld\n", maStructure.var2); /* Accès a var2 de MaStructure */
    printf("%lf\n", maStructure.varN); /* Accès a varN de MaStructure */

    return EXIT_SUCCESS;
}


Ainsi le code suivant nous affiche :

Code console:
0
0
0.000000


Nos variables sont donc bien initialisées à 0.

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.

On peut aussi faire de cette méthode :

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.

On peut donc maintenant modifier n'importe quelles variables de MaStructure.


Pointeurs vers des Structures



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;

void fonction(struct MaStructure *maStructure);

/* Pensez bien à mettre le prototype après la déclaration de la strcture */

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;
}

void fonction(struct MaStructure *maStructure)
{
   /* Ici on pourra modifier les attributs de MaStructure */
}


Cependant avant pour accéder aux attribut on faisait comme cela :

Code c:
maStructure.var1 = 10;


Mais avec un pointeur ça ne marche plus comme ça (ç'aurait été trop beau ?)
Il va nous falloir utiliser une notation un peu plus complexe :

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;

void fonction(struct MaStructure *maStructure);

/* Pensez bien à mettre le prototype après la déclaration de la structure */

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;
}

void fonction(struct MaStructure *maStructure)
{
    maStructure->var1 = 10;
    maStructure->var2 = 40000;
    maStructure->varN = 12.5;
}


Qui nous donne ceci :

Code console:
10
40000
12.500000


Dans la prochaine partie nous verrons le typedef, les énumérations et les unions.


Chapitre 10: Les types avancées [partie II] - Langage C



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;


Les deux types devenant interchangeable, rien ne empèche maintenant d'écrire :

Code c:
synonymeDeInt variable = 10;


qui reviendra donc à écrire :

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 */

void fonction(struct MaStructure *maStructure);

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;
}

/* Plus besoin de struct ici aussi */
void fonction(MaStructure *maStructure)
{
    maStructure->var1 = 10;
    maStructure->var2 = 40000;
    maStructure->varN = 12.5;
}


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};

typedef enum Plan Plan;

int main()
{
    Plan var1 = X;
    Plan var2 = Y;
    Plan var3 = Z;

    printf("var1 = %d\n", var1);
    printf("var2 = %d\n", var2);
    printf("var3 = %d", var3);

    return EXIT_SUCCESS;
}


On peut aussi utiliser nos constantes dans un switch par exemple :

Code c:
enum Plan {X, Y = 3, Z};

typedef enum Plan Plan;

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


Voilà vous savez maintenant comment utiliser les énumérations.
Dans la prochaine partie nous parlerons plus en détail de la mémoire vive et le langage C et vous apprendrez que ce que je vous disais au début sur celle-ci n'est pas totalement vrai gne
Nous verrons aussi comment créer une union.
Cours sur le langage C - Apprendre la programmation en C - Le langage C - Programmer en C
Auteur ppierro
Date de création 20/03/2009 à 20h56
Dernière date d'édition 10/02/2016 à 01h09
Avancement 100 %
Nombre de fois consultés 1043387
Commentaires Ajouter un commentaire
Affichage complet du tutorial
Connecté(s) 1 connectés (0 membres, 1 invités)