Vous êtes sur la page 1sur 28

UNIVERSITE HASSAN 1er

FACULTE DES SCIENCES ET TECHNIQUES DE SETTAT


DEPARTEMENT DE MATHEMATIQUES ET INFORMATIQUE

Introduction au cours d’algorithmique et progra


mmation
Introduction au cours d’algorithmique et programmation
Introduction
à la programmation en Langage C

Sofia DOUDA

Année 2010/2011
Année 2010/2011 1

Introduction au langage C

Petite histoire du C
Le langage C a été mis au point par D. Ritchie et B. W. Kernighan au début des années 70. Leur but
était de permettre de développer un langage qui permettrait d'obtenir un système d'exploitation de
type UNIX portable. D. Ritchie et B.W. Kernighan se sont inspirés des langages B et BCPL, pour
créer un nouveau langage: le langage C.
La première définition de ce langage a été donnée dans leur livre commun "The C programming
language".

Toutefois, suite à l'apparition de nombreux compilateurs C, l'ANSI (abréviation de American


National Standards Institute) a décidé de normaliser ce langage pour donner ce que l'on appelle le
C-ANSI. Suite à cette norme, Ritchie et Kernighan ont sorti une deuxième édition du livre en
intégrant les modifications apportées par l'ANSI.

Les atouts du C
Le langage C reste un des langages les plus utilisés actuellement. Cela est dû au fait que le langage
C est un langage comportant des instructions et des structures de haut niveau (contrairement à
l'assembleur par exemple) tout en générant un code très rapide grâce à un compilateur très
performant.
Un des principaux intérêts du C est que c'est un langage très portable. Un programme écrit en C en
respectant la norme ANSI est portable sans modifications sur n'importe quel système d'exploitation
disposant d'un compilateur C : Windows, UNIX, VMS (système des VAX) ou encore OS/390 ou
z/Os (l'OS des mainframes IBM).
La rapidité des programmes écrits en C est en grande partie due au fait que le compilateur
présuppose que le programmeur sait ce qu'il fait: il génère un code ne contenant pas de vérifications
sur la validité des pointeurs, l'espace d'adressage, etc. Ainsi, les programmes en C sont très
compacts.
De plus, une des caractéristiques du C est qu'il est un langage "faiblement typé" : les types de
données qu'il manipule sont très restreints, et proches de la représentation interne par le processeur :
par exemple, le type 'Chaîne de caractères' n'existe pas en C. A l'inverse, comparer un entier et un
caractère a un sens en C car un caractère est bien représenté en interne par le processeur par une
valeur de type entier (le code ASCII ou le code EBCDIC).

Caractéristiques du langage C
Le fichier source
Le fichier source d'un programme écrit en langage C est un simple fichier texte dont l'extension est
par convention .c.
Ce fichier source doit être un fichier texte non formaté, c'est-à-dire un fichier texte dans sa plus
simple expression, sans mise en forme particulière ou caractères spéciaux (il contient uniquement
les caractères ASCII de base).

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 2

Lorsque le programme est prêt à être essayé, il s'agit de le compiler (le traduire en langage
machine).
De nombreux compilateurs C existent: sous les systèmes de type UNIX par exemple, le compilateur
C est fourni en standard, si bien que la programmation en langage C est aisée sous ce type de
système. La compilation sous UNIX se fait par la ligne de commande suivante:
cc fichier.c

Les différentes étapes de la vie d’un programme en langage C


On distingue quatre étapes :
- l’édition
- la compilation
- l’édition de liens
- l’exécution

L’édition
Il s’agit de la phase de saisie, éventuellement de modifications, du texte du programme. Elle se fait
de façon classique en mémoire centrale, avec des facilités de sauvegarde sur disque dur.
Le terme de programme source est réservé au texte placé en mémoire et le terme fichier source est
utilisé pour désigner ce même texte lorsqu’il sera placé dans un fichier disque.

La compilation
Cette étape consiste à traduire en langage machine l’ensemble du texte constituant le programme.
Elle pourra porte, soit sur un programme source (situé en mémoire centrale), soit sur un fichier
source (situé sur disque).
L’une des originalités du langage C réside dans l’existence d’un ″préprocesseur″. Il permet au
programmeur d'inclure des fichiers source dans d'autres fichiers source (directive #include), de
définir des macros (directive #define), et de procéder à des compilations conditionnelles.

La directive #include
Le rôle de cette directive est de recopier le contenu d'un fichier dans le fichier courant. On l'emploie
généralement pour inclure les en-têtes de bibliothèques, telles que les fonctions mathématiques
(<math.h>) ou les fonctions d'entrée/sortie standard (<stdio.h>). Cette directive peut s’appliquer
également à des fichiers de votre cru. Cela peut s’avérer utile, par exemple pour écrire une seule
fois les déclarations communes à plusieurs fichiers sources différents.
Cette directive possède deux syntaxes semblables :
#include <nom_fichier>
recherche le fichier mentionné dans le répertoire « include »
#include ″nom_fichier″″
recherche d’abord le fichier mentionné dans le répertoire courant puis, en cas d’échec, dans le
répertoire ″include″

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 3

La directive #define
Elle offre deux possibilités :
- définition de symboles
- définition de macros

Définition de symboles
Une directive telle que :
#define nb_max 10
demande de substituer au symbole nb_max le texte 5, et ceci à chaque fois que ce symbole
apparaîtra dans la suite du fichier source.
#define entier int
Placée en début de programme, permettra d’écrire « ne français » les déclarations de variables
entières. Ainsi, par exemple, ces instructions :
entier a,b ;
entier *p ;
seront remplacées par :
int a,b ;
int *p ;

Voici quelques derniers exemples vous montrant comment résumer en un seul mot une instruction
C:
#define bonjour printf(″bonjour ″)
#define affiche printf(″resultat %d\n″,a)
#define ligne printf(″\n″)

Définition de macros
La définition de macros ressemble à la définition de symboles mais elle fait intervenir la notion de
paramètres.
Par exemple, avec cette directive :
#define carre(a) a*a
le préprocesseur remplacera dans la suite, tous les textes de la forme :
carre(x) dans lesquels x représente en fait un symbole quelconque par : x*x :
Par exemple :
carre(z) deviendra z*z
carre(valeur) deviendra valeur*valeur

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 4

carre(12) deviendra 12*12


La macro précédente ne disposait que d’un seul paramètre, mais il est possible d’en faire intervenir
plusieurs en les séparant, classiquement, par des virgules.
Par exemple, avec :
#define diff(a,b) a-b
diff(x,z) deviendrait x-z
diff(valeur+9,n) deviendrait valeur+9-n

Les définitions peuvent s’imbriquer. Ainsi, avec les deux définitions précédente, le texte :
diff(carre(p),carre(q))
sera, dans un premier temps, remplacé par : diff(p*p,q*q) puis, dans un deuxième temps, par :
p*p-q*q.

Remarque : il faut ajouter des parenthèses pour éviter des erreurs inattendues :
Exemple :
#define DOUBLE(x) x+x

DOUBLE(a)/b
Le texte généré par le préprocesseur sera le suivant :
a+a/b
ce qui différent de (a+a)/b.
Ce problème est lié aux priorités relatives des opérateurs et peut être résolu en introduisant des
parenthèses dans la définition de la macro. Ainsi, avec :
#define DOUBLE(x) ((x)+(x))

L’édition de liens
Le module objet crée par la compilation, bien que constitué d’instructions en langage machine,
n’est pas directement exécutable. Il lui manque pour cela les différents modules objets
correspondants aux fonctions (de la bibliothèque) appelées par votre programme.
C’est le rôle de l’éditeur de liens que de réaliser cette incorporation de modules.
Ces modules peuvent être obtenus par l’éditeur de liens de deux manières :
- Par simple recopie de fichiers d’extension obj,
- par recherche dans fichier d’extension lib, lequel regroupe en fait plusieurs modules objets ayant
trait à un même domaine (par exemple maths.lib contient tous les modules objets correspondants
aux routines mathématiques).
Le résultat de l’édition de liens est un programme exécutable.

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 5

Aspect d'un programme en C


Un programme écrit en langage C, comporte une fonction principale appelée main() renfermant les
instructions qui doivent être exécutées. Celles-ci sont comprises entre des accolades qui suivent le
nom de la fonction.
Un programme C de base ressemblera donc à ceci :
main()
{ printf("Ceci est votre premier programme");
}

Typologie
La manière d'écrire les choses en langage C a son importance.
Le langage C est par exemple sensible à la casse (en anglais case sensitive), cela signifie qu'un
nom contenant des majuscules est différent du même nom écrit en minuscules. Ainsi, les
spécifications du langage C précisent que la fonction principale doit être appelée main() et non
Main() ou MAIN().

Ajout de commentaires
/*Voici un commentaire!*/
En plus des symboles /* et */, fonctionnant un peu comme des parenthèses, le symbole // permet de
mettre en commentaire toute la ligne qui la suit (i.e. les caractères à droite de ce symbole sur la
même ligne.
Il convient toutefois d'utiliser préférablement la notation /* */ que //, car c'est beaucoup plus joli et
plus propre.

Les types de données


Les données manipulées en langage C sont typées, c'est-à-dire que pour chaque donnée que l'on
utilise (dans les variables par exemple) il faut préciser le type de donnée, ce qui permet de connaître
l'occupation mémoire (le nombre d'octets) de la donnée ainsi que sa représentation
• des nombres: entiers (int) ou réels, c'est-à-dire à virgules (float)
• des pointeurs (pointer): permettent de stocker l'adresse d'une autre donnée, ils "pointent"
vers une autre donnée

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 6

Type de donnée Signification Taille (en octets) Plage de valeurs acceptée


Char Caractère 1 -128 à 127
unsigned char Caractère non signé 1 0 à 255
short int Entier court 2 -32768 à 32767
unsigned short Entier court non 2 0 à 65535
int signé
int Entier 2 (sur processeur 16 bits) -32768 à 32767
4 (sur processeur 32 bits) -2147483648 à 2147483647
unsigned int Entier non signé 2 (sur processeur 16 bits) 0 à 65535
4 (sur processeur 32 bits) 0 à 4294967295
long int Entier long 4 -2 147 483 648 à 2 147 483 647
unsigned long Entier long non 4 0 à 4 294 967 295
int signé
float flottant (réel) 4 3.4*10-38 à 3.4*1038
double flottant double 8 1.7*10-308 à 1.7*10308
long double flottant double long 10 3.4*10-4932 à 3.4*104932

Créer un type de donnée


Il est possible en C de définir un nouveau type de données grâce au mot clé typedef. Celui-ci admet
la syntaxe suivante:
typedef Caracteristiques_du_type Nom_du_type

• Caracteristiques_du_type représente un type de données existant (par exemple float, short
int, ...)
• Nom_du_type définit le nom que vous donnez au nouveau type de donnée
Ainsi l'instruction suivante crée un type de donnée Ch calqué sur le type char
typedef char Ch

Conversion de type de données


conversion implicite: une conversion implicite consiste en une modification du type de donnée
effectuée automatiquement par le compilateur.
Exemple :
int x;
x = 8.324;
x contiendra après affectation la valeur 8
• conversion explicite: une conversion explicite (appelée aussi opération de cast) consiste en
une modification du type de donnée forcée. Cela signifie que l'on utilise un opérateur dit de cast
pour spécifier la conversion. L'opérateur de cast est tout simplement le type de donnée, dans lequel
on désire convertir une variable, entre des parenthèses précédant la variable.

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 7

• int x;
• x = (int)8.324;
x contiendra après affectation la valeur 8

Les variables du langage C


Le concept du langage C
Une variable est un objet repéré par son nom, pouvant contenir des données, qui pourront être
modifiées lors de l'exécution du programme. Les variables en langage C sont typées, c'est-à-dire
que les données contenues dans celles-ci possèdent un type, ainsi elles sont donc stockées dans la
mémoire et occupent un nombre d'octets dépendant du type de donnée stockée.
En langage C, les noms de variables peuvent être aussi long que l'on désire, toutefois le compilateur
ne tiendra compte que des 32 premiers caractères. De plus, elles doivent répondre à certains
critères:
• un nom de variable doit commencer par une lettre (majuscule ou minuscule) ou un "_" (pas
par un chiffre)
• un nom de variables peut comporter des lettres, des chiffres et le caractère _ (les espaces ne
sont pas autorisés)
• Les noms de variables ne peuvent pas être les noms suivants (qui sont des noms réservés):
 auto  register, return
 break  short, signed, sizeof, static, struct, switch
 case char const continue  typedef
 default do double  union, unsigned
 else enum extern  void, volatile
 float for  while
 goto
 if, int
 long

Nom de variable correct Nom de variable incorrect Raison


Variable Nom de Variable comporte des espaces
Nom_De_Variable 123Nom_De_Variable commence par un chiffre
nom_de_variable cpp@mailcity.com caractère spécial @
nom_de_variable_123 Nom-de-variable signe - interdit
_707 goto nom réservé

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 8

La déclaration de variables
Pour pouvoir utiliser une variable, il faut la définir, c'est-à-dire lui donner un nom, mais surtout un
type de donnée à stocker afin qu'un espace mémoire conforme au type de donnée qu'elle contient
lui soit réservé.
Une variable se déclare de la façon suivante:
type Nom_variable;
ou bien s'il y a plusieurs variables du même type:
type Nom_variable1, Nom_variable2, ...;

Affectation d'une donnée à une variable


Pour stocker une donnée dans une variable que l'on a initialisée, il faut faire une affectation, c'est-à-
dire préciser la donnée qui va être stockée à l'emplacement mémoire qui a été réservé lors de
l'initialisation.
Pour cela on utilise l'opérateur d'affectation "=" :
Nom_variable = donnée;
Exemple :
char caractere;
Pour stocker le caractère B dans la variable que l'on a appelée Caractere, il faudra écrire:
Caractere = 'B';

Initialisation d'une variable


On peut affecter une valeur initiale à la variable lors de sa déclaration, on parle alors d'initialisation:
type Nom_de_la_variable = donnee;
Par exemple:
float T = 125.36;

Portée (visibilité) des variables


Selon l'endroit où on déclare une variable, celle-ci pourra être accessible (visible) de partout dans le
code ou bien que dans une portion confinée de celui-ci (à l'intérieur d'une fonction par exemple), on
parle de portée (ou visibilité) d'une variable.
Variable globale : c’est une variable déclarée dans le code même, c'est-à-dire à l'extérieur de toute
fonction ou de tout bloc d'instruction, elle est accessible de partout dans le code (n'importe quelle
fonction du programme peut faire appel à cette variable).
Lorsque l'on déclare une variable à l'intérieur d'un bloc d'instructions (entre des accolades), sa
portée se confine à l'intérieur du bloc dans lequel elle est déclarée.
• Une variable déclarée au début du code, c'est-à-dire avant tout bloc de donnée, sera globale,
on pourra alors les utiliser à partir de n'importe quel bloc d'instruction

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 9

Une variable locale : est déclarée à l'intérieur d'un bloc d'instructions (dans une fonction ou une
boucle par exemple) et aura une portée limitée à ce seul bloc d'instruction, c'est-à-dire qu'elle est
inutilisable ailleurs.

Définition de constantes

Constantes non typées :


#define _Pi 3.1415927
remplacera tous les identifiants "_Pi" (sans les guillemets) par la valeur 3.1415927, sauf dans les
chaînes de caractères:
resultat = _Pi * sin(a); //-> remplacé
resultat = _Pi+1; //-> remplacé
_Pi = 12; //-> remplacé MAIS génère une erreur
resultat = _PiPo; //-> pas remplacé
printf("pi = _Pi "); //-> pas remplacé

Constantes non typées :


const int max = 10;

Les opérateurs du langage C


Les opérateurs sont des symboles qui permettent de manipuler des variables, c'est-à-dire effectuer
des opérations, les évaluer, ...
On distingue plusieurs types d'opérateurs:
• les opérateurs de calcul
• les opérateurs d'assignation
• les opérateurs d'incrémentation
• les opérateurs de comparaison
• les opérateurs logiques
• (les opérateurs bit-à-bit)
• (les opérateurs de décalage de bit)

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 10

Les opérateurs de calcul


Les opérateurs de calcul permettent de modifier mathématiquement la valeur d'une variable
Opérateur Dénomination Effet Exemple Résultat (avec x valant 7)
+ opérateur d'addition Ajoute deux valeurs x+3 10
- opérateur de soustraction Soustrait deux valeurs x-3 4
* opérateur de Multiplie deux valeurs x*3 21
multiplication
/ plus: opérateur de Divise deux valeurs x/3 2.3333333
division
= opérateur d'affectation Affecte une valeur à x=3 Met la valeur 3 dans la variable x
une variable

Les opérateurs d'incrémentation


Ce type d'opérateur permet de facilement augmenter ou diminuer d'une unité une variable. Ces
opérateurs sont très utiles pour des structures telles que des boucles, qui ont besoin d'un compteur
(variable qui augmente de un en un).
Un opérateur de type x++ permet de remplacer des notations lourdes telles que x=x+1 ou bien x+=1

Opérateur Dénomination Effet Syntaxe Résultat (avec x valant 7)


++ Incrémentation Augmente d'une unité la variable x++ 8
-- Décrémentation Diminue d'une unité la variable x-- 6

Les opérateurs d'assignation


Ces opérateurs permettent de simplifier des opérations telles que ajouter une valeur dans une
variable et stocker le résultat dans la variable. Une telle opérations s'écrirait habituellement de la
façon suivante par exemple: i=i+2
I=i+k peut être écris i+=k
De même vous pourrez remplacer:
a = a*b par a*=b
n = n << 3 par n <<=3
D’une manière générale, C permet de condenser les affectations de la forme :
valeur = valeur opérateur expression
en :
valeur opérateur=expression
Cette possibilité concerne tous les opérateurs binaires arithmétiques et de manipulation de bits.
Voici la liste complète de tous ces nouveaux opérateurs nommés ″opérateurs d’affectation élargie″ :
+=, -=, *=, /=, %=, |=, ^=, &=, <<=, >>=.
L'opérateur d'affectation = renvoie aussi une valeur, qui est celle de la variable après affectation.
Cela permet notamment de faire des affectations en cascade:

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 11

a = b = c = 1;
ce qui correspond à :
a = (b = (c = 1));
Les opérateurs de comparaison
Opérateur Dénomination Effet Exemple Résultat
(avec x valant 7)
== opérateur d'égalité Compare deux valeurs et x==3 Retourne 1 si X est
A ne pas confondre avec vérifie leur égalité égal à 3, sinon 0
le signe d'affectation (=)
< opérateur Vérifie qu'une variable est x<3 Retourne 1 si X est
d'infériorité stricte strictement inférieure à une inférieur à 3, sinon 0
valeur
<= opérateur Vérifie qu'une variable est x<=3 Retourne 1 si X est
d'infériorité inférieure ou égale à une inférieur ou égal à 3,
valeur sinon 0
> opérateur de Vérifie qu'une variable est x>3 Retourne 1 si X est
supériorité stricte strictement supérieure à une supérieur à 3, sinon 0
valeur
>= opérateur de Vérifie qu'une variable est x>=3 Retourne 1 si X est
supériorité supérieure ou égale à une supérieur ou égal à 3,
valeur sinon 0
!= opérateur de Vérifie qu'une variable est x!=3 Retourne 1 si X est
différence différente d'une valeur différent de 3, sinon 0

Les opérateurs logiques (booléens)


Ce type d'opérateur permet de vérifier si plusieurs conditions sont vraies:

Opérateur Dénomination Effet Syntaxe


|| OU logique Vérifie qu'une des conditions est réalisée ((condition1)||(condition2))
&& ET logique Vérifie que toutes les conditions sont réalisées ((condition1)&&(condition2))
! NON logique Inverse l'état d'une variable booléenne (retourne la (!condition)
valeur 1 si la variable vaut 0, 0 si elle vaut 1)

(Les opérateurs bit-à-bit)


Opérateur Dénomination Effet Syntaxe Résultat (avec x valant
7)
& ET bit-à-bit Retourne 1 si les deux bits 9 & 12 8 (1000)
de même poids sont à 1 (1001 &
1100)
| OU bit-à-bit Retourne 1 si l'un ou l'autre 9 | 12 13 (1101)
des deux bits de même poids (1001 | 1100)
est à 1 (ou les deux)
^ OU bit-à-bit Retourne 1 si l'un des deux bits 9 ^ 12 5 (0101)
exclusif de même poids est à 1 (mais pas les (1001 ^ 1100)
deux)

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 12

L’opérateur & permet d’accéder à une partie des bits d’une valeur en ″masquant″ les autres. Par
exemple, si n est de type int, l’expression :
n & 0x000F
permet de ne prendre en compte que les quatre bits de droite de n.
De même n & 0x8000 permet d’extraire le ″bit de signe″ de n.
Voici un exemple de programme qui décide si un entier est pair ou impair, en examinant
simplement le dernier bit de sa représentation binaire.
void main()
{
int n ;
printf(″donner un entier : ″) ;
scanf(″%d″,&n) ;
if (n & 0x0001==1)
printf(″%d est impair\n″,n) ;
else printf(″%d est pair\n″,n) ;
}

Les opérateurs de décalage de bit


Opérateur Dénomination Effet Syntaxe Résultat (avec
x valant 7)
<< Décalage à gauche Décale les bits vers la gauche 6 << 1 12 (1100)
(multiplie par 2 à chaque décalage). (110 << 1)
Les zéros qui sortent à gauche sont perdus,
tandis que des zéros sont insérés à droite
>> Décalage à droite avec Décale les bits vers la droite 6 >> 1 3 (0011)
conservation du signe (divise par 2 à chaque décalage). (0110 >> 1)
Les zéros qui sortent à droite sont perdus,
tandis que le bit non-nul de poids plus fort
est recopié à gauche

L’opérateur conditionnel
Considérons la structure de choix :
if (a > b) max = a ;
else
max = b ;

peut être remplacée par :

max = a > b ? a : b

L’expression figurant à droite de l’opérateur d’affectation est en fait constituée de 3 (a > b, a et b)


qui sont les 3 opérandes de l’opérateur conditionnel, lequel se matérialise par 2 symboles
séparés : ? et : .

D’une manière générale, cet opérateur évalue la première expression qui joue le rôle d’une
condition. Comme toujours en C, celle-ci peut être en fait de n’importe quel type type.

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 13

Les expressions et les instructions


Expressions :
La formation des expressions est définie par récurrence :
Les constantes et les variables sont des expressions.
Les expressions peuvent être combinées entre elles par des opérateurs et former ainsi des
expressions plus complexes.
Les expressions peuvent contenir des appels de fonctions et elles peuvent apparaître comme
paramètres dans des appels de fonctions.
Exemples:
i=0
i++
X=pow(A,4)
printf(" Bonjour !\n")
a=(5*x+10*y)*2
(a+b)>=100
position!=limite

Instructions :
Une expression comme i=0 ou i++ ou printf(...) devient une instruction, si elle est suivie
d'un point-virgule.
Exemples:
i=0;
i++;
X=pow(A,4);
printf(" Bonjour !\n");
a=(5*x+10*y)*2;
Évaluation et résultats
En C toutes les expressions sont évaluées et retournent une valeur comme résultat:
(3+4==7) retourne la valeur 1 (vrai)
A=5+6 retourne la valeur 8
Comme les affectations sont aussi interprétées comme des expressions, il est possible de profiter de
la valeur rendue par l'affectation:
((A=cos(X)) == 0.5)

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 14

Les priorités des opérateurs


L'ordre de l'évaluation des différentes parties d'une expression correspond en principe à celle que
nous connaissons des mathématiques.
Exemple
Supposons pour l'instruction suivante: A=5, B=10, C=1
X = 2*A+3*B+4*C;
L'ordinateur évalue d'abord les multiplications:
2*A ==> 10 , 3*B ==> 30 , 4*C ==> 4
Ensuite, il fait l'addition des trois résultats obtenus:
10+30+4 ==> 44
A la fin, il affecte le résultat général à la variable:
X = 44

Priorité d'un opérateur


On dit alors que la multiplication a la priorité sur l'addition et que la multiplication et l'addition ont
la priorité sur l'affectation.
Si nous voulons forcer l'ordinateur à commencer par un opérateur avec une priorité plus faible, nous
devons (comme en mathématiques) entourer le terme en question par des parenthèses.
Exemple
Dans l'instruction:
X = 2*(A+3)*B+4*C;
L'ordinateur évalue d'abord l'expression entre parenthèses, ensuite les multiplications, ensuite
l'addition et enfin l'affectation. (En reprenant les valeurs de l'exemple ci-dessus, le résultat sera 164)
Entre les opérateurs que nous connaissons jusqu'ici, nous pouvons distinguer les classes de priorités
suivantes:
Classes de priorités

Priorité 1 (la plus forte): ()


Priorité 2: ! ++ --
Priorité 3: */%
Priorité 4: +-
Priorité 5: < <= > >=
Priorité 6: == !=
Priorité 7: &&
Priorité 8: ||
Priorité 9 (la plus faible): = += -= *= /= %=

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 15

Les structures conditionnelles


On appelle structure conditionnelle les instructions qui permettent de tester si une condition est
vraie ou non. Ces structures conditionnelles peuvent être associées à des structures qui se répètent
suivant la réalisation de la condition, on appelle ces structures des structures de boucle
La notion de bloc
Une expression suivie d'un point-virgule est appelée instruction. Voici un exemple d'instruction :
a++;
Lorsque l'on veut regrouper plusieurs instructions, on peut créer ce que l'on appelle un bloc, c'est-à-
dire un ensemble d'instructions (suivies respectivement par des point-virgules) et comprises entre
les accolades { et }.
Les instructions if, while et for peuvent par exemple être suivies d'un bloc d'instructions à
exécuter...
L'instruction if
La syntaxe de cette expression est la suivante:
if (condition réalisée) {
liste d'instructions;
}
Remarques:
• la condition doit être entre des parenthèses
• il est possible de définir plusieurs conditions à remplir avec les opérateurs ET et OU (&& et
||)
Par exemple l'instruction suivante teste si les deux conditions sont vraies
if ((condition1)&&(condition2))
L'instruction suivante exécutera les instructions si l'une ou l'autre des deux conditions est vraie :
if ((condition1)||(condition2))
• s'il n'y a qu'une instruction, les accolades ne sont pas nécessaires...
• les instructions situées dans le bloc qui suit else sont les instructions qui seront exécutées si
la ou les conditions ne sont pas remplies
L'instruction if ... else
La syntaxe de cette expression est la suivante:
if (condition réalisée)
{ liste d'instructions }
else { autre série d'instructions }
Il est possible de faire un test avec une structure beaucoup moins lourde grâce à la structure
suivante:
(condition) ? instruction si vrai : instruction si faux
Remarques:
• la condition doit être entre des parenthèses

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 16

• Lorsque la condition est vraie, l'instruction de gauche est exécutée


• Lorsque la condition est fausse, l'instruction de droite est exécutée
• En plus d'être exécutée, la structure ?: renvoie la valeur résultant de l'instruction exécutée.
Ainsi, cette forme ?: est souvent utilisée comme suit :
• position = ((enAvant == 1) ? compteur+1 : compteur-1);

L'instruction switch
L'instruction switch permet de faire plusieurs tests de valeurs sur le contenu d'une même variable.
Ce branchement conditionnel simplifie beaucoup le test de plusieurs valeurs d'une variable, car
cette opération aurait été compliquée (mais possible) avec des if imbriqués. Sa syntaxe est la
suivante:
switch (Variable) {
case Valeur1: Liste d'instructions;
break;
case Valeur2: Liste d'instructions;
break;
case Valeurs...: Liste d'instructions;
break;
default: Liste d'instructions;
}

Les boucles
Les boucles sont des structures qui permettent d'exécuter plusieurs fois la même série d'instructions
jusqu'à ce qu'une condition ne soit plus réalisée...
L'instruction while
L'instruction while représente un autre moyen d'exécuter plusieurs fois la même série d'instructions.
La syntaxe de cette expression est la suivante:
while (condition) {
liste d'instructions;
}
Cette instruction exécute la liste d'instructions tant que la condition est réalisée.
La condition de sortie pouvant être n'importe quelle structure conditionnelle, les risques de boucle
infinie (boucle dont la condition est toujours vraie) sont grands, c'est-à-dire qu'elle risque de
provoquer un plantage du programme en cours d'exécution.

Exemple :
Considérons le programme suivant :
#include <stdio.h>
void main()
{int n, som ;
som=0 ;
while (som < 100)

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 17

{ printf(″donner un nombre : ″) ;
scanf(″%d″,&n) ;
som=som + n ;
}
printf(″somme obtenue : %d″, som) ;
}

La construction « while (som < 100) » répète l’instruction qui suit (ici un bloc d’instructions) tant
que la condition mentionnée est vraie. La condition est examinée avant chaque parcours de la
boucle. Une telle boucle peut très bien n’être parcourue aucune fois si la condition est fausse dés
qu’on l’aborde comme le montre l’exemple suivant :

int i ;
i= 13 ;
while (i<10)
{ printf(″i=%d \n″,i) ;
i++ ; }
Dans cet exemple, la condition est fausse dés le début.

La boucle do { } while
Il peut arriver que l'on ne veuille effectuer le test de continuation qu'après avoir exécuté
l'instruction. Dans ce cas, on utilise la boucle do { } while. Sa syntaxe est
do
{ instruction
} while (expression );
Ici, instruction sera exécutée tant que expression est non nulle. Cela signifie donc que instruction
est toujours exécutée au moins une fois. Par exemple, pour saisir au clavier un entier entre 1 et 10 :
int a;
do
{ printf("\n Entrez un entier entre 1 et 10 : ");
scanf("%d",&a);
}
while ((a <= 0) || (a > 10));

La boucle for
La syntaxe de cette expression est la suivante:
for (initialisation du compteur; condition ; modification du compteur)
{liste d'instructions; }
Par exemple :

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 18

for (i=1; i<6; i++) {


printf("%d ", i);
}
Cette boucle affiche 5 fois la valeur de i, c'est-à-dire vous aurez à l’écran : 1 2 3 4 5
Autres exemples :
 for(i=0;i<10;i++) exécute 10 fois la boucle (i de 0 à 9)
 for(i=0;i<=10;i++) exécute 11 fois la boucle (i de 0 à 10)
 for(i=1;i<10;i++) exécute 9 fois la boucle (i de 1 à 9)
 for(i=1;i<=10;i++) exécute 10 fois la boucle (i de 1 à 10)

D’une manière générale, nous pouvons dire que :


for( expression1 ; expression2 ; expression3) instruction ;
est équivalent à :
expression1 ;
while (expression2)
{ instruction ;
expression3 ;
}
Chacune des trois expressions est facultative. Ainsi, ces constructions suivantes sont équivalentes :

i=1 ;
for (i=1; i<6; i++) i=1 ;
for ( ; i<6; )
printf("%d ", i); for ( ; i<6; i++)
⇔ ⇔ { printf("%d ", i);
printf("%d ", i);
i++ ; }

Notez que lorsque expression2 est absente, elle considérée comme vraie.
La richesse de la notion d’expression en C permet de grouper plusieurs actions dans une expression.
Ainsi :
j=1 ; k=5 ; i=0 ; j=1 ;k=5 ;
for(i=0, j=1, k=5 ;… ; …) for(i=0 ;… ; …) for( ;… ; …)
…. ; ⇔ ⇔
…. ; …. ;

De même :

for(i=1, printf(″Début\n″) ; printf(″Fin de tour\ n″) , i<=5; i++)


{instruction ;}

est équivalent à :

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 19

printf(″Début\n″) ;
for(i=1; i<=5; i++)
{ printf(″Fin de tour\ n″) ;
instruction ;
}
printf(″Fin de tour\ n″) ;

Les constructions :
for( ; ; ) ;
for ( ; ; ) { }
sont syntaxiquement correctes. Elles représentent des boucles infinies de corps vide. En pratique,
elles ne présentent aucun intérêt.
Par contre, cette construction
for( ; ; )
instruction ;
est une boucle à priori infinie dont on pourra éventuellement sortir par une instruction break.

Saut inconditionnel
x=1;
while (x<=10) {
if (x == 7) {
printf("Division par zéro!");
continue;
}
a = 1/(x-7);
printf("%f", a);
x++;
}

Il y a une erreur dans ce programme: lorsque x est égal à 7, le compteur ne s'incrémente plus, il
reste constamment à la valeur 7, il aurait fallu écrire:
x=1;
while (x<=10) {
if (x == 7) {
printf("division par 0");
x++;
continue;
}
a = 1/(x-7);
printf("%f", a);
x++;
}

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 20

Arrêt inconditionnel
for (x=1; x<=10; x++) {
a = x-7;
if (a == 0) {
printf("division par 0");
break;
}
printf("%f", 1/a);
}

L’instruction goto
for (x=1; x<=10; x++) {
a = x-7;
if (a == 0) goto etiq;
printf("%f", 1/a);
}
etiq : printf("division par 0"); /* fin */

L'instruction ″goto etiq″ permet d'effectuer un saut jusqu'à l'instruction etiq.

Les fonctions en C
Une fonction est un sous-programme qui permet d'effectuer un ensemble d'instruction par simple
appel de la fonction dans le corps du programme principal.
Les fonctions permettent d'exécuter dans plusieurs parties du programme une série d'instructions,
cela permet une simplicité du code et donc une taille de programme minimale.
Une fonction peut faire appel à elle-même, on parle alors de fonction récursive (il ne faut pas
oublier de mettre une condition de sortie au risque sinon de ne pas pouvoir arrêter le programme...).
La déclaration d'une fonction
type_retourne nom_fonction(type1 argument1, type2 argument2, ...)
{ liste d'instructions }
Remarques:
• type_retourne représente le type de valeur que la fonction est sensée retourner (char, int,
float,...)
• Si la fonction ne renvoie aucune valeur, on la fait alors précéder du mot-clé void
• Si aucun type de donnée n'est précisé, le type int est pris par défaut
• le nom de la fonction suit les mêmes règles que les noms de variables:
 le nom doit commencer par une lettre
 un nom de fonction peut comporter des lettres, des chiffres et les caractères _ et &
(les espaces ne sont pas autorisés!)
 le nom de la fonction, comme celui des variables est sensible à la casse
(différenciation entre les minuscules et majuscules)
• Les arguments sont facultatifs, mais s'il n'y a pas d'arguments, les parenthèses doivent rester
présentes
• Il ne faut pas oublier de refermer les accolades

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 21

• Le nombre d'accolades ouvertes (fonction, boucles et autres structures) doit être égal au
nombre d'accolades fermées
• La même chose s'applique pour les parenthèses, les crochets ou les guillemets

Appel de fonction
Pour exécuter une fonction, il suffit de faire appel à elle en écrivant son nom (une fois de plus en
respectant la casse) suivie d'une parenthèse ouverte (éventuellement des arguments) puis d'une
parenthèse fermée: nom_fonction();

Prototype d'une fonction


Le prototype d'une fonction est une description d'une fonction qui est définie plus loin dans le
programme. On place donc le prototype en début de programme (avant la fonction principale
main()).
Un prototype de fonction ressemble donc à ceci:
type__renvoye nom_fonction(type_argument1, type_argument2, ...);
Le prototype est une instruction, il est donc suivi d'un point-virgule.
Voici quelques exemples de prototypes:
void Affiche_car(char, int);
int Somme(int, int);

Les arguments d'une fonction


Il est possible de passer des arguments à une fonction, c'est-à-dire lui fournir une valeur ou le nom
d'une variable afin que la fonction puisse effectuer des opérations sur ces arguments ou bien grâce à
ces arguments.
Le passage d'arguments à une fonction se fait au moyen d'une liste d'arguments (séparés par des
virgules) entre parenthèses suivant immédiatement le nom de la fonction.

Exemple 1:
void affiche(int n) ; void affiche(int n)
void main() {
{ int a=10, b=20 ; printf(″valeur : %d\n ″,n) ;
affiche(a) ; }
affiche(b) ;
affiche(a+b) ;
}

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 22

Exemple 2 :
void affiche_trois(int a, int b, float x) ; void affiche_trois(int a, int b, float x)
{
void main() printf(″%d %d %f\n ″,a, b, x) ;
{ int n, p; }
float x;
printf(″Donner deux entiers\n″) ;
scanf(″%d%d″,&n,&p) ;
printf(″Donner un réel\n″) ;
scanf(″%f″,&x) ;
affiche(n,p,x) ;
affiche(n+p, 5*n, x-20) ;
}

Fonctions fournissant un résultat


Exemple 1:

double somme(double u, double v) ; double somme(double u, double v) ;


void main() {
{double a, b , c, d , x, y; double s ;
a=1. ; b = 2. ; c=3. ; d= 4. ; s=u+v ;
x = somme(a, b) + 5 ; return(s);
printf(″x : %e\n ″, x) ; }
y = 3 * somme(c ,d);
printf(″y : %e\n″, y) ;
}

L’instruction return

double somme(double u, double v)


{return(u+v); }
L’instruction return peut apparaître à plusieurs reprises dans une fonction, comme dans cet
exemple:
double abssomme(double u, double v)
{double s ;
s=u+v ;
if (s>0) return(s);
else retrun(-s);
}

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 23

Les valeurs sont transmises par valeur

void echange(int a, int b) ; void echange(int a, int b)


{
void main() int c ;
{ printf(″début échange : %d %d\n″, a, b) ;
int n=10, p=20 ; c=a ;
printf(″avant appel : %d %d\n″,n, p) ; a=b ;
echange(n, p) ; b=c ;
printf(″après appel : %d %d\n″,n, p) ; printf(″fin échange : %d %d\n″, a, b) ;
} }

A l’écran vous aurez les résultats suivants :

avant appel : 10 20
début echange : 10 20
fin echange : 20 10
après appel : 10 20

Les variables globales

Exemple d’utilisation de variables globales

void message() ; A l’écran d’exécution, vous aurez :


int i ; / * variable globale */ Appel n° : 1
void main() Appel n° : 2
{ Appel n° : 3
for(i=1 ; i<=6 ; i++) Appel n° : 4
message(); Appel n° : 5
} Appel n° : 6
void message()
{
printf(″Appel n° : %d\n″,i) ;
}

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 24

Propriétés des variables globales

Portée
Les variables globales ainsi définies ne sont connues du compilateur que dans la partie du source
suivant leur déclaration. On dit que leur ″portée″ (ou encore leur ″espace de validité″) est limitée à
la partie du source qui suit leur déclaration.

Examinons l’exemple suivant :

…fct1(…) ;
… fct2(…) ;
void main()
{

}
int n ;
float x ;

fct1(..)
{
/* on peut utiliser n et x*/

}
…fct2(…)
{
/* on peut utiliser n et x*/

}

Les variables n et x sont accessibles aux fonctions fct1 et fct2, mais pas au programme principal (la
fonction main).
Pour des raisons de lisibilité du programme, on préférera regrouper les déclarations de toutes les
variables globales au début du source.

Classe d’allocation

Variables locales : automatiques ou statiques

A l’exception de l’exemple précédent, les variables que nous avions rencontrées jusqu’ici n’étaient
pas des variables globales. Plus précisément, elles étaient définies au sein d’une fonction (qui
pouvait être la fonction main). De telles variables sont dits ″locales″ à la fonction dans laquelle elles
sont déclarées.

La portée des variables locales

Les variables locales ne sont connues qu’à l’intérieur de la fonction où elles sont déclarées. Leur
portée est donc limitée à cette fonction.
Les variables locales n’ont aucun lien avec des variables globales de même nom ou avec d’autres
variables locales à d’autres fonctions.

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 25

Examinons l’exemple suivant :

void fct1() ;
int n ; /* variables globales */
void main()
{
int p ; /*variables locales*/

}
void fct1()
{
int n ; /*variables locales*/
int p ; /*variables locales*/

}

Les variables locales statiques


Il est toutefois possible de demander d’attribuer un emplacement permanent à une variable locale et
qu’ainsi sa valeur se conserve d’un appel au suivant. Il suffit pour cela de la déclarer à l’aide du
mot-clé : static

Examinons l’exemple suivant :

void fct() ; A l’écran de l’exécution, vous aurez :


void main() appel numéro : 1
{ appel numéro : 2
int n ; appel numéro : 3
for(n=1 ; n<=6 ;n++) appel numéro : 4
fct(); appel numéro : 5
} appel numéro : 6
void fct()
{
statitc int i;
i++;
printf(″appel numéro : %d\n″, i) ;
}

Le cas de fonctions récursives

Le langage C autorise la récursivité des appels de fonctions. Celle peut prendre deux aspects :
- récursivité directe : une fonction comporte, dans sa définition, au moins un appel à elle-
même,
- récursivité croisée : l’appel d’une fonction entraîne celui d’une autre fonction qui, à son
tour appelle la fonction initiale.
Exemple 1 :
Le factoriel peut être définie de deux manières:

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 26

Définition itérative
N ! = 1 si N = 0
Sinon N ! = 1 x 2 x … (N–1) x N
Définition récursive
Si N = 0 alors N != 1
Sinon N !=N x (N-1) !
Ainsi on peut écrire la fonction qui calcule le factoriel d’un nombre d’une manière récursive de la
manière suivante :
long factoriel(int n)
{
if (n <= 1) return (1);
else return (n * factoriel (n-1));
}

Exemple 2 : Prenons le cas de la suite de Fibonacci, définie par


U0 =0, U1=1
Un= Un-1+ Un-2 pour n > 1
On obtient donc la suite 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584,
4181, 6765, 10946,...
De même on peut écrire la fonction qui calcule la suite de fibonacci de la manière suivante:

int Fib(int n)
{ if (n == 0) return (0);
if (n==1) return(1);
else return (Fib (n-1) + Fib (n-2));
}

Nous allons essayer de le suivre sur le calcul de Fib(4).


Fib(4) -> Fib (3) + Fib (2)
-> (Fib (2) + Fib (1)) + Fib (2)
-> ((Fib (1) + Fib (1)) + Fib (1)) + Fib(2)
-> ((1 + Fib(1)) + Fib (1)) + Fib(2)
-> ((1 + 1) + Fib (1)) + Fib(2)
-> (2 + Fib(1)) + Fib(2)
-> (2 + 1) + Fib(2)
-> 3 + Fib(2)
-> 3 + (Fib (1) + Fib (1))
-> 3 + (1 + Fib(1))
-> 3 + (1 + 1)
-> 3 + 2
-> 5

Cours d’introduction à la programmation en Langage C Sofia Douda


Année 2010/2011 27

Le programme itératif pour le calcul de la suite Fibonacci est le suivant :


/* Fonction itérative qui calcule la suite de Fibonacci */

int Fib_iter(int n)
{ int u0,u1, u2;
int i;
if (n == 0) return (0);
if (n==1) return(1);
u0 = 0; u1 = 1;
for (i = 2; i <=n; ++i)
{u2=u0+u1;
u0=u1;
u1 = u2;
}
return (u2);
}

Cours d’introduction à la programmation en Langage C Sofia Douda

Vous aimerez peut-être aussi