Vous êtes sur la page 1sur 84

Langage de Programmation: I

- Le Langage C -
Sommaire

 Histoire du langage C

1. Introduction au langage

2. Éléments de base (règles d’écriture, types…)

3. Les variables

4. Opérateurs et expressions

5. Les entrées-Sorties (printf, scanf)

6. Les structures de contrôle


Sommaire

7. Les objets structurés (tableaux statiques)

8. Les objets structurés (chainede caractères)

9. Complement sur Les pointeurs

10. Allocation dynamique de la mémoire

11. Les Fonctions

12. Les objets structurés (structures)

13. Liens utils


Histoire du C

 Origines
C a trois ancêtres : les langages CPL, BCPL et B.

CPL : (pour Combined Programming Language) a été conçu au début des


années 1960 - universités de Cambridge et de Londres. Fortement typé
mais trop complexe  disparition dans las année 70

BCPL : (pour Basic CPL) Cambridge en 1966 par Martin Richards. Version
siplifiée  Ecriture d’un 1er Compilateur et de divers systèmes
d’exploitations

B : Ken Thompson vers 1970 dans les laboratoires Bell  Version simplifiée
du BCPL
Histoire du C

C: développé par un collègue de Ken Thompson, Dennis Ritchie qui ajouta les
tableaux, les pointeurs, les nombres à virgule flottante, les structures...
1972 fut l'année de développement la plus productive et sans doute l'année
de baptême de C. En 1973, C fut suffisamment au point pour que 90% de
UNIX puisse être récrit avec.

- Une 1ère définition du langage est apparue en 1978 avec l’ouvrage de


Ritchie et Kernighan « The C programming language ».

- Son succès international a contribué à sa normalisation:


1- ANSI (American National Standard Institute
2- ISO (International Standadization Organisation
3- CEN (Comité Européen de Normalisation) en 1993
1. Introduction au langage C

- Le langage C est un langage de bas niveaux, dans le sens où il permet la


manipulation de données que manipulent les ordinateurs (Bit, octet, adresse) ≠
Langages évolués (Pascal, Fortran, ADA)

- Il est suffisamment général pour permettre de développer des application de


type scientifique ou de gestion basée sur l’accès aux bases de données (Word
et Excel sont écrits à partir de C ou C++)

- Il est un des 1ers langages offrant des possibilités de programmation modulaire:


Un programme peut être constitué de plusieurs module (module = fichier .c)
1. Introduction au langage C
- Un langage de programmation a pour finalité de communiquer avec la machine. Le
langage maternel de la machine n'utilise que deux symboles (0 et 1): c'est le langage
machine.

Exemple: le nombre 5 est reconnu par une machine par la succession des symboles 101
(c'est la représentation du nombre en base 2).

De même, les opérations qu'une machine est capable d'exécuter sont codées par des
nombres, c'est-à-dire une succession de 0 et 1. Par exemple, l'instruction Machine
00011010 0001 0010 demande à la machine d'effectuer l'opération 1+2.

Ce langage est le seul qui soit compris par l'ordinateur, Est-il alors le seul moyen pour
communiquer avec celui-ci???

Réponse : Non, utilisation du langage assembleur : add $1 $2

Il fut suivi par des langages plus sophistiqués et de plus en plus proche du langage
humain
1. Introduction au langage C

- La programmation structurée (Fortran, Pascal, C, Perl, Tcl ),


- La programmation structurée et modulaire (Ada, Modula),
- La programmation fonctionnelle (Lisp)
- La programmation logique (Prolog)
- La programmation objet (C++, Java, VB.net, C# …).

Compilateur
1. Introduction au langage C
Qu’est ce qu’un programme C?

C’est un texte écrit avec un éditeur de texte, respectant une certaine syntaxe et
stocké sous forme d'un ou plusieurs fichiers (généralement avec l'extension .c). A
l'opposé du langage assembleur, les instructions du langage C sont obligatoirement
encapsulées dans des fonctions et il existe une fonction privilégiée appelée main qui
est le point de départ de tout programme.

Exemple: main()
{
printf(’’Bonjour!’’);
}

Source.c
Compilation Objet.o Edition des liens Exécutable
2. Éléments de base
2.1 les fichiers include

Exemple:
# include <stdio.h>
main()
{
printf(’’Bonjour!’’);
}

La directive #include inclu le fichier stdio.h au programme avant la compilation (pour


pouvoir utiliser la fonction prédéfinie printf.

On parle alors de préproceseur


2. Éléments de base
2.2 les Commentaires

Exemple:
# include <stdio.h> //pour pouvoir utiliser la fonction printf
main()
{
printf(’’Bonjour!’’);
}
/*Ce programme imprime la chaine de
caractère ‘’Bonjour!’’ à l’écran*/
2. Éléments de base
2.3 Présentation de quelques instructions du langage C
2. Éléments de base
2.3 Présentation de quelques instructions du langage C

Exemple 2 :
2. Éléments de base
2.4 Les identificateurs

Les identificateurs servent à désigner les différents objets manipulés par le


programme:Variables, fonctions, …

- Commence nécessairement par une lettre


- une lettre majuscule est tenue pour différente de la lettre minuscule correspondante;
- Au plus 31 caractère
- Le caractère _ (appelé « blanc souligné ») est considéré comme une lettre ; il peut
donc figurer à n'importe quelle place dans un identificateur: _Total2, Prix_unit
2. Éléments de base
2.5 Les Types dans C

Les types de base du langage C se répartissent en 3 grande catégories en fonction


de la nature des informations qu’ils permettent de représenter:

 Nombres entiers (int)

 Nombres flottants (float ou double)

 Caractère (char): apparaît en C comme un cas particulier de int.

Ils peuvent être signés ou non signés : signed ou unsigned (unsigned int x;)
2. Éléments de base
a. Les Types Entiers

 short int ou short (entier sur 16 bits : - 32 768 à 32 767)


 int (entier sur 32 bits : - 2 147 483 648 à 2 147 483 647)

 long int ou long (entier sur 32 bits ou 64 bits, selon les machines)

Chacun des 3 peut être nuancé par l’utilisation du qualificatif unsigned pour ne

représenter que des nombres positifs:

Exemple: unsigned short x; x peut aller de 0 à 65 535

pas de bit réservé pour le signe

- C accepte les constantes entière en notation décimale, hexadécimale ou octale


2. Éléments de base
b. Les Types Flottants

Float : codé sur 4 octets avec 1 bit de signe, 23 bits de mantisse et 8 bits
d'exposant
Double : codé sur 8 octets avec 1 bit de signe, 52 bits de mantisse et 11
bits d'exposant
Long : codé sur 10 octets avec 1 bit de signe, 64 bits de mantisse et 15 bits
d'exposant

- C accepte les constantes flottante en notation décimale ou scientifique

3.5e+3 3500 2.43 -0.38 -.38 4. .27


2. Éléments de base
c. Le Type Char

En C, un caractère est un entier signé codé sur 1 octet


Notation des constantes caractères : ‘a’ , ‘$’ ..

Important: ‘a’ ≠ ‘’a’’

Il existe des caractères non imprimables, tel que le changement de ligne, de


Tabulation, … en voici un tableau récapitulatif
2. Éléments de base

NOTATION RESULTAT
\a cloche ou bip (alert ou audible bell)
\b Retour arrière (Backspace)
\f Saut de page (Form Feed)
\n Saut de Ligne (Line Feed)
\r Retour chariot (Carriage Return)
\t Tabulation horizontaLe (HorizontaL Tab)
\v Tabutation verticale (VerticaL Tab)
\\ \
\' ‘
\ '' ‘’
\? ?
2. Éléments de base
A propos du type booléen :

Pas de type booléen en C. Le type booléen est représenté par un entier. Il se comporte
comme la valeur booléenne vraie si cette valeur entière est non nulle.

Dans un contexte qui exige une valeur booléenne (comme les tests, par exemple), un
entier non nul équivaut à vrai et la valeur zero équivaut à faux
2. Éléments de base
2.6 Les Mots réservés

Les mots suivants sont réservés. Leur fonction est prévue par la syntaxe de C et ils ne
peuvent pas être utilisés dans un autre but :

auto break case char const continue default do

double else enum extern float for goto if

int long register return short signed sizeof static

struct switch typedef union unsigned void volatile while


3. Les Variables
3.1 Declaration
Char
Unsigned Short
Auto Signed Int
Register Const
long identificateur = expression
Static volatile Float
extern Double
Long double

Exemple: int x, y=0, z;


extern float a,b;
static unsigned short n=1000;
3. Les Variables
3.2 Les variables statiques locale

Le qualificatif static, placé devant la déclaration d'une variable locale, produit une
variable qui est:
-Pour sa visibilité , locale
-Pour sa durée de vie, statique (Permanente)
Elle n'est accessible que depuis l'intérieur du bloc ou elle est déclarée, mais elle est créée
au début du programme et elle existe aussi longtemps que dure l'exécution de celui-ci.

Exemple : void bizarre(void)


{ static int cpt = 1000; Appels consécutifs : 1000 1001 1002
printf("%d ", cpt);
cpt++; }
4. Opérateurs et Expressions
C dispose d'un important éventail d'opérateurs originaux d'affectation et
d'incrémentation.

4.1 Opérateurs arithmétiques en C

 Comme tous les langages, C dispose d'opérateurs classiques "binaires" , à


savoir l'addition (+), la soustraction (-), la multiplication (*) et la division (/), ainsi
que d'un opérateur "unaire" correspondant à l'opposé noté - (comme dans -n ou
-x+y).

 Les opérateurs binaires ne sont à priori définis que pour deux opérandes ayant
le même type parmi: int, long int, float, double, long double et ils fournissent
un résultat de même type que leurs opérandes.
4. Opérateurs et Expressions
4.1 Opérateurs arithmétiques en C

 De plus, il existe un opérateur de "modulo" noté % qui ne peut porter que sur
des entiers et qui fournit le reste de la division de son premier opérande par son
second. Par exemple, 11%4 vaut 3, 23%6 vaut 5

 Remarque: le quotient de deux entiers fournit un entier. Ainsi 5/2 vaut 2; en


revanche, le quotient de deux flottants (noté, lui aussi, /) est bien un flottant
(5.0/2.0 vaut bien approximativement 2.5).

Priorité des opérateurs :


les règles sont "naturelles" et rejoignent celles de l'algèbre traditionnelle
4. Opérateurs et Expressions

Conversions implicites :

 On peut écrire des expressions mixtes dans lesquelles interviennent des opérandes
de types différents:
Int n,p; float x; n*x + p
(int * float) + int
Conversion implicite: int  float ( float*float) + int
float + int
Même mécanisme : float + float  float

On parle de conversion d’ajustement de type: intlongfloatdoublelong double


4. Opérateurs et Expressions

Promotions numériques :

 On a vu que les opérateurs numériques ne sont pas définis pour le types char et
short :

C prévoit que toute valeur char ou short soit d’abord convertie en int.
short n,p; float x; n*x + p
(short * float) + short
Conversion systématique: ( int * float) + int
Conversion implicite : float * float + int
float + float  float
4. Opérateurs et Expressions
4.2 Opérateurs Relationnels

Comme tout langage, C permet de "comparer" des expressions à l'aide


d'opérateurs classiques de comparaison. exemple : 2*a > b +5

Par contre, C se distingue de la plupart des autres langages sur deux points:

1-le résultat de la comparaison est, non pas une valeur "booléenne" (on dit aussi
"logique") prenant l'une des deux valeurs vrai ou faux, mais un entier valant:
 0 si le résultat de la comparaison est faux,
 1 si le résultat de la comparaison est vrai.
Ainsi, la comparaison ci-dessus devient en fait une expression de type entier. Cela
signifie qu'elle pourra éventuellement intervenir dans des calculs arithmétiques;
4. Opérateurs et Expressions
4.2 Opérateurs Relationnels

2-les expressions comparées pourront être de type quelconque et seront soumises au


règles de conversion présentées précédemment.

Liste des opérateurs: < <= > >= == !=


même priorité > même priorité

Exemple: a < b == c < d  (a < b) == (c < d)

Remarque: les opérateurs relationnels sont moins prioritaires que les opérateurs
arithmétiques ( x+y < a+2  (x+y) < (a+2) )
4. Opérateurs et Expressions
4.3 Opérateurs Logiques

 C dispose de trois opérateurs logiques classiques: et (noté &&), ou (noté | |) et


non (noté ! ). Par exemple: (a<b) && (c<d) prend la valeur 1 (vrai) si les deux
expressions a<b et c<d sont toutes deux vraies ( de valeur 1), la valeur 0 (faux)
dans le cas contraire.

 Ces opérateurs acceptent n'importe quel opérande numérique, y compris les


types flottants, avec les règles de conversion implicite déjà rencontrées. à
condition de considérer que:
 0 correspond à faux,
 toute valeur non nulle correspond à vrai
4. Opérateurs et Expressions
4.3 Opérateurs Logiques

Exemples:
n et p sont des entiers, le compilateur accepte des expression telles que:
n && p n||p if ( !n )  if (n == 0)

Remarque1: l’opérateur ! a une priorité supérieur à celle de tous lés opérateurs


arithmétiques et relationnels. La négation de a==b serait !(a==b) et non
!a==b
Ne sera évaluée que si a<b
est vrai
Remarque2: l’opérateur | | est moins prioritaire que &&. Tous deux sont de priorité
inférieure aux opérateurs arithmétique et relationnels
a<b && c<d équivaut à (a<b) && (c<d)
4. Opérateurs et Expressions
4.4 Opérateur d’affectation ordinaire

 Nous avons déjà eu l'occasion de remarquer que : i = 5 était une expression qui
réalisait une action : l'affectation de la valeur 5 à i. Cet opérateur d'affectation (=)
peut faire intervenir d'autres expressions comme dans : c=b + 3

 Cet opérateur possède une associativité de droite à gauche : i = j = 5


4. Opérateurs et Expressions
4.5 Opérateurs d’incrémentation et de décrémentation ( ++ -- )

 ++ i : expression qui incrémente de 1 la valeur de i, et sa valeur est celle de i


après incrémentation

 si la valeur de i est 5, l'expression : n = ++i - 5 affectera à i la valeur 6 et à n la


valeur 1.
 n = i++ - 5 (n==0 , i++ vaut 5, i vaut 6)

 On dit que ++ est:


-un opérateur de pré incrémentation lorsqu'il est placé à gauche
-un opérateur de post incrémentation lorsqu'il est placé à droite
4. Opérateurs et Expressions
4.5 Opérateurs d’incrémentation et de décrémentation ( ++ -- )

Priorité:

3 * i++ * j-- + k++ équivaut à 3 * (i++) * (j--) + (k++)

La priorité élevée de ces opérateurs unaires permet d’écrire des expression


assez compliquées sans qu’il soit nécessaire d’employer des ( )

4.6 Opérateurs d’affectation élargie:


i=i+k  i+=k a=a*b  a*=b i=i-k  i-=k a=a/b  a/=b
4. Opérateurs et Expressions
4.7 L’opérateur de CAST :

Exemple: n=10, p=3;


(double) (n/p) aura comme valeur 3
(double) n/p aura comme valeur 3.33333…

4.8 L’opérateur conditionnel : (seul opérateur ternaire en C)


syntaxe : condition ? Valeur si vrai : valeur si faux
z = (x=y) ? a : b ; on utilise la valeur de l’expression
a>b ? i++ : i-- ; la valeur de l’expression n’est pas utilisée
4. Opérateurs et Expressions

EXERCICES
5. Les Entées-Sorties Conversationnelles

 Quelles sont les écritures autorisés pour des nombres fournis en données? Que se

passe-t-il lorsque l’utilisateur ne les respecte pas?

 Comment organiser les données lorsque l’on mélange les types numériques et les

types caractères?

 Que se passe-t-il lorsque, en réponse à scanf, on fournit trop ou peu

d’informations?

 Comment agir sur la présentation des informations à l’écran?


5.Les Entées-Sorties Conversationnelles
5.1 Les possibilités de la fonction printf
La fonction printf a comme 1er argument une chaîne de caractères qui spécifie:

 Des caractères à afficher tels quels;


 Des code de format repérés par %. Un code de conversion (c, d, f..)
précise le type de l’information à afficher.

Un code de format peut contenir des informations complémentaires agissant sur le


cadrage, le gabarit ou la précision.

Exemple: printf("leur somme est : %d",n1+n2);


5.Les Entées-Sorties Conversationnelles
5.1 Les possibilités de la fonction printf

a. Les principaux codes de conversion:

 c : char: caractère affiché ''en clair" (convient aussi à short ou à int compte tenu

des conversions systématiques)

 d : int (convient aussi à char, compte tenu des conversions systématiques)

 u : unsigned int (convient aussi à unsigned char ou à unsigned short, compte tenu

des conversions systématiques)

 ld : long

 lu : unsigned long
5.Les Entées-Sorties Conversationnelles
5.1 Les possibilités de la fonction printf

a. Les principaux codes de conversion:

 f : double ou float écrit en notation "décimale" avec six chiffres après le point

 e : double ou float écrit en notation ‘'exponentielle'' (mantisse entre 1 et 9) avec six


chiffres après le point décimal, sous la forme x.xxxxxxe+yyy ou x.xxxxxxe-yyy pour
les nombres positifs et -x.xxxxxxe+yyy ou -x.xxxxxxe-yyy pour les nombres
négatifs

 s : chaîne de caractères dont on fournit l'adresse (notion qui sera étudiée


ultérieurement)
5.Les Entées-Sorties Conversationnelles
5.1 Les possibilités de la fonction printf

b. Action sur le gabarit d’affichage:

Les entiers sont affichés par défaut sans espaces avant ou après. Les flottants avec six
chiffres après le point.
Pour agir sur l’affichage  un nombre est placé après % et précise le nombre de
caractère minimum à utiliser.

Exemples: printf("%3d" , n );
n = 20 ^20
n=3 ^^3
n = 2358 2358
n = -5200 -5200
5.Les Entées-Sorties Conversationnelles
5.1 Les possibilités de la fonction printf

b. Action sur le gabarit d’affichage:

Exemples: printf("%f" , x );
x = 1.2345 1.234500
x = 12.3456789 12.345678

printf("%10f" , x );
x = 1.2345 ^^1.234500
x = 1.2345E5 123450.000000
printf("%e" , x );
x = 1.2345 1.234500e+000
x = 123.45 1.234500e+002
5.Les Entées-Sorties Conversationnelles
5.1 Les possibilités de la fonction printf
c. Actions sur la précision :
pour les flottants, on peut préciser un nombre de chiffres après le point décimal

Exemples: printf("%10.3f" , x );
x = 1.2345 ^^^^^1.235
x = 1.2345E3 ^^1234.500
x = 1.2345E7 12345000.000
Remarques:
Cadrage de l’affichage à gauche  printf("%-10.3f" , x ); x = 1.2345  1.235^^^^^
- Le caractère * figurants à la place d’un gabarit ou une précision signifie que la valeur
effective est fournie dans la liste des arguments de printf:
printf("%8.*f" , n, x ); n=1; x=1.2345  ^^^^^1.2
- La fonction printf fournit une valeur de retour (nombre de caractère affichés)
5.Les Entées-Sorties Conversationnelles
5.1 Les possibilités de la fonction printf
d. Les erreurs de programmation :

Erreur 1 : Code de format en désaccord avec le type de l’expression à afficher:


Conséquence : mauvaise interprétation si même taille (int en %u), sinon, conséquences
plus désastreuses.

Erreur 2: Nombre de code de format différents du nombre d’expressions de la liste


Conséquence 1 : si des expressions de la liste n’ont pas de format, elles ne seront pas
affichées ( printf("%d" , n, p ); // valeur de p ne sera pas affiché )
Conséquence 2 : s’il y a trop de code de format, printf cherchera à afficher n’importe
quoi ( printf("%d %d" , n ); n=8  8 2 )
5.Les Entées-Sorties Conversationnelles
5.2 Les possibilités de la fonction scanf

a. Les principaux codes de conversion :

 c : char

 d : int

 u : unsigned int

 hd : short int

 hu : unsigned short

 ld : long

 lu : unsigned long
5.Les Entées-Sorties Conversationnelles
5.2 Les possibilités de la fonction scanf

a. Les principaux codes de conversion :

 f ou e : float écrit en notation "décimale" ou ‘'exponentielle''

 Lf ou le : double écrit en notation "décimale" ou ‘'exponentielle''

 s : chaîne de caractères dont on fournit l'adresse (notion qui sera étudiée


ultérieurement)

b. Premières notion de tampon et de séparateurs :

Lorsque scanf attend des données, l’information frappée au clavier est rangée

temporairement dans l’emplacement mémoire nommé « tampon ». Ce dernier est

exploré caractère par caractère au fur et à mesure des besoins. Certains caractères

jouent un rôle particulier: les séparateurs (l’espace et la fin de ligne \n)


5.Les Entées-Sorties Conversationnelles
5.2 Les possibilités de la fonction scanf

c. Les premières règles utilisées par scanf :

 Les codes de format correspondant à un nombre entraînent l’avancement du


pointeur jusqu’au 1er caractère différent d’un séparateur, puis scanf prend en
compte tous les caractères suivants jusqu’à la rencontre d’un séparateur.

 Quand au code de format %c, il entraîne la prise en compte du caractère désigné


par le pointeur (même un séparateur) et il est avancé sur le caractère suivant.
5.Les Entées-Sorties Conversationnelles
5.2 Les possibilités de la fonction scanf

c. Les premières règles utilisées par scanf :

Exemples : (n et p sont de type int, c char, @ désigne une fin de ligne)


scanf("%d%d" , &n, &p );
12^25@ n = 12 p=25
^12^^25^^@ n = 12 p=25

123@
@
^25 n = 123 p=25
scanf("%d%c" , &n, &c );
12^a@ n = 12 c=‘ ‘
5.Les Entées-Sorties Conversationnelles
5.2 Les possibilités de la fonction scanf

d. On peut imposer un gabarit maximal :

Le traitement d’un code de format s’interrompe soit à la rencontre d’un séparateur, soit
lorsque le nombre de caractère indiqué a été atteint !!

Exemples : (n et p sont de type int, @ désigne une fin de ligne)

scanf("%3d%3d" , &n, &p );


12^25@ n = 12 p=25
^^^^^12345@ n = 123 p=45

12@
25@ n = 12 p=25
5.Les Entées-Sorties Conversationnelles
5.2 Les possibilités de la fonction scanf

e. Rôle d’un espace dans le format :

Un espace entre deux codes de format demande à scanf de faire avancer le pointeur au
prochain caractère différent d’un séparateur !!

Exemples : (n et p sont de type int, c char, @ désigne une fin de ligne)

scanf("%d %c" , &n, &c );


12^a@ n = 12 c=‘a‘
12^^^@
a@ n = 12 c=‘a‘
5.Les Entées-Sorties Conversationnelles
5.2 Les possibilités de la fonction scanf

f. Arrêt prématuré de scanf :

Compte = scanf("%d %d %c" , &n, &p, &c );


12^25^b@ n = 12 p = 25 c=‘b‘ compte = 3
12b@ n = 12 p inchangé c inchangé compte = 1
b@ n indéfini p inchangé c inchangé compte = 0

Un arrêt prématuré de scanf a lieu dans le cas où scanf n’est pas en mesur de fabriquer
une valeur adéquate !!
5.Les Entées-Sorties Conversationnelles
5.2 Les possibilités de la fonction scanf

f. Problème de synchronisation entre l’écran et le clavier :

Examinons cet exemple:


#include <stdio.h>
main()
{ int n, p;
printf("donner une valeur pour n : ");
scanf("%d",&n);
printf("Merci pour %d\n",n);
printf("donner une valeur pour p : ");
scanf("%d",&p);
printf("Merci pour %d\n",p);
} exécution
5.Les Entées-Sorties Conversationnelles
5.2 Les possibilités de la fonction scanf

f. Problème de synchronisation entre l’écran et le clavier :


Le tampon n’est pas vide à chaque nouvel appel de scanf
g. Erreurs de programation :

1- Code de format en désaccord avec le type de l’expression:


Si même taille  introduction d’une mauvaise valeur
Si la variable a une taille inférieur  écrasement d’un emplacement mémoire
consécutif à cette variable

2- Nombre de codes de format différent du nombre d’éléments de la liste:


Scanf("%d",&n, &p);  seule la valeur de n est lue
Scanf("%d%d",&n);  on affecte une valeur à un emplacement aléatoire de la
mémoire
6. Les structures de contrôle
 Choix
if (<condition>) <action 1>;
[else
<action 2>;]
• Toutes les conditions sont entre parenthèses.
• Le else est optionnel (c'est pourquoi il est mis entre crochets)
• S'il y a plusieurs instructions après le if ou le else, on les encadre
par des accolades : { }.
• La valeur logique équivalente à vrai est différente de 0, et la valeur
logique équivalente à faux est 0.
6. Les structures de contrôle
 Exemple
/* Exemple de if */ /* Exemple de if imbriqués */
if(x==3) if(a<b)
{ if(c<d)
y=1; j=1 ;
printf("x=3 donc : y=%d",y); /* sinon (c ≥ d) */
} else
/* Sinon, si x est différent de 3 */ j=2 ;
else /* sinon (a ≥ b) */
{ /* on ne fait rien */
y=-1; else ;
printf ("x !=3 donc : y=%d",y);
}
6. Les structures de contrôle
 Choix multiple
switch (<condition>)
{
case <valeur 1> : <action 1>; break;
case <valeur 2> : <action 2>; break;

default : <action n>;
}
6. Les structures de contrôle
 Exemple
/* Exemple 1 : */ /* Exemple 2 : */
/* Test sur la valeur de i */ /* Test sur la valeur de i */
j=0, k=0, l=0; j=0, k=0, l=0;
switch (i) switch (i)
{ {
/* Si i a pour valeur 0 */ /* Si i a pour valeur 0 */
/* Alors j=1, et on passe à */ /* Alors j=1, et on sort du */
/* l'instruction suivante */ /* switch */
case 0: j=1; case 0: j=1;
/* Si vaut 0 ou 1 */ break;
/* j = 0, et on passe à */ /* Si vaut 1, alors j=0 */
/* l'instruction suivante */ /* et on sort du switch */
case 1: k=1; case1: k=1; break;
/* Quel que soit la valeur de i */ /*Pour i différent de 0 ou 1 */
/* on affiche erreur */ /* on affiche erreur */
default : l=1; default : l=1;
} /* Fin du switch*/ } /* Fin du switch*/
6. Les structures de contrôle

 Itération
 Il existe deux manière de programmer une itération :

while (<condition>) Do
<actions>; <actions>
while(<condition>);

 Dans la première forme d'itération (while …), la condition est évaluée.


Puis, tant que la condition est vraie, les actions sont exécutées.
 Dans la deuxième forme d'itération (do ..), les actions sont exécutées
au moins une fois. Puis, tant que la condition est vraie, elles sont
exécutées de nouveau.
 Un break dans un while, quelle que soit la forme de l'itération, permet
de sortir de la boucle.
6. Les structures de contrôle

 Exemple

i=0; i=2;
while(i<2) while (i<2)
{ i++; { i++;
printf("%d\n",i); printf("%d\n",i);
} }
printf("fin"); printf("fin");

i=0; i=2;
do do
{ {
i++; i++;
printf("%d\n",i); printf("%d\n",i);
} while (i<2) ; }
printf("fin"); while (i<2) ;
printf("fin");
6. Les structures de contrôle

 Boucle for
for ([<instructions initiales>];[<condition>];[<instructions>])
[<corps de la boucle>];
for (exp1;exp2;exp3) équivalent à :
instruction; expr1;
while (expr2) {instruction;
expr3;
}

 L'exp1 est exécutée à la première itération. Les exp2 et exp3 sont réévaluées à chaque
fois que l'instruction (le corps de la boucle) est exécutée.
 S'il y a plusieurs instructions initiales ou finales, elles sont séparées par des virgules.
 <condition> ⇔ Tant que la condition est vraie.
 Les <instructions> sont exécutées après le corps de la boucle mais avant de tester à
nouveau la condition.
6. Les structures de contrôle

 Exemple
 for (;;); boucle infinie.
 for (i=0;i<2;i++)
S+=i;
 for(i=0,j=n;i<j;i++,j--)
{
instructions ;
}
 for(c='A';c<='Z';c++)
{
instructions ;
}
7. Les tableaux statiques (Objets structurés)
Ensemble de variables de même type stockées consécutivement dans la
mémoire et que l'on peut manipuler globalement ou bien élément par
élément.
Les tableaux statiques sont représentés par des crochets, entre lesquels
est indiquée la taille du tableau. .
 EXEMPLES :
int iTableau[10]; → tableau de 10 entiers,
iTableau est un pointeur, c'est-à-dire l'adresse de début d'une zone
mémoire de taille (nombre d'octets) égale au nombre entre crochets
multiplié par la taille du type du pointeur, soit 10*2 octets.
Pour accéder au xième élément du tableau iTableau, il faut faire :
iTableau[x-1]
 ATTENTION : Les éléments des tableaux sont indicés de 0 à n-1.
7. Les tableaux statiques (Objets structurés)

 EXEMPLE 2 :
int iTabDeuxDim[5][4]; → tableau d'entiers à deux
dimensions de 20 éléments.
iTabDeuxDim est un pointeur sur une zone de 4*5*2 octets.
 EXEMPLE 3 :
On peut remplir un tableau lors de sa déclaration :
int iTableau[] = {4,5,8,12,-3};
déclaration et initialisation d'un tableau (on peut mettre le
nombre d'éléments à l'intérieur des crochets, mais dans ce
cas, ce n'est pas obligatoire). La taille du tableau est fixée à 5
éléments.
8. Les chaînes de caractères (Objets structurés)
Les chaînes de caractères sont représentées par des tableaux statiques
ou par des pointeurs.
 EXEMPLES :
char identificateur[dimension];
On peut initialiser un tableau de caractères (ou chaîne de caractères) lors
de sa déclaration :
 EXEMPLE 1 : char t[] = ''abcde''
 EXEMPLE 2 : char t[] = {'a','b',...}
8. Les chaînes de caractères (Objets structurés)

 Lecture de chaîne
scanf ("%s", adresse de la chaîne);
 Fonctions gets et puts
char* gets (char*); // ramène l'adresse de la chaîne lue
void puts(char*); //affiche la chaîne qui est en argument
 Fonction de manipulation:
Pensez à inclure préalablement string.h
 strlen(<s>) : fournit la longueur de la chaîne sans compter le '\0' final.
 strcpy(<s>, <t>) : copie <t> vers <s>
 strcat(<s>, <t>) : ajoute <t> à la fin de <s>
 strcmp(<s>, <t>) : compare <s> et <t> lexicographiquement et fournit un résultat :
négatif si <s> précède <t>;
zero si <s> est égal à <t>;
Positif si <s> suit <t>.
9. COMPLEMENT SUR LES POINTEURS

 Un pointeur est une référence sur une donnée.


 Il s'agit d'une adresse en mémoire où sont stockées les données
référencées.
 On peut définir des pointeurs sur n'importe quoi :
int* p; /* pointeur sur un entier */
int* t[100]; /* Tableau de 100 pointeurs sur entier */
int** p; /* pointeur sur un pointeur d'entier */
La constante NULL, définie dans le fichier <stdio.h> est la valeur
standard pour un pointeur vide (ne pointant sur rien).
Cette constante est très utile pour l'initialisation des pointeurs et les tests
9. COMPLEMENT SUR LES POINTEURS

 Opérateur * et &
• L'opérateur * désigne le contenu de l'adresse pointée ;
*iPointeur : désigne le contenu de la zone mémoire pointée par iPointeur.
• L'opérateur & est un opérateur unaire qui fournit comme résultat
l'adresse de son opérande.
Cet opérateur est déjà utilisé dans la fonction scanf.
Exemple:
int* iPointeur=NULL; /* Déclaration et initialisation d'un pointeur */
int iEntier =20; /* Déclaration et initialisation d'un entier */
iPointeur = &iEntier; /* Placement de l'adresse de l'entier dans le pointeur */
*iPointeur = 30; /* Modification de l'entier pointé */
/* équivalent à iEntie=30; * /
10. Allocation dynamique de la mémoire

L'initialisation d'un pointeur peut se faire en transmettant l'adresse d'un


autre pointeur, ou en allouant de la mémoire :
int iEntier; /* Déclaration d'un entier et de deux pointeurs
int* iPointeur1=NULL; sur un entier et initialisation des pointeurs à
int* iPointeur2=NULL; NULL */
iPointeur1=&iEntier; /* iPointeur1 pointe sur l'adresse de iEntier */

Les fonctions malloc et free de la librairie C permettent respectivement


d'allouer de la mémoire à un pointeur ou de désallouer la mémoire pointée
par le pointeur. Ces fonctions sont définies dans la librairie <stdlib.h>.

/*Allocation mémoire de iPointeur2 sur une zone mémoire de la taille d'un


entier */
iPointeur2=(int*)malloc(sizeof(int));
/*La fonction sizeof, de la librairie C, permet de calculer la taille occupée par un
type de données. */
Free(iPointeur); /*libération de la zone mémoir occupée par iPointeur*/
10. Allocation dynamique de la mémoire
 Opérations sur les pointeurs
*iPointeur = 3; /* iPointeur pointe sur une zone mémoire dont on modifie la
valeur */
iValeur=*iPointeur; /* iValeur est égale à la valeur de la zone mémoire où
pointe iPointeur */
 Comparaison: les pointeurs doivent être de même type.
int* iPointeur1=NULL;
int* iPointeur2=NULL;
if(iPointeur1==iPointeur2)
 Addition et soustraction d'un entier
/* Pointeur pointe sur l'élément suivant de la structure sur laquelle il pointe */
Pointeur++;
/* Décalage du pointeur de 2 éléments dans la structure pointée */
Pointeur+=2;
10. Allocation dynamique de la mémoire

 Il est possible de soustraire deux pointeurs (mais pas de les additionner) .


/* Calcul du nombres d'octets entre les deux adresses de Pointeur1 et
Pointeur2. il faut que p>q en adresse */
iDifference_Adresse = Pointeur1-Pointeur2;
 Gestion dynamique des tableaux (fonction malloc)
/* Déclaration d'un pointeur sur des entiers iPointeur et de la taille du
tableau iTaille */
int* iPointeur=NULL;
int iTaille;
/* Saisie de la taille du tableau par l'utilisateur */
scanf ("%d",&iTaille);
/* Allocation dynamique de la zone mémoire occupée par le tableau */
iPointeur = (int*)malloc (iTaille*sizeof(int));
free(iPointeur); //libération de l’espace mémoire
10. Allocation dynamique de la mémoire

 Gestion dynamique des tableaux (fonction calloc et realloc)


/* Déclaration d'un pointeur sur des entiers iPointeur et de la taille du
tableau iTaille */
int* iPointeur=NULL;
int iTaille;
/* Saisie de la taille du tableau par l'utilisateur */
scanf ("%d",&iTaille);
/* Allocation dynamique de la zone mémoire occupée par le tableau */
iPointeur = (int*)calloc (iTaille,sizeof(int));
/* Saisie de la nouvelle taille du tableau par l'utilisateur */
scanf ("%d",&iTaille);
/* Allocation dynamique de la nouvelle zone mémoire occupée par le tableau */
iPointeur = (int*)realloc (iTaille,sizeof(int));
10. Allocation dynamique de la mémoire

 Gestion dynamique des tableaux Multi_Dim (fonction calloc)


/* Déclaration d'un pointeur des pointeurs sur des entiers iPointeur et de la taille du
tableau iTaille */
int** iPointeur=NULL;
int iTaille;
/* Saisie de la taille du tableau par l'utilisateur */
scanf ("%d",&iTaille);
/* Allocation dynamique de la zone mémoire occupée par le tableau */
iPointeur = calloc (iTaille,sizeof(*iPointeur));
/* Allocation dynamique de la zone mémoire occupée par iTaille pointeur*/
For(i=0;i<iTaille;i++)
iPointeur[i] = (int*)calloc (1,sizeof(int));
11. Les Fonctions

La programmation modulaire permet d'éviter les séquences d'instructions


répétitives et permet le partage d'outils communs qu'il suffit d'avoir écrits et
mis au point une seule fois. En C, il n'existe qu'une sorte de module,
nommé fonction.
 Les fonctions sont écrites avant le programme principal (main).
 Il est possible de les définir après, mais il faut alors les déclarer avant.
 Elle dispose d'arguments ou peut ne pas avoir d'arguments du tout.
 Il existe deux types principaux de fonctions :
 Les fonctions qui retournent quelque chose dont la signature est :
 type nom_fonction(déclarations_d'arguments);
 Les fonctions qui ne retournent rien (void) dont la signature est :
 void nom_fonction(déclarations_d'arguments);
11. Les Fonctions

 Déclaration d'une fonction .


type-de-retour nom-de-fonction(déclarations d'arguments);
//On appelle cela la signature ou prototype de la fonction.
 Définition du corps de la fonction */
type-de-retour nom-de-fonction(déclarations d'arguments)
{
déclarations et instructions
}
Les instructions entre accolades correspondent au corps de la fonction.
11. Les Fonctions

 Exemple de la déclaration:
/* fonction calculant le produit de deux entiers */
int calcule_produit (int arg1, int arg2)
/* Paramètres d'entrée : deux entiers */
/* Type retour : entier */
 Exemple de la définition:
int calcule_produit (int iExp1, int iExp2)
{
int iProduit;
iProduit = iExp1 * iExp2;
return iProduit;
}
11. Les Fonctions

 Exemple
/* Procédure affichant le produit de deux entiers */
/* */
/* Paramètres d'entrée : deux entiers */
/* Type retour : rien */
void affiche_produit (int iExp1, int iExp2)
{
int iProduit;
iProduit = iExp1 * iExp2;
printf ("Le produit de %d et %d est égal à %d", iExp1, iExp2, iProduit);
}
11. Les Fonctions

 L’appel des fonctions et le passage des paramètres


 Quand le type de retour est un void

Syantaxe : Nom_fonction(arguments);
Affiche_produit(var1,var2);
void affiche_produit (int iExp1, int iExp2)
{
int iProduit;
iProduit = iExp1 * iExp2;
printf ("Le produit de %d et %d est égal à %d", iExp1, iExp2, iProduit);
}
int main()
{
int var1,var2;
var1=145; var2=35;
affiche_produit(var1,var2);//Appel de la fonction affiche_produit dans la fonction main
return 0;
} /*le programme affiche : Le produit de 145 et 35 est égal à 180*/
11. Les Fonctions

 L’appel des fonctions et le passage des paramètres


 Quand la fonction retourne une valeur.
Syantaxe : var = Nom_fonction(arguments); /*var a le meme type que le type de
retour de la fonction*/
var =calcule_produit(var1,var2);
int calcule_produit (int iExp1, int iExp2)
{
int iProduit;
iProduit = iExp1 * iExp2;
return iProduit;
}
int main()
{
int var1,var2,var;
var1=145; var2=35;
var = affiche_produit(var1,var2);//Appel de la fonction affiche_produit dans la fonction main
printf ("Le produit de %d et %d est égal à %d", var1, var2, var);
return 0;
} /*le programme affiche : Le produit de 145 et 35 est égal à 180*/
11. Les Fonctions

 L’appel des fonctions et le passage des paramètres


 Passage par valeur.
Syantaxe : Nom_fonction(type agr1, type atg2);
Appel : calcule_produit(var1,var2);//var1 et var2 sont des variables globales
Les valeurs sont passées et la fonction stoke dans des variable locles.
Le contenu des variables globales restes inchangé.

void calcule_produit (int iExp1, int iExp2,int iExp3) int main()


{
iExp1=10;
{
iExp2=20; int var1,var2,var3;
iExp3 = iExp1 * iExp2; var1=0; var2=0; var3=0;
printf ("Le produit de %d et %d est égal à %d", calcule_produit(var1,var2,var3)
iExp1, iExp2, iExp3); printf ("Le produit de %d et %d est égal
return 0; à %d", var1, var2, var);
} return 0;
}

calcule_produit affiche: Le produit de 10 et 20 est Main affiche: Le produit de 0 et 0 est égal à


égal à 30*/ 0*/
11. Les Fonctions
 L’appel des fonctions et le passage des paramètres
 Passage par référence.
Syantaxe : Nom_fonction(type *agr1, type* atg2);
Appel : calcule_produit(&var1,&var2);//var1 et var2 sont des variables globales
Appel : calcule_produit(p1,p2); //p1 et p2 sont des pointeurs
Les valeurs sont passées et la fonction stoke dans des variable locles.
Le contenu des variables globales ou espace mémoire est changé.

void calcule_produit (int *iExp1, int *iExp2,int *iExp3) int main()


{
*iExp1=10;
{
*iExp2=20; int var1,var2,var3;
*iExp3 = (*iExp1) * (*iExp2); var1=0; var2=0; var3=0;
printf ("Le produit de %d et %d est égal à %d", calcule_produit(&var1,&var2,&var3)
*iExp1, *iExp2, *iExp3); printf ("Le produit de %d et %d est égal
return 0; à %d", var1, var2, var3);
} return 0;
}

calcule_produit affiche: Le produit de 10 et 20 est Main affiche: Le produit de 10 et 20 est égal


égal à 200*/ à 200*/
12. les Structures (Objets structurés)

 Définition
struct [<nom de la structure>]
{
<type> <nom ou identifiant>; /* champ */
} [<nom d'une variable>];
/* <nom d'une variable> est une variable de type struct <nom de la structure>*/
 EXEMPLE :
/* Structure personne, composée de deux champs : cNom et iAge */
struct personne
{
char* cNom; int iAge;
};
 struct personne individu; /* Déclaration d'un élément individu de type struct
personne */
12. les Structures (Objets structurés)
 Accès à un élément d'une structure
/* Structure personne, composée de deux champs : cNom et iAge */
struct personne
{
char* cNom; int iAge;
};
int main()
{
struct personne individu;
struct personne *pindividu=NULL;
printf ("%s", individu.cNom);
printf("%d",individu.iAge);
printf("%s",(*pindividu).cNom);
printf("%s", pindividu->cNom);
}
13. Liens utiles

 https://openclassrooms.com/courses/apprenez-a-programmer-en-c
 http://www.apprendre-informatique.com/tutorial/programmation/langage-
c/apprendre-le-c/
 https://www.rocq.inria.fr/secret/Anne.Canteaut/COURS_C/cours.pdf
 https://www.rocq.inria.fr/secret/Anne.Canteaut/COURS_C/chapitre1.html