Techniques Deprogram C
Techniques Deprogram C
Techniques Deprogram C
Langage C
1ère Année GC
Ecole Hassania des Travaux Publics
1
Un algorithme
Origine étymologique:
– Vient du nom du mathématicien Al Khawarizmi latinisé en
« algoritmi »
Définitions:
– Académie Française: Méthode de calcul qui indique la
démarche à suivre pour résoudre une série de problèmes
équivalents en appliquant dans un ordre précis une suite
finie de règles.
– Wikipedia: Un algorithme est un moyen pour un humain de
présenter la résolution par calcul d’un problème à une autre
personne physique (un autre humain) ou virtuelle (un
2 calculateur)
Qualités d’un bon concepteur
d’algorithmes
L’intuition:
– Pas de méthode universelle absolue pour résoudre
un problème
La rigueur et la logique
– La méthodologie, la capacité à se mettre à la place
de la machine et d’être aussi idiot qu’elle!
L’expérience
– Renforce les deux premiers points
– Plus on écrit d’algorithmes, plus on est performant à
3 le faire
Algorithmique Vs programmation
4
Le Langage C
5
Origine
6
Etapes de développement d’un
programme C
8
Un fichier code source C…
10
L’intérêt des variables
La déclaration
L’instruction d’affectation
La lecture/écriture
La libération
12
Les variables en C
Deux cas
– Les opérandes sont du même type:
Le résultat est du même type que ces opérandes
– Les opérandes sont de deux types (numériques) différents
le compilateur prévoit une conversion implicite suivant l'ordre :
{ char -> int -> long -> float -> double } et { unsigned -> signed}
Le compilateur considère aussi les valeurs de type
« char » comme des entiers, les opérations sont en fait
faites sur les valeurs de code (ASCII)
Les calculs arithmétiques sont faits uniquement soit en
long soit en double, pour éviter des dépassements de
17 capacité
Exemples (1/2)
int a=1,b=2,c=34000;
float x=1,y=2.0;
a=(c*2)/1000;
– Même si on suppose qu’un entier est codé sur 2 octets, le
résultat est 68, même si l'on est passé par un résultat
intermédiaire (68000) qui dépassait la capacité des entiers (mais
pas celle des long)
b=7/b;
– signe = donc en premier calcul de l'argument à droite : 7 (entier) /
2 (entier) donne 3 (entier, reste 1, que l'on obtient par 7%b). donc
18 b=3
Exemples (2/2)
int a=1,b=2,c=34000;
float x=1,y=2.0;
x=7/b;
– 7 et b entiers => passage en réel inutile, calcul de 7/2 donne 3
(entier, reste 1) puis opérateur = (transformation du 3 en 3.0 puis
transfert dans X qui vaut donc 3.0) */
x=7/y;
– un int et un float autour de / : transformation implicite de 7 en réel
(7.0), division des deux réel (3.5), puis transfert dans x
x=((float)(a+2))/b;
– calcul (entier) de a+1, puis transformation explicite en float, et
donc implicite de b en float, division 65.0/3.0 -> 21.666...
19
Opérateurs relationnels
Comparaisons
– == égalité,
– != différent,
– <, >, <=, >=
Des deux côtés du signe opératoire, il faut deux opérandes
de même type (sinon, transformation implicite) mais
numériques (les caractères sont classés suivant leur code
ASCII).
Le résultat de l'opération est de type int :0 si faux, 1 si vrai
Exemple : (5<7)+10*((1+1)= =2) donne 11
20
Logique booléenne (1/2)
21
Logique booléenne (2/2)
Opérateur unaire :
– ! (non).
!arg vaut 1 si arg vaut 0, et 0 sinon.
Opérateurs binaires :
– && correspond à l’opérateur ET
vaut 1 si les 2 opérandes sont non nuls, 0 sinon
– || correspond à l’opérateur OU
vaut 0 si les deux opérandes sont nuls, 1 sinon
Le deuxième opérande n'est évalué que si le premier n'a pas
suffi pour conclure au résultat
exemple: (a= =0)&&((x=x+1)<0) incrémente x si a est nul, le
laisse intact sinon.
22
opérations bit à bit
7&12 donne 4
– 0111&1100 donne 0100
5<<2 donne 20.
– 00..00101 décalé de deux positions à gauche
donne 00..10100
24
Opération d’affectation
a=5
– met la valeur 5 dans la variable a. Si a est float, il y a conversion
implicite en float
b=(a*5)/2
– Effectue le calcul d'abord, puis met le résultat dans b
a=5+(b=2)
– Le compilateur lit l'expression de gauche à droite. la première
affectation nécessite le calcul 5+(b=2). Celle ci comporte une
addition, dont il évalue le premier opérande (5) puis le second
(b=2). Il met donc 2 dans b, le résultat de l'opération est 2, qui
sera donc ajouté à 5 pour être mis dans a. La variable a vaut
26 donc 7 et b, 2. Le résultat de l'expression est 7 (si l'on veut s'en
servir).
Big Warning!!!
27
Mathématique Vs Informatique
+ =,
-=,
*=,
/=,
%=,
&=,…
Exemples
– a+=5 est équivalent à a=(a+5).
30 – a&=1 est équivalent à a=(a&&1)
Opérateurs d’adresses
31
L’operateur conditionnel ?
Exemple :
– val=a>b?a:b
32
opérateurs description
*/% multiplicatifs
+- addition
= = != égalité
& binaire
Priorités par ordre
^ binaire
| binaire
décroissant
&& logique
|| logique
?: conditionnel (ternaire)
= += -= *= etc. affectation
33
Exo1
35
La Lecture/Ecriture
36
Motivation
38
Lecture/écriture des caractères
char putchar(char) :
– affiche sur l'écran (ou du moins stdout) le
caractère fourni en argument
– stdout est l'écran, ou un fichier si on a redirigé
l'écran (en rajoutant ">nomfichier" derrière l'appel
du programme, sous DOS ou UNIX).
– cette fonction retourne le caractère affiché ou
EOF en cas d'erreur.
char getchar(void) :
– attend le prochain appui sur le clavier, et rend le
39
caractère qui a été saisi
Lecture/écriture des chaînes de
caractères
puts(chaîne)
– affiche, sur stdout, la chaîne de caractères puis positionne le
curseur en début de ligne suivante.
– retourne EOF en cas d'erreur
gets(chaîne)
– lecture d'une chaîne sur stdin. Tous les caractères peuvent être
entrés, y compris les blancs.
– La saisie est terminée par un retour chariot. gets retourne un
pointeur sur le premier caractère entré (donc égal à son
paramètre d'entrée, ou le pointeur NULL en cas d'erreur).
40
écriture des chaînes de
caractères: printf
printf(format,listevaleurs)
– affiche la liste de valeurs (variables ou expressions)
dans le format choisi.
– format est
une chaîne de caractères entre guillemets (double quote "),
dans laquelle se trouve un texte qui sera écrit tel quel,
des spécifications de format (débutant par %) qui seront
remplacées par la valeur effective des variables, dans l'ordre
donné dans listevaleurs,
– retourne le nombre de caractères écrits, ou EOF en
cas de problème.
41
Spécification du format
% [largeur][.précision]type, avec
– La largeur est le nombre minimal de caractères à écrire (des blancs sont
rajoutés si nécessaire).
– Si le texte à écrire est plus long, il est néanmoins écrit en totalité.
– En donnant le signe * comme largeur, le prochain argument de la liste de
valeurs donnera la largeur
– ex printf("%*f",largeur,val)
La précision définit,
– Pour les réels, le nombre de chiffres après la virgule (doit être inférieur à
la largeur).
– Dans le cas d'entiers, indique le nombre minimal de chiffes désirés (ajout
de 0 sinon)
– Pour une chaîne (%s), elle indique la longueur maximale imprimée
(tronqué si trop long).
42 La précision peut, comme la largeur, être variable en préfixant par: .*
Les caractères spéciaux pour
l’affichage
\t (tabulation),
\n (retour à la ligne),
\\ (signe \),
43
Les types pour les formats
scanf(format,listeadresse)
– lecture au clavier de valeurs, dans le format
spécifié.
– les arguments sont des pointeurs sur les
variables résultats (dans le cas de variables
scalaires, les précéder par l'opérateur &).
– retourne le nombre de valeurs effectivement lues
et mémorisées.
45
Le format pour scanf
47
Exo3
48
Exo4
49
Les structures de
contrôle
50
Les instructions
– Le branchement if
– Le branchement switch
53
Le branchement if
structure :
– if (expression) instruction1
– Ou: if (expression) instruction1 else instruction2
Même sémantique que le concept général
« Si Alors Sinon » en Algorithmique
– Si l'expression est vraie on effectue l'instruction1,
puis on passe à la suite.
– Sinon, on effectue l'instruction 2 puis on passe à
la suite.
54
Exo5
55
Tests imbriqués: motivation
56
Tests imbriqués
58
Exo6
59
Exo7
int voyelle(char c)
switch(c) {
case 'a': return(1);
case 'e': return(1);
case 'i': return(1);
case 'o': return(1);
case 'u': return(1);
case 'y':return(1);
default :return(0);
63 }
L’instruction break
65
Branchements inconditionnels
Sémantique:
– Quand on arrive sur une telle instruction, on se branche
obligatoirement sur une autre partie du programme
66
continue
70
return
Permet de
– sortir de la fonction actuelle
– rendre la valeur résultat de la fonction.
structure :
– return; ou return(expression);
exemple :
int max(int a, int b) {
if (a>b) return(a);
71 else return(b);}
exit
72
Les boucles
73
Justification, un exemple (1/2)
75
La Boucle while
77
Exemple
int a;
do {
puts("veuillez entrer le nombre 482");
scanf("%d",&a);
}
while (a!=482);
puts("Merci!");
78
Exo11
79
Exo12
80
Exo13
81
Exo14
82
Boucle for (1/2)
structure :
– for ( expr_initiale;expr_condition;expr_incrémentation) instruction
Equivalente sémantiquement à la boucle « Pour »
Cette boucle est surtout utilisée lorsque l'on connaît à
l'avance le nombre d'itérations à effectuer.
– L'expr_initiale est effectuée une fois, en premier.
– Puis on teste la condition.
– On effectue l'instruction puis l'incrémentation tant que la condition
est vraie.
– L'instruction et l'incrémentation peuvent ne jamais être
effectuées.
83
Boucle for (2/2)
{ char c;
for(c='Z';c>='A';c--) putchar(c);
}
85
Exo15
87
Exo17
88
Exo 18
89
Exo19
91
Gestion des variables
92
Gestion des variables lors de
l’exécution
int double(int b)
{int c;
c=2*b;
b=0;
return(c); }
int main()
{ int c=5;
printf("%d %d\n",double(c),c); }
94
Durée de vie et visibilité
auto :
– la variable est créée à l'entrée du bloc (dans la
pile) et libérée automatiquement à sa sortie.
98
Les classes des variables (2/3)
register :
– la variable est créée, possède la même durée de vie et visibilité
qu'une classe auto,
– mais sera placée dans un registre du (micro)processeur.
– Si tous les registres sont déjà utilisés, la variable sera de classe
auto.
– Avantages
Accès très rapide
– Inconvénients
le compilateur peut avoir besoin des registres pour ses besoins
internes ou pour les fonctions des bibliothèques
les compilateurs optimisés choisissent de mettre en registre des
99 variables auto, et souvent de manière plus pertinente que vous!
Les classes des variables (3/3)
static :
– La variable ne sera pas dans la pile mais dans la
même zone que le code machine du programme.
– Sa durée de vie sera donc celle du programme.
– Elle ne sera initialisée qu'une fois, au début du
programme, et restera toujours réservée.
– Sa visibilité reste la même (limitée au bloc).
– Une variable statique permet en général un gain en
temps d'exécution contre une perte en place mémoire.
100
Déclaration globales
102
Autres classes des déclarations
globales
La classe static
– rend la visibilité de la variable limitée au fichier
actuel.
La classe extern
– permet de déclarer une variable d'un autre fichier
(et donc ne pas lui réserver de mémoire mais la
rendre visible).
– Elle ne doit pas être initialisée à cet endroit.
– Une variable commune à plusieurs fichiers devra
103
donc être déclarée sans classe dans un fichier et
Exemples
107
Définitions générales
108
Gestion des arguments d’une
fonction
void hello( )
{
int i;
for(i=0;i<10;i++)
printf("bonjour les gars!");
}
Appel: hello();
110
Exemple: elle ne retourne rien
111
Exemple: elle prend et retourne
112
Un seul type de retour pour les
fonctions
113
déclaration des fonctions
114
Classes des fonctions
116
Analysons la gestion de la pile
121
Les types de données
du langage C
122
Les types de variables
123
Le type scalaire: char
124
Le type scalaire: int
126
Taille et plages des types scalaires
type taille (en bits) plage de valeurs
130
Concept
Un tableau est un regroupement, dans une même variable,
de plusieurs variables simples, toutes de même type.
déclaration :
– [classe] type nom [nombre_d'éléments];
exemple :
– int tab[10];
– réserve en mémoire un espace contigu pouvant contenir 10
entiers
– Le premier élément est tab[0] et le dernier c’est tab[9]
– Si vous utilisez tab[10] ou plus,
pas forcément d’erreur
131 Vous allez récupérer ce qui a dans la mémoire correspondante
(probablement réservée pour autre chose!)
Les tableaux
#include <stdlib.h>
char *tab;
int nb;
puts("donner la taille");
scanf("%d",&nb);
tab=(char*) calloc(nb,sizeof(char));
138
D’autres fonctions
stdlib.h ou alloc.h (selon le compilateur)
141
Petit exo:
Ecrire un programme C avec les fonctions suivantes:
– Une fonction « affichage » qui affiche une matrice d’entiers
sachant sa dimension
– Une fonction « saisie » qui prend en paramètre deux entiers et
permet de remplir les éléments d’une matrice avec la dimension
correspondante. Elle retourne la matrice ainsi instanciée
– Une fonction qui prend en paramètres deux matrices ainsi que
leurs dimensions et retourne dans un troisième paramètre (quand
cela est consistant) la matrice résultant de leur multiplication
– La fonction main qui utilisera les fonctions précédente et
permettant de
Saisir deux matrices ainsi que leurs dimensions
142 Afficher les deux matrices saisies ainsi que la matrice résultant de leur
multiplication
Les structures
143
Concept
La déclaration
– struct nom_type {déclaration champs} liste_variables;
Exemple:
– struct client { char* nom;
char* prenom;
char* mail;
int tel;
}
Toto,Titi,MesClients[20];
Déclaration d’une variable:
145 – struct client tutu;
Traitements sur les structures
147
Motivation
150
Ouverture et fermeture de fichiers
bruts
L’ouverture d’un fichier est la première action à réaliser:
– int open(char *nomfic, int mode);
– Nomfic: le nom fichier à ouvrir
– Mode correspond au mode des interactions avec le fichier:
O_RDONLY lecture seule,
O_WRONLY écriture seule,
O_RDWR lecture et écriture
O_APPEND positionnement en fin de fichier (permet d'augmenter le fichier),
O_CREAT crée le fichier s'il n'existe pas, au lieu de donner une erreur, sans
effet s'il existe
O_TRUNC vide le fichier s'il existait
On peut combiner cet accès avec d'autres spécifications, par une opération
OU (|)
– Retourne -1 si erreur, un nombre positif si l’ouverture a été réalisée
151 correspondant au handle attribué au fichier ouvert
Lecture
156
Exemple (2/2)
if((source=open(argv[1],O_RDONLY|O_BINARY))<0) {
puts("erreur ouverture");return(2);}
if((destination=open(argv[2], O_WRONLY| O_CREAT|
O_TRUNC| O_BINARY))<0)
{puts("erreur ouverture");return(2);}
do {
nb_lus=read(source,buffer,taillebloc);
if (nb_lus>0) nb_ecrits= write(destination,buffer, nb_lus); }
while ((nb_lus==taillebloc)&&(nb_ecrits>0));
close(source);
close(destination);
return(0); }
157
Fichiers bufférisés
Niveau caractères:
– char fgetc(FILE *id),
lit un caractère
– char fputc(char c, FILE *id),
écrit un caractère
– char ungetc(char c, FILE *id),
permet de "reculer" d'un caractère,
équivalent à {fseek(id,-1,1);c=fgetc(id)}
163
Données formatées (chaînes de
caractères)
164
Données formatées (chaînes de
caractères)
165
Exemple avec les structures (1/2)
Client C[100];
int nbr=0;
…
FILE * fic=fopen("toto.txt", "a");
for(i=0;i<nbr;i++)
{
fwrite(C[i], sizeof(struct client), 1, fic);
}
fclose(fic);
166
Exemple avec les structures (1/2)
fic=fopen("toto.txt", "r");
Client c1=(Client) malloc(sizeof(struct client));
j=fread(c1,sizeof(struct client), 1, fic);
while(j>0)
{
printf("Nom: %s, prenom: %s, solde: %d\n",c1->nom,
c1->prenom,c1->solde);
j=fread(c1,sizeof(struct client), 1, fic);
}
167 fclose(fic);
MERCI DE VOTRE ATTENTION
168