=====================================================================
	Préambule
=====================================================================

	Bien. Suite au harcèlement incessant d'Alex Ploit ces dernières semaines, vous allez avoir le privilège de découvrir ici le premier article d'une longue série que je compte écrire sur la programmation en général et le C en particulier... Evidemment, pour ne pas vous rebuter en masse, ceux-ci seront de difficulté progressive, et ceux qui ont déjà roulé leur bosse dans la programmation pourraient bien s'ennuyer dans la première partie ! Mais qu'ils se rappellent de leurs débuts et ils comprendront peut-être pourquoi il est nécessaire de rappeler ce qu'ils considèrent comme trivial depuis longtemps...

	Certains ont peut-être quelques appréhensions vis à vis du C, comme quoi il s'agit d'un langage difficile et réservé à une élite boutonneuse et à la peau bronzée par les ultraviolets de leurs moniteurs ? Que nenni ! Déjà, un vrai programmeur C dispose d'un écran TFT 21" afin de pouvoir ouvrir plein de fichiers et de consoles en même temps ;) Plus sérieusement et partant de mon expérience personnelle, je n'y connaissais rien en C jusqu'à ce qu'un beau jour, je m'y mette, et un mois plus tard, j'en maîtrisais tous les concepts... Si vous trouvez que c'est long, abandonnez l'idée de pouvoir programmer en quoi que ce soit !

	Enfin, que vous préfériez Windows ou Linux, peu importe : mes programmes sont tous écrits de manière portable, c'est à dire qu'ils seront utilisables sous votre système préféré sans problème. Dans les prochains articles toutefois, il sera parfois nécessaire d'installer quelques librairies (enfin, surtout pour Windows en fait), mais j'essaie de limiter cela au maximum et de me conformer le plus possible à la norme C90, reconnue par la majorité des compilateurs actuels.

	Avant d'aller plus avant dans cet article, voici une liste de choses qui pourront vous servir à un moment ou à un autre :
		- un compilateur : j'utilise personnellement GCC dans son cru 3.3.1, car il s'agit d'un produit totalement libre et hautement optimisé, disponible sous quasiment tous les OS actuels. GCC est fourni avec Linux, dont il est le compilateur natif. Sous Windows, vous pouvez installer la distribution de MinGW, excellent portage s'il en est (par contre, oubliez Cygwin qui a pris un méchant coup de vieux et qui n'est qu'une sorte d'émulateur unix, bien commode mais pas optimal).
		- un éditeur de textes : sous Linux on trouve traditionnellement vi et emacs, logiciels d'une rare puissance mais nécessitant un long temps d'apprentissage pour en maîtriser toutes les possibilités (si tant est que ce soit possible, d'ailleurs). Pour ma part je préfère des logiciels plus simples et tout aussi fonctionnels, comme l'excellent Bluefish. Pour les utilisateurs de Windows, le notepad se révèlera un compagnon idéal au début, mais je vous recommande de vous tourner vers des éditeurs spécialisés et gérant au minimum la coloration syntaxique du code... Un petit tour sur telecharger.com devrait vous donner pas mal de résultats, je vais pas vous mâcher la vie non plus :)
		- un cerveau : en bon état si possible, pas trop enfumé, pas trop imbibé, frais et dispo...
		- un petit frère : pour passer vos nerfs :)

	Bon, assez de bla-bla, on va maintenant entrer dans le vif du sujet... Si vous ne comprenez pas un passage (ce qui risque d'être relativement fréquent si vous n'avez aucune expérience en programmation), continuez à lire tout de même, vous devriez comprendre par la suite ! En fait, à moins de n'être un surhomme, il serait illusoire de tout ingérer d'un coup...

	Sur ce, bonne lecture à tous !

					Alex Centrique

=====================================================================
	Sommaire
=====================================================================

	1) notre premier programme : code source et commentaires
	2) compilation : un premier contact avec GCC
	3) un programme plus élaboré : arguments
	4) conclusion et points à retenir
	5) dédicaces et remerciements

=====================================================================
	1) Notre premier programme
=====================================================================

	Une vieille tradition en informatique veut que le premier programme affiche "Hello World !" à l'écran. Selon certains, cela viendrait du livre de référence du C, "The C Programming Language" écrit par Brian W. Kernighan et Dennis M. Ritchie, que vous vous devez d'avoir sur votre table de chevet car c'est une mine d'informations, les auteurs étant les pères du C, justement.

	Nous allons donc commencer par étudier un programme C minimal, c'est à dire parfaitement valide bien qu'il ne fasse rien, puis nous l'élargirons pour qu'il affiche le traditionnel "Hello World !" à l'écran.

	En C, tout programme débute son exécution par la fonction main, qui correspond à ce qu'on appelle le point d'entrée du programme. Cette fonction doit obligatoirement retourner une valeur de type entier, et peut ou non recevoir des arguments (nous verrons comment faire dans la section 3).

	Pour ceux qui ne le sauraient pas, une fonction est un morceau de code pouvant (ou non) retourner une valeur. Par exemple, l'addition a=b+c peut se définir en C par une fonction comme a=add(b,c), où a est une variable destinée à recevoir le résultat de la fonction add et b,c sont les arguments de la fonction. Il est important que la variable a et la fonction add aient le même type de données, ou au moins que ceux-ci soient compatibles (on peut mettre un nombre entier dans un nombre réel, mais pas l'inverse, je vous renvoie à vos mathématiques élémentaires).

	Les différentes possibilités pour la valeur de retour d'une fonction sont : rien du tout (void), un entier (short, int et long), un caractère (char) ou un nombre à virgule flottante (float ou double). Nous reviendrons sur ces différentes possibilités plus tard, sachez juste qu'elles existent et que je les ai groupées par compatibilité.

	Ce sont les mêmes pour les variables, à l'exception de void : une variable qui ne serait rien n'aurait pas de sens. Au passage, une variable représente une valeur en mémoire dont l'interprétation est faite par son type. C'est à dire que si la variable est un entier, la mémoire sera présumée contenir une valeur entière, si la variable est un caractère, la mémoire sera lue comme un caractère, etc... Comme vous le voyez, le type d'une variable est d'autant plus primordial qu'il en définit l'interprétation.

	Voici la traduction de tout ce bla-bla en C :
		int main (void) {
			return 0;
		}

	C'est plus compact, non ? Hé revenez, je vais vous expliquer !

	Vous pouvez remarquer que j'ai colorié le code du programme. Loin de n'être qu'un effet esthétique, cette coloration est surtout destinée à permettre au programmeur de repérer du premier coup d'oeil à quel type correspond un mot. Dans la suite de mes articles, le bleu indiquera un mot réservé du C, le vert aux valeurs numériques et chaînes de caractères, et le rouge aux séparateurs. Le reste sera en bleu marine.

	Dans notre exemple, int main (void) déclare donc une fonction appelée main, retournant un résultat de type entier (int) et ne prenant aucun (void) argument. Les accolades { et } servent à délimiter le code de notre fonction. return 0 est une instruction qui commande à main de renvoyer la valeur 0, ce qui provoque la fin du programme, et comme en C toutes les instructions doivent se terminer par des ;, on en trouve un ici.

	C'est un peu plus clair ? Ah, y'en a qui n'ont pas compris le coup du ; ! En fait, on pourrait aussi bien écrire le programme sous une autre forme, moins évidente mais certaint trouvent cela plus esthétique, chacun ses goûts :
		int main (void) {
			return
			0;
		}

 	Le compilateur considérera que return et 0 forment une seule instruction, car il n'y a pas de ; derrière return. L'avantage de cette souplesse de syntaxe est que chacun de vous pourra formater ses codes comme il le souhaite (par exemple, il est tout à fait possible de mettre le ; tout seul sous le zéro), l'inconvénient étant que la plupart de ceux qui formatent comme ils le souhaitent rendent leur code illisible pour n'importe quelle personne normalement constituée, et c'est encore pire en C++ :)

	Le décalage est purement esthétique, mais cette fois je vous conseille de le mettre en oeuvre car il est facile de se perdre dans l'imbrication des accolades. En effet, chaque accolade { ouvre un nouveau bloc de code, qui se terminera à la prochaine accolade }. Donc, pour éviter d'oublier de fermer vos blocs et de perdre du temps à compter vos accolades, décalez votre code d'une tabulation à droite après chaque {, puis revenez d'une tabulation à gauche avant chaque }.

	Bon c'est bien joli tout çà mais on n'a toujours rien affiché à l'écran !

	Pour ce faire, nous allons avoir besoin d'une fonction de la librairie standard du C, c'est à dire des fonctions que l'on retrouve sur tous les OS car elles sont définies dans la norme même du C. Pour afficher du texte, il s'agit de la fonction puts (put string), définie dans la librairie stdio (standard input and output).

	Voyons comment tout ceci est inclus dans le programme précédent :
		/* on inclut la librairie stdio */
		#include <stdio.h>
		/* l'exécution du programme commencera ici */
		int main (void) {
			/* on affiche "Hello World !" */
			puts ("Hello World !");
			/* on quitte le programme et on renvoie le code d'erreur 0 */
			return 0;
		}

	Houla, c'est quoi ces machins gris entre /* et */ ? Ce sont des commentaires, c'est du texte qui sera ignoré par le compilateur et qui permet de décrire les actions effectuées par le programme. Un commentaire débute par /* suivi d'un nombre quelconque de lignes, puis on utilise */ pour fermer le commentaire. Les programmes C ne sont pas toujours évident à comprendre de prime abord, surtout s'ils ont été optimisés, et les commentaires sont parfois vitaux pour comprendre ce que fait réellement le programme...

	En l'occurence, le programme ci-dessus correspond à notre hello world, et il est suffisamment commenté pour que vous puissiez le comprendre sans peine ;) Une fois que vous aurez retapé ou copié/collé le code ci-dessus, enregistrez-le dans un fichier nommé "hello.c", puis nous passerons ensuite à la compilation, qui consiste à transformer notre code en langage machine, l'assembleur, qui fera probablement lui aussi le sujet d'une série d'articles.

=====================================================================
	2) La compilation
=====================================================================

	Bon, vous avez votre hello.c ? Hé bien il est temps d'ouvrir une console !

	C'est quoi ? Ah... Ben une console, c'est une interface en mode texte avec l'ordinateur, c'est à dire que vous lui tapez des commandes, il les exécute, puis attend la suivante (comme quoi y'a pas plus con qu'un ordinateur). Sous Windows, selon votre version, il faut exécuter CMD.EXE ou COMMAND.COM, ce qui provoquera l'apparition d'une fenêtre typiquement noire avec du texte gris, en général C:\> suivi d'un curseur clignotant. Sous Linux, vous devriez savoir comment faire, sinon qu'est-ce que vous foutez sous Linux ? D'ailleurs je ne décrirais dans la suite que les manipulations à effectuer sous Windows, sous Linux, reportez-vous au manuel (commande man).

	Une fois dans votre console, tapez ceci : gcc hello.c, puis appuyez sur la touche Entrée.

	Note 1 : si vous obtenez un message du genre "la commande gcc n'est pas reconnue", c'est que votre PATH est mal configuré. Assurez-vous d'avoir le dossier C:\GCC\BIN dans votre PATH ! Pour savoir comment faire, allez voir dans les propriétés système, dans le panneau de configuration... Puis cherchez un peu, et ne revenez qu'après avoir trouvé !

	Note 2 : si vous obtenez le message "gcc: hello.c: No such file or directory", c'est que vous n'êtes pas dans le bon dossier ! Je vous conseille de taper help et de vous instruire sur le maniement d'une console, cela vous sera extrêmement utile pour la suite...

	Après avoir exécuté gcc, vous devriez voir ... rien du tout, hormis un fichier a.exe qui vient d'apparaître dans votre répertoire. Tapez donc a sur votre ligne de commande, vous devriez voir... Hello World ! Non, vous ne voyez rien ? *soupir* Faut appuyer sur entrée après avoir tapé a...

	Voilà, vous savez compiler un programme avec GCC (et accessoirement, qu'il faut taper sur entrée après avoir tapé une commande) ! Je vais quand même vous donner quelques options très utiles, qui vous permettront d'écrire des programmes comportant un minimum d'erreur...
		-Wall		active tous les avertissements sur les ambiguités de votre code
		-W		active d'autres avertissements qui vous permettraient d'améliorer encore votre code
		-o fichier	enregistre le programme dans le fichier donné

	Par exemple, pour compiler hello.c en hello.exe avec tous les avertissements possibles (et surtout utiles) :
		gcc -Wall -W hello.c -o hello.exe

	D'une manière générale, tant que GCC vous prévient d'une potentielle erreur dans votre code, corrigez puis recompilez ! Un bon programme ne devrait avoir AUCUN avertissement, sauf bien sûr si on sait ce que l'on fait, ce qui ne doit pas être votre cas pour le moment... Rassurez-vous, çà viendra avec de la pratique ;)

	Avant de passer à la section suivante, qui présentera un programme un peu plus poussé (avec une fonction et des arguments), je vous conseille de relire attentivement cet article, de prendre une pause clope, de tester ce dont vous avez envie, pourquoi pas de chercher un peu de documentation sur le web, puis de revenir frais et dispo pour la suite :)

=====================================================================
	3) Un programme plus élaboré
=====================================================================

	Alex Ploit trouvait mon hello world trop simple, et c'est peut être votre cas aussi ? Ok, on va donc se fixer un nouvel objectif... En l'occurence, nous allons essayer de réaliser un programme qui affiche son nom puis la liste de tous les arguments que vous lui avez passés via la ligne de commande (pour les ignares, tout ce qui suit une commande est un argument... à ne pas confondre avec les arguments des fonctions, bien entendu !), çà vous convient ? Tant mieux, de toute façon, vous n'avez pas vraiment le choix ;)

	Bon ok, mais comment on va faire ? Il faut savoir que la fonction main admet deux formes possibles en C (le reste n'est que fantaisie) :
		int main (void)				cette forme ne gère pas les arguments de la ligne de commande
		int main (int argc, char** argv)		cette forme, oui !

	Hum, çà se complique... argc est en fait un nombre entier qui nous indique combien d'arguments sont disponibles, et argv est un tableau de chaines de caractères, dans lequel sont mémorisés chacun de nos arguments... En C, un tableau correspond à des zones contigues en mémoire, accessibles par une variable de type tableau (le ** derrière char définit un tableau de chaines de caractères), la première case étant à l'adresse 0, la deuxième à l'adresse 1, et ainsi de suite...

	Voici un petit diagramme pour illustrer un tableau de dix entiers :
		Case n°	 0	1	2	 3	4	5	 6	7	8	9
		Contenu	-1	3	7	-5	3	6	-7	0	3	6
	J'espère que vous avez capté, parce que c'est une notion de base, très souvent utilisée en C (on en reparle un peu plus bas de toute façon).

	Nous venons de voir comment seront stockés nos arguments, maintenant il va nous falloir une instruction pour parcourir notre tableau... Et là, nous verrons deux façons de faire : une qui reproduit notre manière humaine de faire, et une autre, plus optimisée pour un ordinateur.

		Première possibilité de parcours du tableau : for

	for permet de créer une boucle qui sera exécutée jusqu'à ce qu'une certaine condition soit satisfaite.
	Sa syntaxe est la suivante :
		for ( initialisation ; condition d'arrêt ; incrémentation ) { code }

	Voici un exemple plus concret, pour parcourir notre tableau de 0 (première case) à argc-1 (dernière case, puisqu'on commence à 0) :
		  for (i = 0; i < argc; i++) { code }

	i++ signifie tout simplement i=i+1 qu'on pourrait également écrire i+=1. Comme vous pouvez le constater, le C dispose de nombreuses manières d'écrire la même chose : adoptez celle qui vous convient, mais sachez que le code généré par un compilateur rencontrant "i++" générera un code plus optimisé qu'en rencontrant une addition généraliste de la forme "i+=1", qui est elle-même plus optimisable que "i=i+1". Et oui, le C est un langage ou le compilateur ET le programmeur (donc, vous) coopèrent afin de produire un code extrêmement rapide et compact... En un mot, optimisé ! C'est pourquoi il est nécessaire de bien comprendre les différentes structures du langage, car si elles sont mal utilisées, cela finira inévitablement en "assertion failed" ou autre "access violation"...

	Par exemple, que ce passerait-il si vous tentiez d'accéder à la case n°10 d'un tableau n'en disposant que 9 ? Je vous laisse deviner... tic, tac, tic, tac, ding ! mon oeuf à la coque est à point :) Ah oui... Eh bien, vous verriez ceci sous linux : "segmentation fault, core dumped" et sous windows : "access violation" ou... rien (windows et la sécurité, une notion des plus vagues) ! Le fait que windows aie un comportement aussi aléatoire pourrait vous arranger, mais produit en fait une sorte de bug aléatoire que vous pourriez bien passer des heures à traquer, donc je vous recommande chaudement de faire attention au code que vous écrivez, en particulier dans les accès aux tableaux ! Souvenez vous bien qu'un tableau commence TOUJOURS à la case 0 et non pas 1 !

	Bon avec tout ce que nous venons de dire et ce que nous avons vu dans la section 1, vous devriez maintenant pouvoir écrire le programme dont nous parlions précédemment ! La solution est en dessous, mais si vous souhaitez progresser, il vaudrait mieux d'abord que vous essayiez par vous même...

		Solution avec une foucle for
	#include <stdio.h>
	int main (int argc, char** argv) {
		/* on déclare un entier pour savoir à quelle case du tableau on est */
		int i;
		/* on parcourt le tableau argv de 0 à argc-1 et on affiche son contenu */
		for (i = 0; i < argc; i++) puts (argv[i]);
		/* fin du programme */
		return 0;
	}

	C'est ce que vous aviez écrit ? Bravo ! Non ? Alors relisez tout avant de continuer, vous avez probablement mal compris un passage.

	Nous allons maintenant compiler notre programme, comme vu dans la section 2 :
		gcc -Wall -W args.c -o args.exe

	Ce qui nous donne un fichier args.exe, que nous allons nous empresser de tester :
		args

	Ben quoi, çà fait que çà ? Et oui, on ne lui a pas passé d'arguments, donc il n'a affiché que son nom... Essayons autre chose :
		args c'est de la balle ce programme !

	Et voilà, c'est tout de suite mieux :) Pas mal en une ligne de code non (le for fait tout le boulot) ? Néanmoins, montrez ce code à n'importe quel puriste du C et vous vous en prendrez plein la gueule, car ce n'est pas très optimisé et on peut faire une ligne beaucoup plus compacte et élégante :) En C et contrairement à Rocco, plus c'est court et mieux c'est !

		Deuxième possibilité de parcours du tableau : while

	Comme for, while permet d'exécuter une boucle jusqu'à ce qu'une condition soit vraie. Voici sa syntaxe :
		while (condition) { code }

	Maintenant que vous connaissez cette instruction et son utilisation, je vous laisse chercher comment adapter l'exemple précédent pour utiliser while et non for...

		Solution avec une foucle while
	#include <stdio.h>
	int main (int argc, char** argv) {
		/* on déclare un entier pour savoir à quelle case du tableau on est, et on démarre à la case 0 */
		int i = 0;
		/* tant qu'on n'a pas dépassé la dernière case, afficher le contenu de la case courante puis passer à la suivante */
		while (i < argc) puts (argv[i++]);
		/* fin du programme */
		return 0;
	}

	C'était simple non ? Vous n'aviez peut être pas écrit exactement çà, mais du moment que votre programme fonctionne, c'est le principal ! J'ai juste souhaité vous fournir en solution une version très optimisée (donc, très concise) : comparez les tailles des commentaires et des lignes de code correspondantes, y a pas photo...

=====================================================================
	4) Conclusion et points importants à retenir
=====================================================================

	Nous voici arrivés à la fin de ce premier article qui, je l'espère, vous aura été profitable ! Si vous avez aimé cet aperçu de la puissance du C (sa concision !), alors vous attendrez probablement avec impatience le prochain article, dédié à l'interaction avec l'utilisateur, à la modularité et aux Makefile, ces fabuleux fichiers qui permettent au programme de gérer une compilation optimisée sans trop se prendre la tête :)

	Sinon, bah... Il vous reste Visual Basic :]

	N'hésitez pas à envoyer toutes vos remarques, critiques et autres à Alex Ploit qui me fera suivre ! Après tout, la Family est là pour vous et c'est à vous de la faire évoluer (positivement, tant qu'à faire) ! Et non, vos courriers n'iront pas dans /dev/null :)

	Pour finir, voici un résumé de ce qui a été vu :
		- un programme commence toujours par la fonction main
		- la fonction main admet deux formes : int main (void) et int main (int argc, char** argc)
		- on peut afficher du texte avec puts
		- quitter la fonction main avec un return termine le programme
		- les accolades permettent de délimiter la portée d'une fonction, d'une boucle ou d'un traitement
		- une instruction ne se termine pas forcèment à la fin d'une ligne, il faut utiliser un ;
		- on peut utiliser des commentaires pour expliquer ce que fait notre code
		- on peut utiliser for et while pour parcourir des tableaux
		- un tableau commence toujours à la case 0
		- on peut incrémenter une variable avec i++, i+=1 et i=i+1
		- on peut décrémenter une variable avec i--, i-=1 et i=i-1
		- il est préférable de compiler un programme avec gcc -Wall -W pour éviter les erreurs

=====================================================================
	5) Dédicaces et remerciements
=====================================================================

	Un salut tout particulier à toutes les personnes travaillant au monde libre, et qui produisent des outils d'une qualité inégalée, bravo les gars !

	Et bien sûr, dédicace à toute la Family, pourvu qu'on continue encore longtemps :]

	A la prochaine !
					Alex Centrique