7
Chapitre 1
Introduction
1.1 Références
Les livres et supports de cours sur le Langage C de Henri Garreta et Claude Delannoy
sont des références de premier choix pour apprendre les bases du langage. Ils sont facilement
accessibles sur internet. Ils sont bien plus détaillés que le présent support et vont souvent au-delà
de l’objet de ce cours. Toutefois, il plus que souhaitable de les consulter pour approfondir les
notions évoquées ici.
1.2 Algorithmique et Programmation
La programmation informatique est l’ensemble des activités qui permettent l’écriture des pro-
grammes informatiques. L’algorithmique désigne l’ensemble des activités logiques qui relèvent
des algorithmes. Ce mot vient du nom d’un mathématicien perse Abou Jafar Muhammad Ibn
Al-Khuwarizm qui au neuvième siècle, écrivit le premier ouvrage systématique sur la résolution
des équations linéaires et quadratiques. Un algorithme est une séquence d’actions (plus ou moins
simples) qui permet d’aller d’un état initial à un état final, le but. Un algorithme décrit une
démarche sous la forme d’une suite d’opérations, pour résoudre un problème donné. L’écriture
de cette démarche dans un langage de programmation constitue la brique élémentaire de la
programmation informatique. Les termes implémentation et codage sont souvent utilisés par
les informaticiens pour y faire référence. Il existe des milliers de langages de programmation
informatique : Pascal, Java, Fortran, C, C++, etc.
Ce sont des langages formels avec une syntaxe stricte qui permet d’éviter les ambiguı̈tés contrai-
rement au langage naturel. Ils peuvent être plus ou moins évolués. Le langage machine est le plus
basique. Le code d’un algorithme en langage machine n’est pas très lisible (compréhensible), il
traduit les opérations à effectuer au niveau de l’ordinateur. C’est une suite de 0 et 1 associée aux
instructions élémentaires exécutables par le microprocesseur. Le défaut majeur de ce type de
langage pour un informaticien, est sa non lisibilité qui nuit nécessairement à la compréhension
et la modification du code. Heureusement, il existe des langages plus évolués tels que l’Assem-
bleur qui est un peu plus lisible et assez souvent utilisé pour coder les instructions élémentaires
pour le microprocesseur. D’autres langages de niveau encore plus élevé sont largement utilisés.
Ils donnent un niveau de compréhension très élevé à toute personne maı̂trisant leur syntaxe.
Cependant, ces langages évolués ne sont pas adaptés pour une exécution directe du micropro-
cesseur des instructions élémentaires sous-jacentes. Une traduction en langage machine est donc
nécessaire. Cette opération dans le cas du langage C, se fait en deux étapes : la compilation et
l’édition de liens. La compilation traduit le code source (écrit en C) en langage machine dans un
fichier dit objet. Ce fichier peut contenir des trous qui sont des appels à d’autres programmes
8 1. Introduction
déjà existants. L’éditeur de liens associe le fichier objet de notre programme avec celui des
programmes appelés pour construire un unique fichier exécutable.
L’objet de ce cours est de s’initier à la syntaxe du langage C qui est un langage de program-
mation impérative : les instructions sont exécutées pour transformer l’état actuel du programme.
1.3 Présentation du langage
1.3.1 Un peu d’histoire
Le langage C a été mis au point par Ritchie et Kernighan au début des années 70. Leur
but était de développer un langage qui permettrait d’obtenir un système d’exploitation de type
UNIX portable.
Les opérations possibles sont limitées : les assignations, les branchements conditionnels, les
branchements inconditionnels, les bouclages.
La règle veut que tout apprentissage d’un langage informatique commence par le codage de
l’algorithme suivant :
Algorithme 1 : Affiche bonjour()
1 Entrées :
2 Sorties :
3 Afficher ”Bonjour !” à l’écran.
Algorithme 2 : Programme C : Afficher bonjour
1 #include < stdio.h >
2 int main()
3 {
4 printf(”Bonjour ! \n”) ;
5 return 0 ;
6 }
1.3.2 Représentation de l’information en mémoire centrale
La mémoire centrale peut être vue comme un tableau à une dimension dont le contenu des
cases (appelées bits) est une des deux valeurs 0 ou 1. Dans ce tableau, un indice (numéro) est
attribué à chaque paquet de 8 bits contigus (appelé octet). Cet indice représente l’adresse de
cet octet dans la mémoire et permet de le repérer. De ce fait, une donnée stockée en mémoire
est représentée sur au moins un octet.
Cependant, le nombre de données différentes qu’il est possible de représenter en binaire (suite
de 0 et 1) sur un octet est limité à 28 = 256. Aussi, une information peut être représentée sur
plusieurs octets.
Donc, pour repérer une information en mémoire centrale, il faut connaı̂tre l’adresse de son
premier octet et sa taille (i.e. le nombre d’octets sur lequel elle est représentée). La taille d’une
information est donnée par son type (sa nature). Ce dernier permet également de décoder correc-
tement sa représentation binaire en mémoire. En effet, une même suite de 0 et 1 sera interprétée
différemment selon qu’elle représente un entier naturel, un entier relatif, un caractère...
1.3. Présentation du langage 9
Algorithme 3 : Programme C : Structure d’un programme
1 # directives adressées au préprocesseur
2 déclarations (des objets qui seront manipulés)
3 int main()
4 {
5 déclarations (des objets qui seront manipulés)
6 instructions (les opérations à exécuter)
7 }
1.3.3 Structure d’un programme
Dans le cas général, un programme C se présente sous la forme de plusieurs fichiers sources
(avec l’extension .c) et fichiers d’en-tête (avec l’extension .h). L’intérêt de ce découpage du code
est tout d’abord de regrouper des parties du programme en fonction de leur finalité permettant
un maintien plus aisé. Mais plus encore, cela permet la compilation séparée des différentes
composantes et donc de ne pas reprendre totalement cette phase après chaque modification. Par
soucis de simplicité, nous nous plaçons ici dans le cas simple où tout le programme se trouve
dans un unique fichier source.
— Le fichier source contient des directives au préprocesseur (un programme qui procède à la
transformation du code avant la compilation) : souvent l’objectif est d’inclure le contenu
d’autres fichiers dans le fichier courant.
— Le fichier source contient des déclarations et des définitions de fonctions qui sont des sous-
programmes accomplissant une tâche déterminée qui rentre dans la résolution globale du
problème posé. En outre, le programme doit contenir une et une seule fonction main :
c’est le point d’entrée du programme.
— Le fichier source contient des déclarations des objets qui sont manipulés. Ces derniers,
de même que les données constantes, peuvent être de différents types : entiers, flottants,
caractères, chaı̂nes de caractères...
— Les opérations arithmétiques usuelles sont définies : +, *, -, /...
— Ils existent des mots réservés qui ne peuvent être utilisés pour nommer nos objets ou
fonctions : if, else, while, for, do, char, short, int, long, float, double, signed, unsigned,
switch, case, break, goto, default, continue, void, return, sizeof, struct, typedef, const,
static, union, enum, extern, auto, register, volatile.
— Les blancs (espaces, tabulations, fins de lignes) sont ignorés.
— Les commentaires /* Ceci est un commentaire */ sont également ignorés.
Le langage C n’étant pas directement exécutable pour le processeur, une phase de traduction
en langage machine, la compilation, est nécessaire. La compilation du fichier source génère un
nouveau fichier dit objet (avec l’extension .o). L’édition de liens rajoute le code objet des sous-
programmes pré-définis utilisés dans notre programme et crée un fichier exécutable autonome
(avec l’extension .exe). Les sous-programmes pré-définis sont des fonctions dont le code est déjà
rédigé et stocké dans des bibliothèques dans le but de faciliter la création d’un programme C.
Par exemple, l’affichage d’une chaı̂ne de caractères à l’écran peut se faire de manière très simple
en utilisant une fonction déjà existante, printf qui se trouve dans la bibliothèque stdio (standard
input/output). Pour ce faire, il est nécessaire de rédiger la directive au préprocesseur #include
< stdio.h > qui permet d’inclure le fichier stdio.h contenant les en-têtes des fonctions de cette
bibliothèque.