1. Livres & vidéos
  2. Langage C
  3. Introduction
Extrait - Langage C Maîtriser la programmation procédurale (avec exercices pratiques) (3e édition)
Extraits du livre
Langage C Maîtriser la programmation procédurale (avec exercices pratiques) (3e édition)
2 avis
Revenir à la page d'achat du livre

Introduction

Objectif : apprendre à programmer avec le C

L’objectif premier est d’apprendre à programmer, ce qui signifie maîtriser la conception algorithmique avec au minimum un langage de programmation. À cet égard, le langage C se montre particulièrement efficace pour apprendre et commencer, même si, détaché du C++, il n’aborde pas la dimension objet. De nombreux étudiants en informatique, maintenant intégrés dans un travail, nous affirment que les bases de C leur ont donné la possibilité de s’adapter assez rapidement à d’autres langages et à de nombreuses situations de développement.

Initialement influencé par le langage Fortan, le langage C, à l’origine de nombreux autres langages, procure un moyen d’acquérir un savoir-faire fondamental en programmation informatique qui va permettre de circuler facilement dans la plupart des autres techniques et langages de programmation. Le C se trouve en effet à la racine de langages très utilisés. Il est inclus dans le langage C++ et directement relié aux langages C#, Objective-C, Java, PHP, Perl, Python et JavaScript. Il se retrouve aussi indirectement dans le langage Ruby, qui relève de Perl, Python et C++, le langage Scala associé à Java, et le langage Groovy qui passe par Ruby, Perl et Python.

Alors que le C++, langage objet appuyé sur sa base en C, offre des possibilités de structuration et d’architectures des données extrêmement puissantes, le C, quant à lui, fournit plutôt une extraordinaire fluidité pour l’algorithmique. Par là, le C demeure un langage modulable, souple, flexible, finalement vif et moderne (même si des améliorations apportées par le C++ sont bien venues), très adapté aux traitements de nombreuses situations complexes.

Avec juste quelques définitions syntaxiques qui tiennent sur une page A4 lorsqu’elles sont maîtrisées, ce langage permet d’écrire une infinité de programmes. C’est un peu comme les notes en musique : 13 notes en tout pour une infinité de musiques.

Comme un instrument de musique, le C demande très vite une certaine forme de virtuosité. En effet, la plupart des programmes C partent de rien. Mis à part l’utilisation de bibliothèques C spécialisées, le C n’offre pas de composants préprogrammés, comme souvent dans des environnements objet. Il s’agit quasiment toujours de tout programmer soi-même. Cette obligation offre une grande liberté d’action et d’imagination et elle est très formatrice. L’apprenant est obligé de comprendre toutes les étapes de la conception d’un programme, même simple. Il s’agit pour lui de se confronter à la difficulté réelle et fondamentale de la programmation, y compris avec des premiers programmes réalisés en console, sans bibliothèques graphiques ou autres.

Contenu

Ce livre traite du langage C standard, basé sur la norme ISO/IEC 9899:2018 (C17). Bien que la norme C23 (ISO/IEC 9899:2024) soit disponible, au moment où nous écrivons elle n’est pas encore largement prise en charge par les compilateurs et n’apporte que des modifications mineures. Le code présenté est donc portable, sauf en cas d’utilisation de bibliothèques spécifiques comme Windows.h, qu’il faudra remplacer par des équivalents pour MacOS ou Linux.

Nous recommandons Visual Studio (version Community gratuite) comme environnement de développement, mais d’autres options sont possibles, notamment Code::Blocks (open source) ou Clion (JetBrains). Visual Studio Code peut également être utilisé, mais nécessite l’ajout manuel d’un compilateur. Pour simplifier, nous privilégions Visual Studio et Code::Blocks, tous deux fournis avec un compilateur intégré.

Le parcours proposé commence par l’installation de l’environnement de développement, suivie de l’apprentissage des types de données et des instructions de base nécessaires à la conception d’algorithmes.

L’ouvrage aborde ensuite des concepts avancés comme la récursivité, l’implémentation de listes chaînées dynamiques et les arbres binaires.

Avec de nombreux exemples, expérimentations, précisions et exercices variés, ce livre vise à offrir à chaque lecteur les moyens de construire son propre parcours, selon ses besoins, difficultés et intérêts.

Librairies graphiques

Nous pouvons actuellement conseiller deux librairies graphiques :

  • Allegro 5, une librairie écrite en C pour la création de jeux vidéo. Les sites officiels sont http://alleg.sourceforge.net/ et https://www.allegro.cc/. Allegro est une très bonne librairie graphique, très puissante et complète. La communauté est active. Cependant, la prise en main n’est pas forcément évidente pour un débutant et actuellement il y a en ligne peu de documentation en français (une documentation est disponible sur le site http://www.developpez.com).

  • SFML, une librairie en C++. C’est une excellente librairie avec une documentation en ligne très fournie. Cependant, si le C est inclus dans le C++, l’inverse n’est pas vrai, ce qui peut nuire à son utilisation pour des programmes C. Cela dit, il existe un binding pour le C : CSFML. Le site officiel est http://www.sfml-dev.org.

Nous avons souhaité rester centrés sur l’étude du C dans cet ouvrage et les exemples de code utiles à nos explications sont plus clairs en mode console. Toutefois le dernier chapitre montre comment utiliser la bibliothèque Allegro 5 pour s’initier à la création de jeux en C.

Public visé

Cet enseignement est donné en premier cycle dans une école d’informatique, en général sur deux semestres de la licence. Un premier semestre est consacré à la maîtrise des fondamentaux inclus dans le langage C ainsi qu’à la programmation graphique de jeux vidéo. Lors du semestre suivant, nous approfondissons la question des pointeurs en nous orientant plutôt cette fois sur la programmation objet en C++. Le C est inclus dans le C++, cependant la logique de programmation fondée sur les fonctions s’avère différente de celle fondée sur des architectures d’objets et nous considérons qu’il est essentiel pour nos étudiants de ne pas se retrouver enfermés dans une seule approche de la programmation. Ce second semestre porte ainsi davantage sur une nouvelle approche de la programmation que sur un nouveau langage, le C++ réinterprétant et par là transformant les possibilités du C.

L’ouvrage peut être adapté à différents publics et différents niveaux en école d’ingénieurs, comme à l’université. Récemment, il a permis d’animer des ateliers « geeks » de création numérique mis en place au sein d’une médiathèque. Il s’agissait d’un public d’amateurs créatifs avec des niveaux allant de la 6e à bac +3 !

Les modules sur la récursivité et les listes apparaissent surtout comme des modules d’approfondissement. Ils constituent un bagage de culture informatique aujourd’hui devenu spécialisé et utile lorsqu’il est corrélé avec des projets très avancés en C ou même C++.

Organisation du livre

1. Chapitres

Les dix premiers chapitres couvrent l’apprentissage du langage C et les bases de l’algorithmique :

1. Installer un environnement : choix et mise en place du compilateur.

2. Variables simples : types, affectation et affichage.

3. Les opérations : manipulation de variables et opérations de base.

4. Les contrôles des blocs d’instructions : organisation du code, sauts, branchements, boucles et fonctions, avec introduction au style de programmation.

5-6. Les structures et Les tableaux : structures et tableaux, ouvrant la voie à une conception plus élaborée.

7. Les unions : utilisation pour simuler un héritage C++ et possibilité de composer un tableau contenant des éléments potentiellement de types différents.

8. Concevoir et réaliser un programme : gestion de projets sur plusieurs fichiers et bibliothèques. 

9. Les pointeurs : références, allocation dynamique et structures de données non natives (listes chaînées).

10. Introduction aux fichiers : manipulation en mode texte et binaire.

Deux chapitres d’approfondissement suivent, explorant la récursivité et l’implémentation des listes chaînées, piles, files et arbres binaires, essentiels pour la programmation graphique et la structuration avancée des données en C et C++.

Le dernier chapitre propose une introduction au graphisme et à la création de jeux vidéo avec l’utilisation de la bibliothèque Allegro 5.

2. Des questions pour faciliter apprentissage et synthèse

Dans chaque chapitre, les sections essentielles à notre formation en licence d’informatique sont la plupart du temps précédées d’une série de questions. Nous utilisons ces questions en cours avec deux objectifs.

Tout d’abord, nous avons constaté que répondre à des questions que les étudiants ne se posaient pas était la plupart du temps inutile. Au mieux, à la fin du cours les étudiants se posent les questions auxquelles répondait le cours et il n’y a plus qu’à recommencer le cours. Alors, commencer par poser les questions auxquelles répond le cours, en demandant aux étudiants de se débrouiller pour trouver seuls des réponses, rend le cours ensuite plus attractif et plus efficace. L’important pour apprendre semble être tout d’abord de se poser question.

Ensuite, s’il est vrai que la connaissance du C, une fois acquise, peut se réduire à une feuille A4, cet apprentissage passe en général par beaucoup d’hésitations et de tâtonnements. La liste de questions que nous fournissons donne alors un moyen de ne pas se perdre ni de se sentir découragé par l’épaisseur du livre. Ces questions, finalement, constituent la trame d’une synthèse et d’un résumé. Comme une sorte de file d’Ariane, elles permettent d’aller à l’essentiel et d’utiliser le livre, qui ne se lit pas comme un roman. 

Effectivement, il y a dans cet ouvrage beaucoup de précisions qui ne peuvent pas être abordées en cours. C’est pourquoi le livre se veut aussi une référence à laquelle il est possible de revenir dans certaines situations, lorsque ces précisions deviennent nécessaires.

3. Solutions des exercices

Les solutions aux exercices sont téléchargeables depuis l’onglet Compléments. Toutes les solutions ne sont pas données, compte tenu du nombre très important d’exercices proposés. Certains, en effet, peuvent être des sujets de projets et il serait dommage de devoir s’en priver le cas échéant. Mais en ce qui concerne les solutions, d’une façon générale, attention à bien en user. Pourquoi ? Parce que l’essentiel est de commencer par se poser un problème. Sans problème, il n’y a pas de solution, et une solution qui vient sans que l’on se soit posé sérieusement un problème ni que l’on ait cherché activement ne sert à rien. C’est pire que de ne pas avoir de solution du tout. L’illusion d’avoir compris peut maintenir dans celle d’avoir la compétence de trouver alors qu’on ne l’a pas. Il faut aborder un problème, chercher une solution et acquérir les compétences requises pour trouver et faire soi-même. Le concepteur finit toujours par obtenir la technique dont il a besoin pour réaliser ce qu’il a décidé de réaliser.

Comment apprendre à programmer ?

Du point de vue pédagogique, la réponse sur laquelle nous insistons est : par la pratique. Dans ce domaine, le savoir théorique est indissociable de l’expérimentation répétée à travers des réalisations diverses et variées et de différents niveaux. Avec le temps, la pratique seule permet d’acquérir une intuition spécifique qui permet plus facilement de repérer ou de poser des problèmes et de trouver des solutions ensuite.

1. Comprendre n’est pas savoir faire

Pour les débutants confrontés à un langage de programmation, en général, comprendre ne suffit pas. Il faut aussi savoir faire, et comprendre n’est pas savoir faire.

Pour prendre une image, c’est un peu la même situation pour apprendre à jouer d’un instrument de musique. Si un professeur ou un tutoriel vidéo vous explique comment jouer de la guitare, vous pouvez comprendre les explications, mais vous n’êtes pas devenu guitariste ni compositeur de musique. Devenir guitariste suppose de nombreuses heures de travail sur son instrument. Devenir compositeur et avoir des idées de morceaux de musique ou d’arrangements musicaux supposent également beaucoup de questionnements et de travail. C’est la même chose en programmation et en conception informatique.

Écrire un programme nécessite un minimum d’expertise des outils fondamentaux, c’est-à-dire un minimum d’expérience. En effet, l’expert est celui ou celle qui a de l’expérience, et l’expérience conduit à la maîtrise. La maîtrise, même incomplète, permet de faire des hypothèses de réalisation. Elle permet d’identifier et de poser les problèmes à résoudre afin d’inventer des solutions. En effet, trouver une solution pour résoudre un problème revient souvent à créer cette solution. Et il s’agit d’un processus d’élaboration qui nécessite de l’intuition, de la recherche et de la créativité.

C’est pourquoi, dans la perspective de savoir-faire, le livre propose trois parcours parallèles, complémentaires et solidaires entre eux :

  • Un parcours théorique. Le fonctionnement des outils fondamentaux est exposé, expliqué et illustré par des exemples de code.

  • Un parcours expérimental. Nous fournissons également une rubrique "Expérimentation". Il s’agit de code commenté qui résume les explications données. Ce sont des petits programmes que l’on peut lire, réécrire et modifier afin de bien les comprendre et d’en acquérir la maîtrise. Ces programmes exposent, par exemple, des résolutions algorithmiques de problèmes pour la conception de jeux.

  • Un parcours de mise en pratique. Chaque section est suivie d’une section "Mise en pratique" dédiée. Ce sont des exercices que nous avons essayé de beaucoup diversifier. Chaque exercice est une invitation. Il n’est pas nécessaire de les faire tous, en choisir deux ou trois par section suffit. L’important est de se mettre en marche.

Si une idée de programme à faire vous vient pendant l’un de ces parcours ou à l’occasion d’un exercice, surtout faites-le !

2. Trois niveaux de difficulté

Lors de l’apprentissage, trois niveaux de difficulté apparaissent : la maîtrise des outils, la résolution de problèmes, la conception de programmes. Pour chaque niveau, des objectifs spécifiques sont atteints avec de la pratique et des exercices variés pour les points plus difficiles.

a. Maîtriser les outils

L’étudiant en programmation ressemble à un élève de CE1 qui apprend à lire et à écrire. Un élève de CE1 est captivé par le décodage d’une phrase et ce n’est qu’après qu’il l’a décodée qu’il peut commencer à en comprendre le sens, de sorte qu’à un moment donné il a lu la phrase mais il ne l’a pas encore comprise, et s’il est interrogé à ce moment sur le sens de la phrase, il ne sait quoi répondre. De même, un étudiant débutant en programmation a besoin de temps et d’énergie pour décoder le langage de l’algorithme d’un programme simple, comprendre chacun de ses mécanismes et leur enchaînement (tests, boucles, fonctions, etc.).

Mais, à l’issue de cela, il n’a pas nécessairement saisi le fonctionnement du programme et son résultat. La compréhension du résultat, qui s’appuie sur l’effort de décodage, vient après. C’est pourquoi plus le décodage est immédiat et moins il demande d’efforts, et plus la compréhension du fonctionnement de l’algorithme et de son résultat sont rapides. C’est l’objectif de la maîtrise des outils.

Par outils, nous entendons les concepts fondamentaux de la programmation et de l’algorithmique tels qu’ils sont implémentés dans le langage C. Ils ne sont pas nombreux et, sans entrer dans les détails, nous en dénombrons neuf : il y a les variables simples, les opérations, les sauts (if, else), les branchements (switch), les boucles (while, do-while, for), les fonctions, les variables ensembles (structures et tableaux), les variables pointeurs et c’est tout. Mais avec cela, il est possible d’écrire tout ce que l’on veut, y compris un système d’exploitation comme Unix (qui est à l’origine du langage C).

À ce niveau des outils de base, nous proposons de :

  • comprendre ces outils,

  • connaître leur fonctionnement et être capable de les faire tourner dans sa tête afin de pouvoir anticiper leurs comportements dans un programme,

  • savoir lire et interpréter du code où ils apparaissent,

  • savoir écrire du code pour les mettre soi-même en œuvre.

À ce premier niveau, il n’y a pas véritablement de conception. Il s’agit par exemple de faire une boucle dans un programme de test pour voir comment elle marche et comprendre son fonctionnement.

L’acquisition des réflexes de décodage ne doit pas faire perdre de vue l’importance de monter en niveau. Il est certes nécessaire de faire des exercices et d’expérimenter, mais il est nécessaire aussi d’avancer. Surinvestir exagérément sur l’acquisition d’un point particulier peut se montrer contreproductif : lassitude, découragement, perte de temps s’il s’agit d’un détail sans importance, etc. En fait, très souvent, ce qui est étudié dans un chapitre est nécessaire dans les chapitres suivants, de sorte que nous le retrouvons dans les chapitres qui suivent. Il est parfois préférable de continuer d’avancer et de retravailler sur tel ou tel point passé en le retrouvant en avant sur la route plutôt que de s’arrêter dans sa progression. De toute façon, tout ce qui est fondamental devra être acquis. L’important est de pouvoir finalement réaliser un projet personnel conséquent en C.

b. Résoudre un problème

Au niveau suivant, il s’agit d’entrer dans une dynamique de résolution de problème et de conception algorithmique. Il ne suffit plus de comprendre les outils, il faut encore être capable de les utiliser pour faire quelque chose même de simple. En gros, vous avez un marteau, un tournevis, une scie, des clous, des vis, un crayon, une règle et différentes planches, il faut maintenant créer un meuble, par exemple une armoire.

À ce niveau d’entrée dans la conception, nous proposons :

  • d’acquérir la capacité de lire et de comprendre un algorithme ;

  • d’être capable de repérer une structure de données adéquate ;

  • d’être capable d’inventer et d’écrire un algorithme.

Tout ce qui s’écrit et qui est exécutable par la machine passe par l’élaboration d’un algorithme qui est une suite finie d’opérations en vue de l’accomplissement d’une tâche, à savoir une suite réfléchie d’instructions pour faire faire quelque chose à la machine. Notons que l’algorithmique donne lieu à de véritables découvertes et références scientifiques. Il y a un patrimoine d’algorithmes et certains portent le nom de leurs auteurs, par exemple l’algorithme de Bresenham pour le tracé de droites.

C’est dire qu’à ce niveau la difficulté peut être très grande. Mais, heureusement, il y a aussi des choses très accessibles et, selon notre philosophie, chacun fera ce qu’il pourra avec les défis qu’il se fixera et des exercices choisis.

c. Concevoir un programme

Le dernier niveau que nous envisageons est celui de la composition d’un programme complet faisant plusieurs milliers de lignes de code et réunissant de nombreuses résolutions d’énigmes, de nombreux algorithmes. Ce peut être un jeu vidéo classique ou toute autre réalisation. Il s’agit de réaliser un projet conséquent qui permettra de :

  • comprendre un programme complet,

  • savoir concevoir un programme complet.

À ce niveau, les programmes peuvent réunir de nombreux fichiers sources et faire appel à de nombreuses librairies. Des problématiques de méthodologie se posent pour l’écriture du code et pour la gestion d’un projet réalisé éventuellement en équipe. Un éventail d’étapes de travail apparaît. Elles relient l’idée initiale au programme réel qui marche plus ou moins sans bogue et fait plus ou moins ce que l’on attend de lui à la plus ou moins grande satisfaction du client. C’est la conduite et la gestion de projet informatique. Notre objectif ici n’est pas d’approfondir ces questions, mais, nous l’espérons, de préparer à en comprendre les fondements et les enjeux.

3. Un apprentissage non linéaire

D’une façon générale, l’apprentissage n’est pas réductible à une mécanique simple. La clarté se fait progressivement, un peu comme un brouillard qui se lève. Au départ, on ne distingue rien, et petit à petit, au fur et à mesure que le brouillard se dissipe, des formes apparaissent de plus en plus précises et claires. Il arrive que certains se sentent perdus au départ comme devant un mur lisse sur lequel ils n’ont aucune prise, peut-être un peu la même impression que dans un pays étranger en entendant une langue que l’on ne maîtrise pas bien et que l’on s’efforce de comprendre. De ce fait, l’apprentissage n’est pas frontal, direct, facile à planifier. Avec le temps, des expérimentations et des exercices, des pôles de clarté, de compréhension et de savoir-faire s’affirment et se relient doucement entre eux. Et même si des zones de flou perdurent, la persévérance finit toujours par en venir à bout. Les étapes de l’acquisition de la compétence de concevoir et réaliser un programme informatique dépendent des personnes et du travail consenti. Le talent ici n’est pas d’être brillant, c’est plutôt d’aimer programmer, parce que celui ou celle qui aime programmer y passe plus de temps que les autres et devient meilleur pour cette raison.

En cas de découragement, pensez que c’est un univers fini. Le nombre des outils fondamentaux est limité. Il ne va pas augmenter. C’est un point rassurant. De plus, le langage C fournit un passeport efficace pour tous les langages ensuite et cet apprentissage est un bon placement.

4. La programmation comme écriture

Si l’on considère d’un point de vue un peu philosophique que tout langage a un pouvoir architectural et permet de structurer une pensée, la programmation apparaît alors comme une écriture particulière pour exprimer spécifiquement des idées et des points de vue sur pratiquement tous les sujets. Elle s’apprend aussi bien comme un langage que comme un jeu, un art ou une science. C’est dire la richesse des approches possibles.

S’il y a des amateurs de jeux vidéo, du point de vue de la programmation, le jeu est de programmer le jeu. La résolution d’énigmes est véritablement passionnante, et plus le niveau monte, plus c’est difficile et intéressant. L’ordinateur est un robot dont vous êtes le cerveau. Vous devez entrer « dans la peau » de la machine pour lui donner la forme de ce que vous voulez. Cela suppose :

  • de comprendre la machine,

  • d’avoir des idées, de la volonté et des objectifs à lui faire atteindre,

  • de pouvoir traduire vos souhaits en des termes exécutables par la machine via une réflexion méthodique, la maîtrise d’un langage de programmation, l’écriture du programme qui inclut différentes étapes de conception.