Telechargé par Daniel Mbom

programmationC resumé

publicité
Programmation en C
Chapitre 1 Concepts de base
I - Structure générale d’un programme en C
#include <stdio.h> // declaration des fichiers d’en-tête
//Décalaration des constantes
// déclaration des types et fonctions
//déclarations des variables globales
int main()// Début du programme principal
{
// Déclaration des variables
printf("Hello, world\n");
return 0
}
Un programme est toujours subdivisé en plusieurs parties :
Importation des bibliothèques
#include<stdio.h>
#include<conio.h>
Selon ce que l'on souhaite faire dans notre programme, on peut avoir besoin de
différentes fonctions. Celles-ci sont disponibles dans des bibliothèques. On parle
aussi de fichier d’en-tête.
Déclaration des constantes
La valeur d'une constante ne doit jamais changée quelque soit l'instant où le
programme est exécuté. La décalaration se fait par la syntaxe :
#define nom_cte val
où nom_cte est le nom utilisé pour le désigner dans le programme et val sa
valeur fixée
Exemple : #define DEUX 5
Corps du programme
int main ( )
{
printf ( "Bonjour à tous \n! " ) ;
getch ( ) ;
return 0 ;
}
La fonction main() est la fonction principale, un programme C n’a qu’une seule.
Les instructions du main sont toujours placées entre alcollades, même la
déclaration des variables. L’instruction return permet de retourner le résultat de
la fonction. Pour le « main » cette valeur est généralement 0.
La syntaxe générale de la fonction main() est la suivante :
int main ( )
{déclaration des variables
<instructions à exécuter>
return 0 ;
}
Chaque instruction se termine toujours par un point-virgule
getch() ; permet de suspendre l'exécution du programme jusqu'à ce que
l'utilisateur appuie sur une touche. Cette fonction est dans la bibliothèque
conio.h
Commentaires
Un commentaire est une séquence de caractères ignoré par le compilateur, on
s'en sert pour expliquer des portions de code
On délimite un commentaire par /* et */ ou sur la ligne par // (jusqu’à la fin de
ligne). Par exemple
/* Commentaire sur
plusieurs lignes */
// Commentaire jusqu'à la fin de ligne
Variables
Chaque variable porte un nom permettant de l’identifier. Pour utiliser une
variable, il faut toujours la déclarer avant. Cette déclaration peut se faire
n’importe où dans le programme, mais la variable n’est visible que partout dans
les accolades qui entourent cette déclaration. La déclaration suit la syntaxe
suivante :
<Type> <liste des variables> ;
Exemple : Déclarer une variable n de type entier
………………………………………………………………………………..
II- Instructions de base
Affectation
Elle se fait avec le symbole = (variable = expression;) → Expression est évaluée
est sa valeur sauvegardée dans variable.
Exemple : Affecter à la variable n la valeur 5.
………………………………………………..
NB : on peut affecter la valeur initiale à la variable lors de sa déclaration.
Exemple : Initialiser n à 10 lors de sa déclaration
………………………………..
Saisie des valeurs
Pour récupérer les valeurs saisies par un utilisateur et la placer dans une variable
var, on utilise la fonction suivante :
scanf ( "%descripteur" , &var);
Le programme attend jusqu'à ce que l'utilisateur ait saisi une valeur et valide. La
valeur saisie est alors affectée à la variable <variable>.
Attention à l’adresse &.
Exemple : lire un entier n ;
……………………………………
Affichage
Pour afficher le contenu d’une variable à l’écran, on utilise la fonction :
printf ( "%descripteur" , <variable >);
Exemple : afficher le message et la variable n
printf ( " la valeur lue est %d" ,n ) ;
ou autre exemple
printf ( " les valeurs sont x=%d , y=%d e t z = %d ’’, x , y , z ) ;
Les caractères spéciaux :
Fin de ligne : \n
Tabulation : \t
Types de données
Trois types de base servent à représenter les entiers :
Nom
taille(t)
nombre de valeurs
Short
Int
Long
1 octet
2 octets
4 octets
28 valeurs
216 valeurs
232 valeurs
chaîne
format
%hd
%d
%ld
de
Entiers non signés
Par défaut, les entiers permettent de stocker des valeurs de signe quelconque. Il
est préfixé de unsigned,
Nom
taille (t)
nombre de valeur min
valeur
format
valeurs
max
(28t)
unsigned
1 octet
28 valeurs
0
28 -1
%hu
short
unsigned
2 octets
216 valeurs
0
216 -1
%u
int
unsigned
4 octets
232 valeurs
0
232 -1
%lu
long
Entiers signés
Si par contre les données sont signées, on a comme plage de valeurs
Nom
taille (t)
nombre
de plus
petite plus grande
valeurs
valeur
valeur
Short
1 octet
28 valeurs
-27
27 - 1
Int
2 octets
216 valeurs
-215
215 - 1
Long
4 octets
232 valeurs
-231
231 - 1
Caractères
Le type d’un caractère est char. Un char sert à représenter le code ASCII d'un
caractère, il est donc codé sur 1 octet. Le descripteur d’un char est %c.
Affectation
char a ;
…………………………….
Constantes
Une constante est une valeur portant un nom, elles ne sont donc pas modifiables.
On les définit dans l'entête de la source, juste en dessous des #include.
La syntaxe est
#define <NOM CONSTANTE> <valeurConstante>,
Exemple : créer une constante Max ayant la valeur 100
…………………………………
Opérateurs
Les opérateurs en C peuvent être d’arité 1 (opérateur unaire) ou 2 (opérateur
binaire). Un opérateur peut être préfixé (opération avant l’opérande) ou postfixé
(opérateur près opérande)
Les opérateurs unaires
Opposée
L’opposée d’un nombre x s’obtient en –x.
Complément binaire
Le complément binaire d’une variable x s’obtient en ~x ; cet opérateur
complémente bit à bit l’opérande x.
Le cast
Il consiste à convertir une variable à un type compatible, par exemple de l’entier
au réel.
Tous les opérateurs unaires sont de priorité équivalente, le parenthésage
implicite est fait le plus à droite possible, on dit que ces opérateurs sont
associatifs à droite.
Opérateurs binaires
décalages de bits
1. L'opération a >> n effectue n décalages des bits de la représentation
binaire de a vers la droite.
2. L’opération a << n effectue n décalage des bits de la représentation
binaire de a vers la gauche.
NB : n est un entier positif.
Opérations logiques
1. L'opérateur & permet de faire l’opération binaire ET de deux
représentations binaires.
2. L'opérateur | permet de faire l’opération binaire OU de deux
représentations binaires.
3. L'opérateur ^ associe à deux opérandes le OU exclusif de représentations
Les deux opérateurs de décalage sont de priorité équivalente : >>, << ; les
autres opérateurs ont une priorité inférieure à celle des précédents. Du plus
prioritaire au moins on a: &, ^, |. &
Opérateurs arithmétiques (*, /, %, +, -)
Ils permettent de faire respectivement la multiplication, la division, le modulo,
l’addition et la soustraction.
Les multiplications et divisions sont prioritaires sur les sommes et différence :
Noms
opérateurs
produit
*, /, %
Sommes
+, Formes contractées
Unaires
Il est possible d'incrémenter (augmenter de 1) la valeur d'une variable i en
écrivant i++, ou bien ++i.
De la même façon on peut décrémenter (diminuer de 1) i en écrivant i-- (forme
postfixe), ou bien –-i (forme préfixe).
Binaires
Toutes les affectations de la forme variable = variable operateurBinaire
expression peuvent être contractées sous la forme variable operateurBinaire=
expression.
Avant
a=a+b
a=a–b
a=a*b
a=a/b
a=a%b
a=a&b
a=a^b
a=a|b
après
a += b
a -= b
a *= b
a /= b
a %= b
a &= b
a ^= b
a |= b
Traitements conditionnels
Si ... Alors
Syntaxe
i f (<condi t ion >)
{
<Bloc instructions >
}
Les parenthèses ne sont pas obligatoires lorsque le bloc d’instructions contient
une seule instruction.
Comparaisons
La formulation d'une condition se fait souvent à l'aide des opérateurs de
comparaison. Les opérateurs de comparaison disponibles sont :
Opérateurs Définitions
==
égalité
!
Négation - complément
<, <=
Strictement inférieur à, inférieur ou égal à
>, >=
Strictement supérieur à, supérieur ou égal à
Exemple : écrire un programme qui demande à l’utilisateur de lire un nombre n,
puis affiche le message « nombre positif » si n est positif.
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
………………………………………………………….
Si ... Alors ... Sinon
Syntaxe
if (<condition >)
{
<bloc instructions 1 >
}
el se
{
<bloc instructions 2 >
}
Exemple : modifier l’exemple précédent les messages indiquant le signe du
nombre lu.
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
………………………………………………………………………………………………………
Opérateur ternaire
En plaçant l'instruction suivante à droite d'une affectation,
<variable> = (<condition >) ? <valeur si vrai> : < valeur si faux> ;
Où
Valeur si
vrai:
………………………………………………………………………………………………….
Valeur
si
faux :
……………………………………………………………………………………………
condition :……………………………………………………………………………………….
Exemple: donner l’expression pour calculer max le maximum de deux nombres n
et m.
…………………………………………………………………………………….
Switch
La syntaxe est la suivante :
switch(<nomvariable >)
{
case <valeur 1> : <bloc instructions 1 > ; break ;
case <valeur 2> : <bloc instructions 2 > ; break ;
...
case <valeur n> : <bloc instructions n > ; break ;
default : <Bloc instructions par défaut>
}
NB : Le « break » à la fin permet de sortir du switch en sautant les valeurs
suivantes.
Exemple : écrire un programme qui lit un numéro compris entre 1 et 7 et affiche
le jour de la semaine correspondant
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………..
Booléens
Une variable booléenne ne peut prendre que deux valeurs : vrai et faux. Il
n'existe pas de type booléen à proprement parler en C. On utilise des int pour
simuler le comportement des booléens. On représente la valeur booléenne faux
avec la valeur entière 0, toutes les autres valeurs entières servent à représenter
vrai.
Utilisation dans des if
Lorsqu'une condition est évaluée dans un test, cette condition prend à ce
moment la valeur vrai si le test est vérifié, faux dans le cas contraire
Connecteurs logiques
Ils permettent de tester simultanément deux ou plusieurs expressions logiques
dans la condition.
Les connecteurs || et && représentent respectivement le OU et le ET logiques
entre deux expressions booléennes, et peuvent s'appliquer à des valeurs (ou
variables) entières
Exemple : Ecrire une condition pour tester si un nombre n est paire et positif
……………………………………………………………………………………………………………
…………………..
Les priorités
Dans l’ordre décroissant, les priorités des opérations sont :
Noms
opérateurs
opérateurs unaires
cast, -, ~, !, ++, -Produit
*, /, %
Somme
+, décalage binaire
>>, <<
Comparaison
>, <, >=, <=
Egalité, différence
==, !=
ET binaire
&
OU Exclusif binaire
^
OU binaire
|
connecteurs logiques
&&, ||
if ternaire
() ? :
Affectations
=, +=, -=, : : :
Préprocesseur
Macro-instructions
Ce sont des instructions écrites une fois et que l’on peut les appeler à n’importe
quel endroit du programme pour faire une tâche. A la compilation, son code est
simplement recopié à l’endroit où l’appel est fait.
La syntaxe est :
#define NOM_MACRO <instruction>
Exemple : aller à la ligne suivante
#define LS printf ( "\n" )
Et dans le programme, il suffira d’écrire :
LS ; // comme toute autre instruction pour faire le saut de ligne.
Il est possible de paramétrer les instructions du préprocesseur. Cela se fait en
plaçant le paramètre entre parenthèses devant le nom de la macro.
Exemple : calculer le double de n par une macro
#define DOUBLE(n) (2* (n ) )
Et dans le programme, écrire DOUBLE(k) pour calculer 2*k.
Boucles
for
for(<initialisation > ; <condition> ; <pas>)
{
<bloc instructions>
}
Exemple : écrire un programme qui lit un nombre n positif et affiche les nombres
de 1 à n.
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
…………………………………….
while
while(<condition >)
{
<bloc instructions >
}
La condition est évaluée avant chaque passage dans la boucle, à chaque fois
qu'elle est vérifiée, on exécute les instructions de la boucle.
Exemple : lire une suite de nombres entiers qui se termine par un nombre négatif.
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………….
do ... while
La syntaxe de cette boucle :
do
{
<bloc instructions >
}
while(<condition >);
Le fonctionnement est analogue à celui de la boucle tant que à quelques détails
près :
-la condition est évaluée après chaque passage dans la boucle.
-On exécute le corps de la boucle tant que la condition est vérifiée.
En C, la boucle répéter ... jusqu'à est en fait une boucle répéter ... tant que, c'està-dire une boucle tant que dans laquelle la condition est évaluée à la fin. Une
boucle do ... while est donc exécutée donc au moins une fois.
De la même façon que pour la boucle while, le compteur est initialisé avant le
premier passage dans la boucle.
Exemple : reprendre l’exemple précédent avec une boucle do…while
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………
On peut convertir une boucle for en boucle while en procédant de la sorte :
<initialisation >
while(<condition >)
{
<bloc instruction >
<faire le pas>
}
Chapitre 2 : Types de données structurés
I- Tableaux
Un tableau est un regroupement de variables de même type, il est identifié par
un nom. Chacune des variables du tableau est numérotée, ce numéro s'appelle
un indice. Chaque variable du tableau est donc caractérisée par le nom du
tableau et son indice. En C, les indices commencent toujours à 0.
Déclaration
La syntaxe est la suivante :
<type> <nomdutableau>[<taille >] ;
Exemple : Déclarer un tableau de 10 entiers.
……………………………………………………………………………………………………………
Initialisation
Il est possible d'initialiser les éléments d'un tableau à la déclaration, on fait cela
comme pour des variables scalaires :
<type> <nom>[<taille >] = <valeur d’initialisation >;
On peut aussi disposer par ordre d'indice croissant en les séparant par des
virgules les éléments du tableau.
La syntaxe générale de la valeur d'initialisation est donc :
<type> <nom>[<taille >] = {<valeur 0 >, <valeur 1 >, . . . , <valeur n-1>}
Exemple : Déclarer un tableau initialisé par les valeurs 0,2,4,6,8;
…………………………………………………………………..
Accès aux éléments
Pour accéder à l’élément d’indice i, il faut faire T[i]. Il faut que i soit compris entre
0 et n-1. Généralement, on traite les éléments du tableau avec une boucle for.
tableaux à plusieurs indices
Déclaration
La syntaxe est la suivante :
<type> <nomdutableau>[<taille1 >][taille2]... ;
Exemple : Déclarer une matrice de 3*3 entiers.
…………………………………………………………………………………………………………
Initialisation
Comme les tableaux à une dimension, il est possible d'initialiser les éléments
d'un tableau à la déclaration, on fait cela comme pour des variables scalaires :
<type> <nom>[<taille1 >][taille2] = {liste des valeurs};
Attention : le nombre d'éléments doit être ……………………………………….
On peut aussi disposer les éléments ligne par ligne entre alcollades
La syntaxe générale de la valeur d'initialisation est donc :
<type> <nom>[<taille >] [ligne]= {{ligne1},{ligne2},….}
II- Chaînes de caractères
1. Définition
Une chaîne de caractères est un tableau de char contenant un caractère nul. Le
caractère nul a 0 pour code ASCII et s'écrit '\0'. Les valeurs significatives de la
chaîne de caractères sont toutes celles placées avant le caractère nul, donc le
caractère nul est la fin de chaîn..
2. Déclaration
Comme une chaîne de caractères est un tableau de char, on le déclare :
char <nom chaine>[<taille >] ;
Exemple : déclarer une chaine de 200 caractères.
Attention le dernier caractère est ‘\0’
………………………………………
Initialisation
On peut initialiser une chaîne à la déclaration :
char <nom chaine>[<taille >] = <valeur_initiale>;
valeur initiale :………………………………………………………………………………………..
Exemple : déclarer une chaîne initialisée à votre nom.
…………………………………………………………………….. ;
Accès aux éléments
Par accéder à l’élément d’indice i+1 de la chaîne ch, il faut écrire la sorte : ch[i]
Exemple : écrire un programme (instruction) pour tester si un caractère est en
majuscule.
………………………………………………………………………………………………..
Affichage
On peut afficher une chaîne comme un tableau de caractères, ou comme une
chaîne avec le descripteur ‘%s’.
Exemple : afficher la variable qui contient votre nom.
Saisie
Pour obtenir une chaîne ch par saisie au clavier, on utilise la fonction gets(ch)
Une autre syntaxe est la suivante :
fgets (<chaine >, <taille >, stdin ) ;
La taille de la chaîne saisie est limitée par <taille>, caractère nul compris. Le
résultat est placé dans <chaine>. Tous les caractères supplémentaires saisis par
l'utilisateur ne sont pas placés dans <chaine>, seuls les (<taille> - 1) premiers
caractères sont récupérés par fgets. Nous saisirons donc la phrase de notre
programme de la sorte : fgets ( c , 200 , stdin ) ;
La bibliothèque string.h
Elle propose des fonctions de maniement de chaînes de caractères, à savoir :
 strcmp : comparer deux chaînes.
 strlen : longueur d'une chaîne de caractères
 strsubs : rechercher une sous-chaîne
 strcat : concaténer deux chaînes
 strcpy : copier une chaîne
Il vous est conseillé d'examiner de quelle façon fonctionnent ces fonctions, et
comment elles gèrent le caractère nul.
III- Les pointeurs
L'opérateur & pour désigner l’adresse d’une lvalue. D’une manière générale, le
langage C permet de manipuler des adresses par l’intermédiaire de variables
nommées pointeurs. Considérons les instructions :
int * ad ;
int n ;
n = 20 ;
ad = &n ;
*ad = 30 ;
La première réserve une variable nommée ad comme étant un pointeur sur des
entiers. * est un opérateur qui désigne le contenu de l’adresse qui le suit. Ainsi, à
titre mnémonique, on peut dire que cette déclaration signifie que *ad.
Une variable pointeur ad a été déclarée ainsi : int * ad ;
une expression telle que : ad + 1
a un sens pour C.
En effet, ad est censée contenir l’adresse d’un entier et, pour C, l’expression cidessus représente l’adresse de l’entier suivant.
En ptr++ avance ptr du nombre sizeof(). Par exemple ad++ avance ad de
sizeof(int).
Supposons, par exemple, que l’on effectue la déclaration suivante :
int t[10] ;
La notation t est alors totalement équivalente à &t[0] . L’identificateur t est
considéré comme étant de type pointeur sur le type correspondant aux
éléments du tableau, c’est-à-dire, int *. Ainsi, les notations équivalentes :
t+1 → &t[1]
t+i → &t[i]
t[i] → * (t+i)
Pour illustrer ces nouvelles possibilités de notation, voici plusieurs façons de
placer la valeur 1 dans chacun des 10 éléments de notre tableau t :
for (int i=0 ; i<10 ; i++)
* (t+i) = 1 ;
V- Les structures et les énumérations
1. Structure
Il s'agit de l'équivalent de l'enregistrement en algorithmique.
Déclaration d’une structure
Voyez tout d’abord cette déclaration :
struct enreg
{
type champ ;
type champ ;
type champ ;
…….
};
Celle-ci définit un modèle de structure mais ne réserve pas de variables
correspondant à cette structure. Ce modèle s’appelle ici enreg et il précise le nom
et le type de chacun des champs constituant la structure.
Déclaration d'une variable
struct enreg var
exemple : un article est caractérisé par un numéro, une quantité et un prix.
Donner la déclaration.
struct enreg
{
int numero ;
int qte ;
float prix ;
};
struct enreg art1, art2 ;
On peut aussi procéder de la manière suivante :
struct article
{
int numero ;
int qte ;
float prix ;
} art1, art2 ;
En mettant le mot typedef à la création, cela évite d'utiliser le mot struct à la
création des variables.
Utilisation
La désignation d’un champ se note en faisant suivre le nom de la variable
structure de l’opérateur « point » ( . ) (comme en algorithmique) suivi du nom de
champ tel qu’il a été défini dans le modèle (le nom de modèle lui-même
n’intervenant d’ailleurs pas).
Exemple :
art1.qte=20 ;
printf ("%e", art1.prix) ;
scanf ("%e", &art2.prix) ;
art1.numero++ ;
Il est possible d’affecter à une structure le contenu d’une structure définie à
partir du même modèle. Par exemple, si les structures art1 et art2 ont été
déclarées suivant le modèle enreg défini précédemment, nous pourrons écrire :
art1 = art2 ;
Une telle affectation globale remplace avantageusement :
art1.numero = art2.numero ;
art1.qte = art2.qte ;
art1.prix = art2.prix ;
Initialisation
On peut initilisaer une structure de la manière :
struct enreg var={val1, val2,…}
Attention : les valeurs sont dans l'ordre des champs à la création de la structure.
Exemple : struct article art1 = { 100, 285, 2000 } ;
Chapitre 3 : les sous programmes
I - Les procédures
Une procédure est un ensemble d'instructions portant un nom. La syntaxe de
définition est :
void nomprocedure (paramètres)
{
<bloc d’instructions>
}
Son exécution se fait comme celle d’une instruction en utilisant son nom.
Exemple : printf(……….)
La procédure main() désigne la principale et se lance automatiquement au début
du programme.
Variables locales
Dans une procédure, il est possible de définir les variables, ces variables sont
traitées de variables locales. Elles sont déclarées comme dans la procédure
main(). Les variables locales ne sont visibles que dans la procédure où elles ont
été déclarées. La structure d’une procédure est la suivante :
void nomprocedure (paramètres)
{
/*
Declaration des variables locales
*/
<bloc d’instructions>
}
Passage de paramètres
Il est possible que la valeur d'une variable locale d'une procédure ne soit connue
qu'au moment de l'appel de la procédure.
A l’appel d’une procédure, les paramètres effectifs lui sont communiqués. Chaque
paramètre N°i représente l’argument N°i de la définition ou de la déclaration. Les
types doivent être respectés. Ces paramètres doivent être des variables
déclarées dans la procédure appelante.
Exemple : écrire une procédure qui prend un entier n en paramètres et affiche
tous les nombres compris entre 0 et n. Ecrire la procédure main() qui lit un entier
m et passe en paramètre à la procédure.
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
………….
II- Les fonctions
principe
Nous avons vu qu'un sous-programme appelant peut communiquer des valeurs
au sous-programme appelé. Il est aussi possible pour un sous-programme appelé
de communiquer une valeur au sous-programme appelant. Une fonction est un
sous-programme qui communique une valeur au sous-programme appelant.
Cette valeur s'appelle valeur de retour, ou valeur retournée.
La syntaxe de définition d’une fonction est :
Type nomFonction (paramètres)
{
/*
Declaration des variables locales
*/
<bloc d’instructions>
Return <valeur de retour>
}
Return :
……………………………………………………………………………………………………………
………….
NB : en C les procédures sont les fonctions qui ont pour type void.
La syntaxe pour appeler une fonction est :
v = nomFonction (paramètres) ;
L'instruction ci-dessus place dans la variable v la valeur retournée par la fonction
nomFonction quand lui passe les paramètres.
Exemple : écrire une fonction qui prend un nombre en paramètre et retourne son
carré. Appelez cette fonction dans le main().
Passages de paramètre par référence
En C, lorsque vous invoquez une fonction, toutes les valeurs des paramètres
effectifs sont recopiés dans les paramètres formels. On dit dans ce cas que le
passage de paramètre se fait par valeur. Dans ce cas seule la valeur de retour
vous permettra de communiquer une valeur au programme appelante une seule
valeur.
Lorsque vous passez un tableau en paramètre, la valeur qui est recopiée dans le
paramètre formel est l'adresse de ce tableau (l'adresse est une valeur scalaire).
Par conséquent toute modification effectuée sur les éléments d'un tableau dont
l'adresse est passée en paramètre par valeur sera repercutée sur le paramètre
effectif (i.e. le tableau d'origine). On dit alors le paramètre passé par
Référence. Donc un paramètre doit contenir un résultat à la fin d’une procédure,
il faut le passer par référence. Les règles sont les suivantes :
 Les variables scalaires se passent en paramètre par valeur
 Les variables non scalaires se passent en paramètre par référence
 Une fonction ne peut retourner que des valeurs scalaires
chapitre 4 : Fichiers
Définitions
Le problème qui se pose est que lorsque l'on sort de ce programme, les données
saisies sont perdues. Si l'on souhaite les avoir à disposition pour d'une exécution
ultérieure, il convient d'utiliser un fichier. Un fichier peut être vu comme une
mémoire stockée de façon permanente sur un disque et à laquelle on accède
avec un nom. Les données dans un fichier se présentent de façon séquentielle, et
donc se lisent ou s'écrivent du début vers la fin.
Ouverture et fermeture
Pour accéder au contenu d'un fichier en lecture ou en écriture, on utilise la
fonction fopen() et pour fermer la fonction fclose().
La fonction fopen()
fopen permet, comme son nom l'indique, d'ouvrir un fichier. Sa syntaxe est :
FILE *fopen(const char *chemin, const char *mode) ;
Où
Chemin : ……………………………………………………………… ………………………………
……………………………………………………………………………………………………………
……………………..
mode : …………………………………………………… …………………………………………
FILE* est un type permettant de référencer un fichier ouvert,
La fonction fopen retourne NULL s'il est impossible d'ouvrir le fichier. La valeur
retournée devra être placée dans une variable de type FILE*, c'est cette valeur
qui permettra par la suite d'accéder au contenu du fichier.
La fonction fclose
fclose sert à fermer un fichier. Son prototype est int fclose(FILE *fp) ;
Cette fonction retourne 0 si la fermeture s'est bien passée. Dans le cas contraire,
des indications sur l'erreur survenue sont accessibles dans des variables
globales.
Utilisation
Exemple : Ouvrir et fermer le fichier des étudiants
……………………………………………………………………………………………………………
……………………………………………………………………………………………………………
………………………………………………………………………………………….
Lecture et écriture
Il existe plusieurs façons de lire dans un fichier :
 caractère par caractère,
 ligne par ligne,
 par paquets de caractères, etc.
Chaque lecture se fait à l'aide d'une fonction appropriée. Lors d'un traitement se
faisant à partir d'une lecture dans un fichier, on appelle de façon itérée une
fonction de lecture faisant avancer un curseur dans un fichier jusqu'à ce que la
fin du fichier soit atteinte.
L'écriture fonctionne de façon analogue, à un détail près : il est inutile d'écrire le
caractère de fin de fichier, il est ajouté automatiquement lors du fclose.
Caractère par caractère
La fonction int fgetc(FILE* stream) retourne un caractère lu dans le fichier f. Bien
que le caractère lu soit un octet, il est retourné dans un int. Le caractère EOF
indique que la fin du fichier a été atteinte.
Exemple: afficher le contenu du fichier des étudiants
#include<stdio.h>
int main ( )
{
FILE* f ;
char c ;
f = fopen ( "toto.txt " , " r " ) ;
i f ( f == NULL)
{printf ( "Erreur lors de l 'ouverture du fichier toto.txt \n" ) ;
return -1;}
while ( ( c = fgetc ( f ) ) != EOF)
printf ( " %c” , c ) ;
i f ( fclose ( f ) != 0)
{printf ( "Erreur lors de l a fermeture du fichier toto.txt \n" ) ;
return -1;}
return 0 ;
}
On écrit un caractère dans un fichier à l'aide de la fonction
int fputc(int c, FILE* stream) ;
Par chaînes de caractères
Les deux fonctions char *fgets(char *s, int size, FILE *stream) et int fputs(const
char*s, FILE *stream) permettent de lire et d'écrire des chaînes de caractères
dans des fichiers.
Par paquets
Les deux fonctions size t fread(void *ptr, size t size, size t nmemb, FILE *stream)
et size t fwrite(const void *ptr, size t size, size t nmemb, FILE *stream) sont très
utiles lorsque l'on veut sauvegarder un tableau dans un fichier, ou recopier un
fichier dans un tableau.
Téléchargement