Академический Документы
Профессиональный Документы
Культура Документы
INTRODUCTION
AU
LANGAGE
C
Historique
• Le
langage
C
a
été
inventé
en
1972
par
Dennis
Ritchie
et
Ken
Thompson
(AT&T
Bell
Laboratories)
pour
réécrire
Unix
et
développer
des
programmes
sous
Unix.
• En
1978,
Brian
Kernighan
et
Dennis
Ritchie
publient
la
définition
classique
du
C
dans
le
livre
«
The
C
Programming
language
»
.
C’est
une
norme
ANSI
(ANSI‐C)
depuis
1989
et
un
standard
ISO
depuis
1990.
Langage
de
haut
niveau,
structuré,
portable
et
modulaire
grâce
à
ses
nombreuses
librairies
standard
(stdio,
string,
math,
etc.).
Généralités
Un
programme
est
un
ensemble
de
fichiers
qui
peuvent
être
édités,
compilés
et
exécutés
:
• Compilation
:
traduction
d’un
programme
d’un
langage
source
(haut
niveau)
vers
un
langage
destination
(plus
bas
niveau).
• Exécution
d’un
compilateur
:
génère
un
programme
exécutable
à
partir
d’un
ou
de
plusieurs
fichiers
contenant
du
code
source.
Tout
programme
C
est
composé
d'un
programme
principal
(fonction
main).
Variable
=
objet
manipulé
par
le
programme,
qui
sert
à
nommer
un
espace
réservé
en
mémoire.
À
chaque
variable
est
associé
un
type
et
sa
valeur
actuelle
:
• Le
type
est
défini
au
moment
d’une
déclaration
:
une
instruction
composée
d’un
spécificateur
de
type
et
d’une
liste
d’identificateurs
séparés
par
une
virgule.
• La
valeur
d’une
variable
peut
être
modifiée
pendant
l’exécution
du
programme
par
des
instructions
d’affectation.
Une
expression
est
composée
d’une
ou
plusieurs
opérandes
(constantes,
variables,
etc.)
reliés
par
zéro
ou
plusieurs
opérateurs.
A
chaque
expression
est
associé
un
type.
Une
instruction
est
une
expression
qui
se
termine
par
un
point‐virgule
‘;’.
Un
bloc
est
une
instruction
composée
:
• d’une
accolade
ouvrante
{
• d’une
liste
de
déclarations
de
variables
• d’une
liste
d’instructions
• d’une
accolade
fermante
}
Un
commentaire
est
encadré
par
des
délimiteurs
/*
et
*/
(//
commentaire
par
ligne).
Une
variable
globale
est
définie
et
utilisable
par
toutes
les
fonctions
définies
dans
le
programme.
Une
variable
locale
est
définie
et
utilisable
qu’à
l’intérieur
du
bloc
d’instructions
d’une
fonction.
Directives
du
préprocesseur
Une
instruction
du
préprocesseur
:
commence
par
#
Une
constante
est
définie
:
#define
NOM_CONST
constante
• #include
<nom
fichier>
:
inclusion
d’un
fichier
qui
se
trouve
dans
les
répertoires
standard.
• #include
"nom
fichier"
:
inclusion
d’un
fichier
qui
se
trouve
dans
les
répertoires
définis
dans
l’environnement.
Quelques
bibliothèques
standard
ANSI
stdio.h
Gestion
des
entrées
sorties
(io
pour
Input/Output)
printf,
scanf,
getc,
putchar,
fopen,…
stdlib.h
Traitements
courants
ou
utilitaires
rand,
malloc,
atoi,…
string.h
Manipulation
de
chaînes
de
caractères
strcpy,
strcat,
strcmp,
strlen,…
math.h
Traitements
mathématiques
pow,
sqrt,
exp,...
time.h
Manipulation
des
primitives
de
temps
(date,
heure,
etc.)
clock,
time,
mktime,
localtime,…
Lecture
et
Écriture
sur
les
entrées/sorties
standard
(stdin/stdout)
Fonction
:
printf
("…format…",
e1,
e2,
....)
affichage
à
l’écran
(écriture
vers
la
sortie
standard).
Fonction
:
scanf
("…format…",&v1,&v2,...)
saisie
de
valeurs
à
l’écran
(lecture
de
l’entrée
standard)
en
accord
avec
un
format.
Fonction
:
int
putchar
(int
c)
affichage
d’un
caractère
à
l’écran.
Fonction
:
int
puts
(char
*s)
affichage
d’une
chaîne
de
caractères
à
l’écran
(en
ajoutant
le
caractère
‘\n’).
Fonction
:
int
getchar
(void)
saisie
d’un
caractère
à
l’écran.
Fonction
:
int
gets
(char
*s)
saisie
d’une
chaîne
de
caractères
à
l’écran.
Séquences
d’échappement
\n
nouvelle
ligne
\r
retour
chariot
\t
tabulation
horizontale
\f
saut
de
page
\v
tabulation
verticale
\a
signal
d’alerte
\b
retour
arrière
Spécifications
de
conversion
Format
Type
Explication
%d,
%i
int
notation
décimale
signée.
%u
int
notation
décimale
non
signée.
%c
int
un
seul
caractère
après
conversion
en
unsigned
char.
%s
char
*
chaîne
de
caractères
jusqu’au
premier
‘\0’.
%f,
%2.7f
double
notation
décimale
de
la
forme
[‐]mmm.dddddd
(6
par
défaut).
%e,E
double
notation
scientifique
de
la
forme
[‐]m.ddddddE[+‐]xx.
%x
int,double
notation
hexadécimale.
INSTRUCTIONS
SIMPLES,
STRUCTURES
DE
CONTRÔLE
&
ITÉRATIVES
Types
C
Types
arithmétiques
:
• ensembles
des
nombres
entiers
:
o entiers
:
int, short, long
o caractères
:
char
o types
énumérés
(ensembles
fini
d’entiers)
:
enum
• ensembles
des
nombres
à
virgule
flottante
:
flottants
ou
réels
(float,
double)
Type
de
donnée
Signification
Taille
(octets)
Plage
de
valeurs
char
Caractère
1
−128
à
127
unsigned
char
Caractère
non
signé
1
0
à
255
short
int
Entier
court
2
−32
768
à
32
767
unsigned
short
int
Entier
court
non
signé
2
(proc.
16
bits)
0
à
65
535
(signed)
int
Entier
2
(proc.
16
bits)
−32
768
à
32
767
4
(proc.
32
et
64
bits)
−2
147
483
648
à
2
147
483
647
A/
Définition
Rappelons
qu’en
C
une
chaîne
de
caractères
est
un
tableau
unidimensionnel
de
caractères
dont
le
dernier
caractère
significatif
est
le
caractère
‘\0’.
Ainsi,
la
constante
de
type
chaîne
de
caractères
"bonjour",
est
représentée
en
machine
par
le
tableau
unidimensionnel
de
caractères
ci‐dessous
:
Le
pointeur
Pchaine
pointe
vers
le
caractère
b
de
la
chaîne
constante
"bonjour",
mais
on
peut
l’utiliser
comme
s’il
s’agissait
d’un
identificateur
de
tableau
de
caractères,
par
exemple,
pour
imprimer
la
chaîne
avec
:
La procédure printf imprimera tous les caractères qui suivent, jusqu’à rencontrer le caractère ‘\0’ ;
En mémoire centrale, on aurait par exemple:
Pchaine 0 1 2 3 4 5 6 7
1230 'b' 'o' 'n' 'j' 'o' 'u' 'r' '\0'
Adresses 1230 1234 1238 1242 1246 1250 1254 1258
chaine
et
*Pchaine
ont
toutes
deux
à
ce
moment
pour
valeur
la
chaîne
de
caractères
bonjour.
Mais,
chaine
est
un
tableau
implanté
à
une
adresse
fixe
(ici
1230),
et,
pour
changer
sa
valeur,
il
faut
changer
la
valeur
de
ses
cellules
une
à
une,
alors
que
Pchaine
est
une
variable
pointeur
initialisée
de
façon
à
pointer
initialement
sur
la
même
valeur,
mais
sa
valeur
peut
changer.
Par
exemple,
on
peut
écrire
:
Pchaine = "salut" ;
Pchaine pointe
maintenant
sur
une
nouvelle
constante
(allouée
quelque
part
ailleurs
en
mémoire)
sans
qu’aucune
recopie
de
caractères
n’ait
été
effectuée.
Ainsi
on
ne
peut
pas
écrire
:
char chaine[10] ;
chaine = "bonjour" ;
Alors
que
l’on
peut
écrire
:
char *Pchaine ;
Pchaine = "bonjour" ;
En
effet,
lors
d’une
affectation,
on
distingue
clairement
la
partie
gauche
du
signe
de
l’affectation
(souvent
notée
en
anglais
lvalue,
pour
left
value)
et
sa
partie
droite.
La
partie
droite
doit
contenir
une
expression
évaluable,
et
la
partie
gauche
une
valeur
modifiable
par
cette
expression.
Une
valeur
modifiable
est
une
variable
dont
le
type
doit
être
défini
(et
l’expression
figurant
en
partie
droite
devra
avoir
un
type
compatible)
et
ne
peut
être
de
type
tableau
ou
fonction.
(Il
ne
peut
s’agir
non
plus
de
type
const,
et
lorsqu’il
s’agira
d’une
structure,
aucun
des
membres
ou
sous‐membres
ne
pourra
être
constant.)
B/
Fonctions
de
la
bibliothèque
string.h
Pour
utiliser
une
fonction
prédéfinie
permettant
de
manipuler
des
chaînes
de
caractères,
il
faut
inclure
le
fichier
d’entête
<string.h>.
Dans
ce
fichier
on
trouve
de
nombreuses
fonctions
intéressantes.
‐
La
fonction
permettant
de
calculer
la
longueur
d’une
chaîne
de
caractères
(à
savoir
le
nombre
de
caractères
significatifs
–
i.e.
ceux
qui
précèdent
le
caractère
‘\0’)
s’appelle
strlen
et
a
pour
prototype
:
int strlen(<chaine>) ;
où
<chaine>
est
:
soit
une
constante
de
type
chaîne
de
caractères,
soit
un
identificateur
de
tableau
de
caractères,
soit
une
variable
de
type
pointeur
sur
un
caractère.
Exemple
int longueur ;
longueur = strlen("bonjour") ;
/* longueur vaut alors 7 */
‐
La
fonction
prédéfinie
permettant
de
copier
une
chaîne
de
caractères
(appelée
<chaine source>)
dans
une
autre
(ou
à
une
adresse
donnée)
est
strcpy :
Cette
fonction
renvoie
une
valeur
de
type
pointeur
sur
un
caractère.
Cette
valeur
est
l’adresse
du
début
de
la
chaîne
recopiée
(c’est‐à‐dire
la
valeur
du
premier
paramètre
formel).
Exemple
char c[100]= "bonjour" ;
/* pour afficher la chaîne «programmation» et la stocker
dans la variable c */
printf(«%s», strcpy(c, "programmation") );
0 1 2 3 4 12 13 14 ...
c 'b' 'o' 'n' 'j' 'o' …
char tab[80];
char *ret ; /* ou char ret[] ; */
ret = strcpy(tab, "programmation") ;
Mais,
le
programme
sortira
en
erreur
avec
:
‐
La
fonction
prédéfinie
strcat
permettant
de
concaténer
deux
chaînes
de
caractères
a
pour
prototype
:
‐ La fonction prédéfinie permettant de comparer deux chaînes de caractères a pour prototype :
• inférieur à 0 si <chaine1> est inférieure à <chaine2> selon l’ordre lexicographique,
• égal à 0 si <chaine1> et <chaine2> sont identiques,
• supérieur
à
0
si
<chaine1>
est
supérieure
à
<chaine2>
selon
l’ordre
lexicographique.
Exemple
char chaine[10]= "bonjour";
char *c1,*c2 ;
c1 = chaine ;
c2 = chaine ;
Dans ce cas c1==c2 vaut vrai et strcmp(c1,c2) vaut 0.
c1
bonjour
c2
‐
La
fonction
prédéfinie
permettant
de
copier
une
suite
de
caractères
d’une
chaîne
à
partir
d’une
autre
chaîne
de
caractères
a
pour
prototype
:
Prototype Description
int isalpha(int c) retourne une valeur non nulle si c est une lettre
int isupper(int c) retourne une valeur non nulle si c est une lettre majuscule
int islower(int c) retourne une valeur non nulle si c est une lettre minuscule
int isspace(int c) retourne une valeur non nulle si c est un caractère d’espacement
(espace, tabulation, retour de chariot)
D/
Autres
fonctions
de
traitement
de
chaînes
de
caractères
Le fichier d'en-tête <string.h> contient, entre autres, les déclarations des fonctions qui manipulent
les chaînes de caractères. Dans le tableau qui suit, les paramètres nommés s sont de type char*, les
paramètres nommés cs, cs1 et cs2 sont de type const char*, les paramètres nommés n sont de
type size_t et les paramètres nommés c sont de type int converti en char. Voici quelques-unes des
fonctions disponibles dans ce fichier d'en-tête.
Prototype Description
char* strcpy(s, cs) copie la chaîne cs, y compris '\0', dans la chaîne s;
retourne s.
int strcmp(cs1, cs2) compare la chaîne cs1 à la chaîne cs2; retourne une
valeur négative si cs1 < cs2, nulle si cs1 == cs2,
positive si cs1 > cs2.
E/
Fonctions
de
conversion
de
chaînes
de
caractères
Le fichier d'en-tête <stdlib.h> contient, entre autres, les déclarations des fonctions qui convertissent
les chaînes de caractères. Voici quelques-unes des fonctions disponibles dans ce fichier d'en-tête.
Prototype Description
Annexe 3
I. Introduction
Syntaxe :
FILE * < descripteur de fichier > ; /* déclaration d’une variable de type FILE */
< descripteur de fichier > = fopen( <nom_fichier>, <mode>) ;
< descripteur de fichier > : chaîne de caractères ;
< nom_fichier > : chaîne de caractères <= 8;
<mode> :{ r, w, r+, w+, a, a+} où
r : Ce mode permet d’ouvrir le fichier seulement pour la lecture. Si le fichier n’existe pas,
la fonction fopen( ) renvoie la constante NULL.
w : Ce mode permet d’ouvrir le fichier pour l’écriture, si le fichier existe déjà, son contenu
sera détruit.
w+ : Ouverture du fichier l’écriture et la lecture, si le fichier existe déjà son contenu sera
détruit.
La fonction fgets(s, n, <descripteur>) effectue une lecture du fichier spécifié par son
descripteur et stocke les caractères lus dans la chaîne s. la lecture contenue jusqu’à ce que
l’un des caractères ‘\n’ ou EOF soit détecté ou que le nombre de caractères lus égale à n-
1. Le caractère ‘\0’ est ajouté automatiquement à la fin de la chaîne s.
Exemple1 :( lecture caractère par caractère à partir d’un fichier fich1 et écriture dans un
autre fich2):
Exemple2 :( lecture à partir du clavier de toute une ligne et écriture dans un fichier):
FILE * fp1 ;
char *chaine ;
fp1=fopen(″fich1″, ″w″);
if( (fp1==NULL) ) return ;
gets(chaine ) ;
fprintf(fp1, ″ %s ″, chaine ) ;
Exemple1 :( lecture d’un ensemble de lignes à partir d’un fichier fich1 et écriture dans un
autre fich2):
fp1=fopen(″fich1″, ″r″);
fp2=fopen(″fich2″, ″w″);
if( (fp1==NULL) ||(fp1==NULL) )
return ;
while( fgets(chaine, 80, fp1))
fprintf(fp2, ″ %s ″, chaine ) ;
Exemples :
∫ fseek(fp, 25L, SEEK-SET) : déplacement de 25 octets à partir de début du fichier.
∫ fseek(fp, -100L, SEEK-END) : déplacement de 100 octets vers l’arrière à partir de la fin
du fichier.
main( )
{
char nom[ 10 ] ;
FILE *fp ;
printf(″ Entrer le nom du fichier : ″) ;
scanf(″%s″,nom) ;
fp=fopen(nom, ″w″) ;
if(fp==NULL)
return ;
printf(″ \n Entrer la liste de caractères, # pour terminer ″) ;
while( ( c=getchar( ) ) != ‘#’)
fputc(c, fp) ;
fclose(fp) ;
printf(″ \n Chargement terminé ″) ;
}
Annexe 4
I. Présentation générale
Une structure (ou enregistrement ) est une collection de variables regroupées sous un
nom unique pour une utilisation plus simple.
Syntaxe :
struct nom_structure
{
liste de déclaration des champs ;
}
Remarque :
Les membres d’une structure peuvent être eux même des structures.
(Exemple un champ date_naiss peut être une structure de jour, mois et
année dans l’enregistrement étudiant).
Un tableau de structures est un tableau dont les éléments ont pour type une
structure définit précédemment.
Exemple :
On considère la structure étudiant déjà déclarée.
Exemple :
main( )
{
int i ;
étudiant e[12] ; /* sans spécifier le terme struct */
for(i=0 ; i<12 ; e[ i ].âge=20,i++) ;
}
Exemple :
struct étudiant
{
int cin ; /* réservation de 2 octets */
int âge ; /* réservation de 2 octets */
char section[ 10 ] ; /* réservation de 10 octets */
} e1;
sizeof(e1)=14.
Remarque :
La fonction memcpy(&e1, &e2, sizeof(e1) ) permet de copier tout la
structure e2 dans e1.
Exercice :
Écrire un programme C qui calcule et affiche la moyenne d’une classe de 12 étudiants.
Chaque étudiant est identifié par un numéro de carte d’identité (cin), un nom, prénom
et une liste de 10 matières et une moyenne calculable (moy_et). On suppose que les dix
matières ont le même coefficient.
Correction :
typedef struct étudiant
{
int cin ;
char nom[10], prénom[10] ;
int note_mat[10] ;
float moy_et ;
};
main( )
{
étudiant e[12] ;
int i ;
float somme = 0.0 ;
for( i=0 ; i<12 ; i++)
e[ i ]. moy_et = calcul_moy( e, i );
for( i=0 ; i<12 ; i++)
somme = somme + e[ i ]. moy_et ;
printf(″ La moyenne générale de la classe est %f″, somme/12) ;
}
calcul_moy(e, i )
étudiant e[12] ;
int i ;
{
int j ;
float somme=0.0 ;
for(j=0 ; j<10 ; j++)
somme = somme + e[ i ]. note_mat ;
return(somme/10) ;
}
V. Structures et pointeurs
Exemple :
struct étudiant *e ;
int a ;
a = e -> âge /* affecter le contenu du champ âge dans la variable a */
Exemple :
int a ; /* réservation de 2 octets mémoire */
char tab[ 100 ] ; /* réservation de 100 octets */
* La réservation d’un espace mémoire pour une variable reste tout au long
de l’exécution du programme, même si cette variable est inutilisable.
Exemple :
e= (struct étudiant * ) malloc( sizeof(struct étudiant)) ; /* allocation d’un espace
mémoire de type étudiant pointé par e */
C’est en fait une liste de cellules mémoires (ou nœuds ) reliées par une référence
(ou adresse). Chaque cellule est une structure dont les membres en plus des valeurs
on trouve des pointeurs vers la cellule suivante et/ou la précédente.
Exemple :
struct étudiant
{ int cin ;
int âge ;
char section ;
struct étudiant *next ;
};
nœud_1 nœud_2
Exemple :
# include<stdio.h>
# include<string.h>
# include<alloc.h>
main( )
{
struct étudiant *first, *p, préced ;
int num ;
first = préced = NULL ;
printf(″entrer le numéro de la CIN de l’étudiant, -1 pour terminer″) ;
scanf(″%d″,&num) ;
while(num != -1)
{
p=(struct étudiant * ) malloc( sizeof(struct étudiant)) ;
p->cin=num ;
scanf(″%d″,&p->âge) ;
scanf(″%s″,&p->section) ;
if(first == NULL)
first=p ;
else
libérer(first)
struct étudiant *first ;
{
struct étudiant *first ;
while(first)
{
p = first -> next ;
free( first ) ;
first = p ;
}
}