1
Christophe CRUZ Bureau n° 5
christophe.cruz@u-bourgogne.fr
2
Enseignement
• Cours de la semaine 36 à la semaine 23
• 15 semaines de 4 heures
• Examens et contrôles continus
3
Notation
• 1 devoir surveillé de coef. 1
• 1 moyenne des contrôles continus coef. 1
• 1 contrôle de TP coef. 1 Informations Générales
4
Contenu du cours
• Partie pratique
Programmation C et Appels systèmes Linux / Unix / Dos / Windows (Installation openBSD / Virtual PC )
• Partie théorique
Principes sous-jacents à tous S.E.
Compositions / caractéristiques / algorithmes Informations Générales
5
Les chapitres
0. Programmation C
1. Introduction sur les systèmes d’exploitation 2. Les systèmes de gestion des fichiers 3. Les processus
4. La communication entre processus 5. La concurrence entre processus 6. L’ordonnanceur
Objectifs : maîtriser et utiliser conjointement les notions Informations Générales
SGD
Proc. Commun.
6
Systèmes d’exploitation
Chap. 0
Programmation C
7
Plan
1. Introduction
2. Les structures de contrôle 3. Les données mémoires 4. Passage de paramètres 5. La chaîne de compilation 6. Le préprocesseur
7. Les entrées-sorties standards 8. L’allocation dynamique
8
Plan
1. Introduction
2. Les structures de contrôle 3. Les données mémoires 4. Passage de paramètres 5. La chaîne de compilation 6. Le préprocesseur
7. Les entrées-sorties standards 8. L’allocation dynamique
9
1.Introduction
L'Assembleur (ASM) John Von Neumann (1945) 1er langage de programmation l'interruption BIOS/DOS
ou un API de Windows.
Un langage par architecture (Intel x86, Risc, Arms, etc.)
#Mode vidéo dos
#Entée
#Sortir
Chap. 0 – Rappels de langage C
10
1.Introduction
• Plus de 90% du noyau du système UNIX et Linux est écrit en langage C.
• Le compilateur C est écrit en grande partie
en langage C ou à partir d’outils générant du langage C.
• Il en est de même pour les autres outils de la chaîne de compilation (assembleur, éditeur de liens, pré-processeur).
• De plus, tous les utilitaires du système sont écrits en C (shell, outils).
Chap. 0 – Rappels de langage C
11
1.Introduction
Les bibliothèques standards contiennent :
– des fonctions de manipulation de chaînes de caractères.
– des fonctions permettant la gestion des entrées-sorties (E/S).
– des fonctions d’allocation dynamique de mémoire.
– des fonctions à caractère général qui permettent l’accès au système.
Chap. 0 – Rappels de langage C
12
1.Introduction
• Un programme C est un ensemble de fonction
• Les fonctions (et leur code) sont réparties dans un ou plusieurs fichiers textes avec une exetension« .c »
Ex: monprogramme.c
• Une des fonctions doit se nommer main pour que le code soit exécutable
int main(int argc, char * argv[]) int main(int argc, char ** argv) argc : nombre de parammètres
argv : tableau de pointeurs de chaîne de caractères Chap. 0 – Rappels de langage C
13
1.Introduction
• Syntaxe des fonctions
type_de_retour nom_fonction ( liste_des_paramètres ) { code } int readBlock ( int deplacement, int type){ …}
• Toute fonction doit être déclaréeavant d’être utilisée
• Les structures de contrôles et les opérateurs sont les mêmes que le C++ (à quelques restrictions près)
• Les définitions de variables doivent être placées avant leurs utilisations
• Une définition de variable n’initialisepas la variable (valeur inconnue avant première affectation)
14
15
Chap. 0 – Rappels de langage C
Plan
1. Introduction
2. Les structures de contrôle 3. Les données mémoires 4. Passage de paramètres 5. La chaîne de compilation 6. Le préprocesseur
7. Les entrées-sorties standards 8. L’allocation dynamique
16
2. Les structures de contrôle a) Les test :
if (expression) instruction
if (expression) instruction1 else instruction2
if (expression) instruction1 else if (expression2) instruction2 else if (expression3) instruction3
…
else if (expressionN) instructionN else instructionN+1
Chap. 0 – Rappels de langage C
17
2. Les structures de contrôle b) Les boucles :
while (expression) instruction
do instruction while (expression);
for (expression1; expression2; expression3) instruction
Chap. 0 – Rappels de langage C
18
2. Les structures de contrôle c) L’instruction switch :
switch (expression){
case expression-constante1 : instructions break;
case expression-constante2 : instructions break;
…
case expression-constanteN : instructions break;
default :
instructions break ; }
Chap. 0 – Rappels de langage C
19
2. Les structures de contrôle d) Rupture de séquence :
break;
break exécute une sortie d’un bloc d’instructions dépendant de l’une des instructions suivantes do, for, while, ou switch.
continue;
Instruction forçant le passage à l’itération suivante de la boucle la plus proche.
goto label;
label : instruction
L’instruction goto permet de se brancher inconditionnellement à instruction. A éviter absolument.
return [expression];
Exécute une sortie d’une fonction en rendant le contrôle à la fonction appelante, tout en retournant la valeur d’un expression si la fonction appelée l’autorise ( ≠ void ).
20
Plan
1. Introduction
2. Les structures de contrôle 3. Les données mémoires 4. Passage de paramètres 5. La chaîne de compilation 6. Le préprocesseur
7. Les entrées-sorties standards 8. L’allocation dynamique
21
3. Les données mémoires a) Les Types élémentaires :
Les entiers
« int » est un short ou un long selon le compilateur 0 … 4 294 967 295 4 octets
unsigned long int
-2 147 483 647 … 2 147 483 648 4 octets
long int
0 … 65 535 2 octets
unsigned short int
-32 768 … 32 767 2 octets
short int
Chap. 0 – Rappels de langage C
22
3. Les données mémoires a) Les Types élémentaires :
Les réels
10 octets Long double
9.46 E -308 … 1.8 E 308 8 octets
double
simple précision, 1.18 E +/- 38 4 octets
float
Chap. 0 – Rappels de langage C
23
3. Les données mémoires a) Les Types élémentaires :
Les caractères
Pas de gestion des chaînes de caractères
Un caractère est représenté en machine par un entier, ainsi ‘A’ désigne la valeur entière 65 du caractère dans la table ASCII.
0…255 1 octet
unsigned char
-128 … 127 1 octet
char
Chap. 0 – Rappels de langage C
24
3. Les données mémoires a) Les Types élémentaires :
Les caractères
Chap. 0 – Rappels de langage C
25
3. Les données mémoires a) Les Types élémentaires :
Les booléens
Souvent on définit les macro-constantes FALSE et TRUE comme suit : enum bool {FALSE, TRUE } ;
En C, une expression conditionnelle est fausse, quand elle prend la valeur (entière) 0, et vraie dans tous les autres cas.
26
3. Les données mémoires b) Les tableaux ou vecteurs :
• Un tableau est une zone de mémoire contiguë contenant plusieurs valeurs d’un même type.
• La taille d’un tableau est fixée lors de sa définition, elle ne peut pas être modifiée.
• Les tableaux sont indicés de 0 à taille-1; [0, taille-1]
• Il n’y a pas de marqueur de fin de tableau, donc pas de vérification automatique de dépassement
int tab[10]; ……….…tableau de 10 entiers tab[8+1] = 4; ………...initialisation du dernier entier
27
3. Les données mémoires b) Les tableaux ou vecteurs :
int vecteur [ ] = {0, 1, 2}.
float vecteur [3] [2] = {{0.0, 0.1}, {1.0, 1.1}, {2.0, 2.1}} ; float vecteur [3] [2] = {0.0, 0.1, 1.0, 1.1, 2.0, 2.1} ;
char chaine [20] = {‘c’, ’o’, ’u’, ’c’, ’o’, ’u’, ’\0’} ; char chaine [20] = "coucou" ;
Chap. 0 – Rappels de langage C
28
3. Les données mémoires c) Les structures ou enregistrements :
La structure est un type structuré hétérogène. On définit la structure nom_structure possédant N champs de type type_i :
struct nom_structure{
type_1 champ_1;
…
type_N champ_N;
} ;
Par la suite, on déclare une variable article de type struct nom_structure en écrivant struct nom_structure article;
On accède aux données du champs_i de la variable article en écrivant article.champs_i
Chap. 0 – Rappels de langage C
29
3. Les données mémoires c) Les structures ou enregistrements :
struct point {
float x ; float y ; } ;
struct point origine = {0.0, 0.0} ; origine.y = 12.0;
struct point * pp;
//faire une allocation dynamique avant la ligne suivante pp->x = 10.0;
Chap. 0 – Rappels de langage C
30
3. Les données mémoires c) Les structures ou enregistrements :
Autoréférencement : struct noeud {
char * mot ; struct noeud * gauche ; struct noeud * droit ; } ;
Chap. 0 – Rappels de langage C
31
3. Les données mémoires d) Les pointeurs et tableaux :
Un pointeur est une variable dont le contenu est une adresse- mémoire
Un pointeur doit être défini en fonction du type de la donnée stockée à cette adresse-mémoire
char * pc; //pointeur de caractères int * pi; //pointeur d’entier
L’opérateur unaire « & » donne l’adresse-mémoire d’une donnée.
L’opérateur unaire « * » donne la valeur stockée à l’adresse-mémoire (opérateur d’indirection)
32
3. Les données mémoires d) Les pointeurs et tableaux :
char c=’A’; //définition d’une variable
char * p = &c; //définition d’un pointeur
• de type char
• de nom c
• de valeur initiale 65 ou ‘A’
• d’adresse &c
• de type char *
• de nom p
• de valeur initiale &c
=> p pointe sur c
33
3. Les données mémoires d) Les pointeurs et tableaux :
char c;
char * p;
c = ’A’; p = &c;
=> p et &c on la même valeur
=> *p et c ont la même valeur : 65 (qui est représentable par ’A’ ) Chap. 0 – Rappels de langage C
34
3. Les données mémoires d) Les pointeurs et tableaux :
Chap. 0 – Rappels de langage C
35
3. Les données mémoires d) Les pointeurs et tableaux :
Chap. 0 – Rappels de langage C
36
3. Les données mémoires
Chap. 0 – Rappels de langage C
Arguments de ligne de commande
int main(int argc, char * argv[])
37
Plan
1. Introduction
2. Les structures de contrôle 3. Les données mémoires 4. Passage de paramètres 5. La chaîne de compilation 6. Le préprocesseur
7. Les entrées-sorties standards 8. L’allocation dynamique
38
4. Passage de paramètres
Passage d’une valeur
39
4. Passage de paramètres
Passage d’une référence !!!
Déclaration Manipulation
Chap. 0 – Rappels de langage C
40
Chap. 0 – Rappels de langage C
Plan
1. Introduction
2. Les structures de contrôle 3. Les données mémoires 4. Passage de paramètres 5. La chaîne de compilation 6. Le préprocesseur
7. Les entrées-sorties standards 8. L’allocation dynamique
41
5. La chaîne de compilation
Chap. 0 – Rappels de langage C
42
5. La chaîne de compilation
$ gcc essai.c -o essai Chap. 0 – Rappels de langage C
Ou bien en une fois
43
5. La chaîne de compilation
Chaque compilateur possède son jeu de fonctionnalités supplémentaire étendant la norme C ANSI (norme ISO).
Ces fonctionnalités peuvent être désactives afin d'assurer un source portable.
gcc comporte un très grande nombre d'options, dont:
• -ansi : Desactive les fonctionnalites de gcc ne respectant pas la norme ANSI
• -pedantic : Rejette tous programmes ne respectant pas strictement la norme ANSI
• -Wall –W : Active un grand nombre d'avertissement
• -Werror : Transforme tous les avertissements en erreur
44
Plan
1. Introduction
2. Les structures de contrôle 3. Les données mémoires 4. Passage de paramètres 5. La chaîne de compilation 6. Le préprocesseur
7. Les entrées-sorties standards 8. L’allocation dynamique
45
6. Préprocesseur
Un préprocesseur :
• retraite le code avant la compilation
• effectue des substitutions de macros
• inclusion de fichiers par leurs noms Chap. 0 – Rappels de langage C
46
6. Préprocesseur a) Macro constante (et macro fonction)
#define identificateur chaîne
#define MAX 100
Le préprocesseur remplace identificateur par chaîne dans le code source.
_ _LINE_ _ , _ _ DATE_ _, _ _TIME_ _, _ _FILE_ _
sont des macros constantes prédéfinis indiquant la ligne courante dans le code, la date, l’heure, et le nom du fichier courant.
Chap. 0 – Rappels de langage C
47
6. Préprocesseur b) L’inclusion de fichier
# include <nom-de-fichier>
Le préprocesseur recherche nom-de-ficher dans les répertoires standards(/usr/include/), et l’insère dans le code source.
Pour étendre la recherche au repertoire rep, on peut spécifier l’option de compilation -I rep.
# include "nom-de-fichier"
Le préprocesseur recherche nom-de-ficher dans le répertoire courant, et l’insère dans le code source.
Chap. 0 – Rappels de langage C
48
6. Préprocesseur c) La compilation conditionnelle
On propose la syntaxe des instructions conditionnelles propres au préprocesseur.
# if expression-constante ou # ifdef indentificateur ou # ifndef identificateur ( # ifdef identificateur équivaut à # if defined (identificateur) ) ( # ifndef équivaut à # if !defined (identificateur) ) //code
# elif expression-constante //code
# else //code
# endif
Chap. 0 – Rappels de langage C
49
6. Préprocesseur
50
6. Préprocesseur d) Création de module
Le module se compose de deux fichiers module.h, qui contient la déclaration des variables et des fonctions à exporter et module.c, qui contient leurs définitions.
/* fichier module.h */
# ifndef MODULE_H
# define MODULE_H /* déclarations */
extern…
# endif
/* fichier module.c */
# include "module.h"
/* définitions */
…
Evite la redondance du code lors des multiples appels
# include" module.h"
51
Chap. 0 – Rappels de langage C
Plan
1. Introduction
2. Les structures de contrôle 3. Les données mémoires 4. Passage de paramètres 5. La chaîne de compilation 6. Le préprocesseur
7. Les entrées-sorties standards 8. L’allocation dynamique
52
7. Les entrées-sorties standards
Trois pseudo-fichiers permettent l’accès au terminal de l’utilisateur.
Ils ont pour nom :
• stdin
– pour fichier standard d’entrée ; ce fichier est le plus souvent associé au clavier.
• stdout
– pour fichier de standard sortie ; ce fichier désigne le plus souvent l’écran et les fonctions d’accès associées utilisent une technique de tampon pour les écritures qui lui sont associées.
• stderr
– pour fichier standard d’erreur, ce fichier correspond lui aussi le plus souvent à l’écran mais les écritures sont non tamponnées.
Chap. 0 – Rappels de langage C
53
7. Les entrées-sorties standards
Échanges :
• caractère par caractère
• ligne par ligne
• avec formats
Chap. 0 – Rappels de langage C
stdin stdout
54
7. Les entrées-sorties standards
Caractères par caractères
:
char getchar(void) ;
cette fonction permet de lire un caractère sur stdin s’il y en a un. Ce caractère est considéré comme étant du type unsigned char.
int putchar(char ) ;
cette fonction permet d’écrire un caractère sur stdout. en cas d’erreur la fonction retourne EOF.
Chap. 0 – Rappels de langage C
55
7. Les entrées-sorties standards
Caractères par caractères
:
#include <stdio.h>
int main (int argc, char *argv[]) { int c;
while ((c = getchar ()) != EOF) putchar (c);
return 0;
}
56
7. Les entrées-sorties standards
Ligne par ligne
:
char *gets(char *) ;
lire une ligne sur stdin ; les caractères de la ligne sont rangés (un caractère par octet) dans la mémoire à partir de l’adresse donnée en argument à la fonction. Le retour chariot est lu mais n’est pas rangé en mémoire. Il est remplacé par un caractère nul
’\0’ de manière à ce que la ligne, une fois placée en mémoire, puisse être utilisée comme une chaîne de caractères.
int puts(char *) ;
écriture d’une chaîne de caractères, suivie d’un retour chariot sur stdout. En retour, une valeur entière non négative en cas de succès. Elle retourne la valeur EOF en cas de problème.
57
7. Les entrées-sorties standards
Ligne par ligne
:
#include <stdio.h>
int main (int argc, char *argv[]){
char BigBuf[256];
while (gets (BigBuf) != NULL) puts (BigBuf);
return 0;
}
Chap. 0 – Rappels de langage C
58
7. Les entrées-sorties standards Echanges avec formats:
int scanf(const char *, ...) ; lecture formatée sur stdin.
int printf(const char *, ...) ; écriture formatée sur stdout
%c caractère (char)
%d entier (int)
%f nombre à virgule flottante (float)
%o octal (int)
%x hexa (int)
%s chaîne de caractères
%e float en notation exponentielle
%u entier sans signe Chap. 0 – Rappels de langage C
59
7. Les entrées-sorties standards Echanges avec formats :
#include <stdio.h>
int main() {
int a,b;
scanf("%d", &a);
scanf("%d", &b);
printf ("multiplication : %d fois %d donne %d \n", a, b, a*b);
return 0;
}
Chap. 0 – Rappels de langage C
60
Chap. 0 – Rappels de langage C
Plan
1. Introduction
2. Les structures de contrôle 3. Les données mémoires 4. Passage de paramètres 5. La chaîne de compilation 6. Le préprocesseur
7. Les entrées-sorties standards 8. L’allocation dynamique
61
Segment de pile Segment
de données Segment
de code
Mémoire vive
\x00FF
7. Allocation dynamique
La réservation d’espace via les définitions de variables (simple ou tableau ) est appelée allocation statique.
La taille mémoire réservée n’est pas modifiable au cours de l’exécution du programme.
62
7. Allocation dynamique
Pour utiliser l’espace mémoire dont on ne connaît pas la taille avant le début de l’exécution on doit trouver une solution.
La solution naïve consiste à :
• Réserver statiquementune grande zone: char tab[2^32];
• Distribuer et Redistribuer dynamiquementdes bouts de cette zone au cours de l’exécution.
Mémoire vive
\x00FF
char tab[ ]
63
7. Allocation dynamique
La solution naïve a des inconvénients :
• sous-utilisation de la mémoire
les limites de l’allocation statique s’appliquent et toute la mémoire de l’ordinateur (ou du processus) n’est pas utilisable (seul le système a accès à toute la mémoire)
• Mauvaise utilisation de la mémoire Chap. 0 – Rappels de langage C
Mémoire vive
\x00FF
????
64
7. Allocation dynamique
Les systèmes d’exploitation modernes (dont ceux respectant la norme POSIX) offres des fonctions d’allocation mémoire dynamique:
• l’espace mémoire n’est pas réservé avant l’appel système correspondant
• la taille de l’espace mémoire réservé peut-être modifiée au cours de l’exécution du programme sans perte de données
• le système gère seul la mémoire réservée.
Fonction de la bibliothèque standard du C (stdlib.h)
malloc, calloc, realloc, free Chap. 0 – Rappels de langage C
65
7. Allocation dynamique
void * malloc (size_t taille)
• Réserve « taille » octet dans la mémoire
• Retourne l’adresse de début ou NULL si plus de place
• Le pointeur de retour doit être converti en pointeur du type des données qui vont être dans cette zone.
Ex : int * adr = (int *) malloc (sizeof(int)) Chap. 0 – Rappels de langage C
Mémoire vive
\x00FF
Int ~ 4 octets
66
7. Allocation dynamique
void * malloc (size_t taille) Chap. 0 – Rappels de langage C
Mémoire vive
\x00FF
Int ~ 4 octets
Zone non initialisée
67
7. Allocation dynamique
void * calloc (size_t nb, size_t taille)
• Demande au système de réserver une zone de « nb » cases contigus
• Retourne l’adresse de début ou NULL si plus de place
• Le pointeur de retour doit être converti en pointeur du type des données qui vont être dans cette zone.
Ex : int * adr = (int *) calloc (3, sizeof(int)) Mémoire vive
\x00FF
3*4 octets
68
7. Allocation dynamique
void * realloc (void * ptr, size_t taille)
• Change la taille de la zone mémoire pointée par « ptr » pour qu’elle occupe « taille » octets
• Le contenu des cases mémoires est inchangé
• Le pointeur « ptr » DOIT être initialisé par un appel de méthode
« malloc » ou « realloc »
• La fonction retourne un pointeur sur la zone mémoire (null en cas de problème et la zone n’est pas modifiée)
Mémoire vive
\x00FF
69
7. Allocation dynamique
void free (void * ptr)
• La zone mémoire pointée par « ptr » n’est plus utilisée
• Le pointeur « ptr » DOIT avoir été initialisé par une fonction
« malloc », « calloc » ou « realloc » Chap. 0 – Rappels de langage C
Mémoire vive
\x00FF
70
7. Allocation dynamique
Exemple : Taille de la mémoire
#include <stdio.h>
#include <stdlib.h>
main() { int i=0 ; char* sptr ;
while ((sptr = (char*) malloc(1024)) != NULL){
i++;
}
printf("\nLa mémoire disponible est de %d kilo-octets\n" ,i);
getchar();
}
Chap. 0 – Rappels de langage C