Upload
others
View
39
Download
0
Embed Size (px)
Citation preview
Programmation
impérative et langage C
Tableaux, pointeurs, références et
structures
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Tableaux
� Un tableau est un ensemble fini de mots consécutifs en mémoire� Longueur des mots identique, dépend du type� Pour réserver la place en mémoire il faut préciser la
dimension du tableau� Déclaration des tableaux en C :
type nom[taille] ;
� taille : constante entière
� Accès indexés aux éléments d’un tableau :� Nom du tableau� Indice ou rang dans le tableau : commence à 0
� tab[0] : premier élément du tableau
� tab[taille-1] : dernier élément du tableau
� vect[i]
� Le programmeur doit vérifier la validité des indices !
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Tableaux (2)
� Déclaration seule :
� Déclaration d’un tableau d’entiers de dimension 10 :
int vect[10] ;
� ou mieux :
#define N 10
int vect[N] ;
� Déclaration et initialisation :
int vect[4] = {1, 2, 3, 4} ;
� Il est possible d’omettre de la dimension :
int vect[] = {2, 4, 5, 6, 7, 8} ;
� déclare un tableau de 6 entiers
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Tableaux multidimensionnels
� Déclaration d’un tableau à deux dimensions :
type nom[n][m]
� Un tel tableau peut se voir comme une matrice n×m
� n ≡ nb lignes et m ≡ nb colonnes
� Chaque élément d’un tel tableau est identifié par deux indices :
A[i][j]
� Le premier indice (0 ≤ i < n) identifie la ″ligne″� Le second (0 ≤ j < m) identifie la ″colonne″
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Tableaux multidimensionnels (2)
� La déclaration d’un tableau A[N][M] réserve en mémoire N×M mots consécutifs de longueur identique correspondant au type choisi
� En mémoire le tableau est rangé de manière consécutive ligne par ligne :� Place en mémoire : N×M mots (longueur définie par le type)� Première ligne :
� A[0][0] à A[0][M-1]
� mots aux places 0 à M-1� Deuxième ligne :
� A[1][0] à A[1][M-1]
� mots aux places M à (2×M)-1� etc.� i-ème ligne :
� A[i-1][0] à A[i-1][M-1]
� mots aux places (i-1)×M à (i×M)-1� A[i][j] occupe le mot à la place (i×M)+j
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Tableaux multidimensionnels (3)
� Initialisation
� Liste de valeurs entre accolades
� Les valeurs sont stockées dans des cases consécutives à
partir du début du tableau
� Ligne par ligne en imbriquant des accolades
� Les valeurs de chaque ligne sont stockées dans des mots
consécutifs à partir du début de la ligne correspondante
� Les éléments absents sont indéterminés
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Variable et adresse
� La valeur d’une variable est stockée dans un mot en mémoire dont la longueur (nombre d’octets) dépend du type
� Ce mot se situe en mémoire à une certaine adresse (position) :� Unité : octet� Si n bits pour adressage de 0 à 2n-1� L’adresse d’un octet représente sa position en mémoire� Octet à l’adresse k est en (k+1)ème position
� Premier octet à l’adresse 0
� Dernier octet à l’adresse 2n-1
� Opérateur adresse en C : &&nom_variable
� En C deux manières d’accéder à une variable :� Par référence directe : son nom� Par son adresse
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Notion de pointeur
� En C on utilise des pointeurs pour manipuler des adresses
� Un pointeur est une variable :
� Contenue en mémoire
� Longueur fixe (indépendante du type de la variable visée)
� Peut être manipulée comme toute autre variable
� Pointe sur la variable dont il contient l’adresse
� Opérateur indirection : *
p : pointeur
*p : variable sur laquelle pointe p
� Pour le schéma suivant : *p identique à var
p
var
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Notion de pointeur (2)
� Déclaration d’un pointeur :
type *p ; ou type* p ; ou type * p ;
� Pointeur sur un octet :
char *p ; ou char* p ; ou char * p ;
� Pointeur sur un entier (de type int) :
int *p ; ou int* p ; ou int * p ;
� Pointeur sur un réel (de type float) :
float *p ; ou float* p ; ou float * p ;
� Pointeur sur un réel (de type double) :
double *p ; ou double* p ; ou double * p ;
� La déclaration permet uniquement de réserver en mémoire la zone pour stocker le pointeur sans l’initialiser. Avant de
l’utiliser il faut lui affecter une adresse valide.
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Notion de pointeur (3)
� Résumé :
� Déclaration : type *p ; ou type* p ;
� Affectation : p = &i ;
� Accès à mémoire : j = *p ; ou *p = j ;
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (source)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (sortie écran)
Si nous exécutons plusieurs fois ce programme les valeurs
de i (5 ou 23) ne changent pas, par contre son adresse en
mémoire et donc la valeur du pointeur peuvent changer.
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Tableau et pointeur
� Un tableau est un ensemble fini de mots consécutifs en mémoire
� Longueur des mots identique, dépend du type
� Nom du tableau ≡ constante égale à l’adresse de base du tableau (du premier élément du tableau)
� Accès aux éléments d’un tableau par référence au premier élément :
� tab[i] : i = indice dans le tableau
� Pointeur
� Si p = &tab[0] ; ou p = tab ;
*p identique à tab[0]
*(p+i) identique à tab[i]
p = p+i pointe sur tab[i]
Exemple
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
tab et p sont équivalents (ou presque), ce sont deux
pointeurs
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Tableau et pointeur (2)
� Arithmétique des pointeurs :
� Seules opérations autorisées :
� Addition ou soustraction d’un entier
� Incrémentation ou décrémentation
� Soustraction de deux adresses
� Unité : sizeof(type) ≡ nombre d’octets utilisés pour stocker une variable du type type.
� D’où l’intérêt du type dans la déclaration d’un pointeur
tab[N-1]tab[0] tab[1] tab[2]
p
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (source)
Ne pas faire p+(i*sizeof(int))
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (sortie écran)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (source)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (sortie écran)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (source)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (sortie écran)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (source)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (sortie écran)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (source)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (sortie écran)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Chaînes de caractères
� Une chaîne de caractères en C est un tableau de caractères, ou tableau d’octets, dont, par convention, la fin est marquée par un octet nul.
� Chaque octet représente un caractère selon le code ASCII.
� Les chaînes de caractères constantes sont indiquées entre guillemets doubles.
� Pour stocker un texte de n caractères, il faut n+1 octets. Sixoctets pour la chaîne "Hello",
� "" représente une chaîne de caractères vide, représentée par un octet nul.
� Dans les chaînes de caractères, nous pouvons utiliser toutes les séquences d'échappement. Chacune occupe un octet.
� La fin de chaîne se note aussi : ’\0’
� Une variable chaine est une constante dont la valeur est l’adresse du premier caractère.
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Chaînes de caractères (2)
� Des constantes chaînes séparées par des signes d'espacement (espaces, tabulateurs ou interlignes) dans le texte du programme seront réunies en une seule chaîne constante lors de la compilation : "un " "deux"
" trois "
sera évalué à "un deux trois "
� Le code ASCII induit l'ordre lexicographique suivant : 0,1,2, ... ,9 , ___ , A,B,C, ... ,Z, ___, a,b,c, ... ,z
� La chaîne vide "" précède toutes les autres chaînes.� "ABC" précède "BCD" car 'A'<'B'
� "ABC" précède "B" car 'A'<'B'
� "Abc" précède "abc" car 'A'<'a'
� "ab" précède "abcd" car "" précède "cd"
� " ab" précède "ab" car ' ' < 'a'
Exemple
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (source)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (sortie écran)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (source)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (sortie écran)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Tableaux multidimensionnels
� Déclaration d’un tableau à deux dimensions :
type nom[n][m]
� Un tel tableau peut se voir comme une matrice n×m
� n ≡ nb lignes et m ≡ nb colonnes
� Chaque élément d’un tel tableau est identifié par deux indices :
A[i][j]
� Le premier indice (0 ≤ i < n) identifie la ″ligne″� Le second (0 ≤ j < m) identifie la ″colonne″
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Tableaux multidimensionnels (2)
� La déclaration d’un tableau A[N][M] réserve en
mémoire N×M mots consécutifs de longueur
identique correspondant au type choisi
� Les M premiers mots contiennent la première ligne,
les M suivants la deuxième ligne et ainsi de suite.
� L’élément A[i][j] occupe le mot k = (i*M)+j
� Si p est un pointeur pointant sur la première case du
tableau A, p+(i*M)+j pointe sur A[i][j]
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (source)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (source suite)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (sortie écran)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Structures
� Une structure est une collection de variables,
éventuellement de différents types, regroupées sous
un seul nom. Chacune des variables constituant une
structure, appelée champ, dispose d’un identificateur.
� Définition d’une structure, mot clef struct :
struct nom_struct {description membres} ;
� Déclaration d’une structure :
struct nom_struct nom ;
� Un élément d’une structure est identifié par le nom de
la structure et le nom du champ :
nom.identificateur_champ
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Structures (2)
� Une structure peut contenir des champs de différents types :struct employe {
char nom[80] ;
char prenom[80] ;
int naissance[3] ;
float salaire ;
} ;
� Exemple de déclaration avec initialisation :struct employe chef = {"Smith" , "Alain", {10, 4, 1950}, 5432.19 } ;
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (source)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (sortie écran)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (variante source)
Utilisation de la redéfinition de type (mot clef typedef),
remarquer la position du nom de la structure.Permet, par exemple, d’éviter le mot clef struct
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Pointeur et structure
� Comme pour toute variable on peut accéder à une
structure par l’intermédiaire d’un pointeur
� Déclaration d’un pointeur sur une structure :
struct nom_struct *nom_pointeur ;
� Un élément d’une structure est identifié par le
pointeur et le nom du champ :
(*nom_pointeur).identificateur_champ
� Les parenthèses sont indispensables (car * moins
prioritaire que le .)
� Autre notation fréquemment utilisée :
nom_pointeur->identificateur_champ
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (source)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (sortie écran)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Tableau de structures
� Il est possible de déclarer un tableau de
structure :struct nom_struct nom[dimension] ;
� Un élément d’une structure est alors identifié le nom
de la structure, un indice et le nom du champ :
nom[indice].identificateur_champ
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple
Attention un champ peut être défini comme un tableau.
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Unions
� Alors que les champs d’une structure occupent des places différentes en mémoire, les champs d’une union occupent une zone commune
� Taille de cette zone définie par le champ le plus long
� Permet une interprétation différente d’une même zone mémoire
� Gain de place si le contenu dépend du contexte d’utilisation
� Définition d’une union, mot clef union :
union nom_struct {description champs} ;
� Déclaration d’une union :
union nom_struct identificateur ;
� Un champ d’une union est identifié par le nom de la structure et le nom du champ :
identificateur.identificateur_champ
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (code source)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (copie d’écran)
� Cet exemple permet d’accéder à la
représentation binaire (visualisée ici en hexadécimal) d’un réel du type float.
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (code source)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exemple (copie d’écran)
� Permet de constater l’ordre de stockage d’un
tableau à deux dimensions
� La zone compte 10 mots
� Pour stocker le plus grand champ
Gestion dynamique de la
mémoire en C� Deux fonctions de base (stdlib) :
#include <stdlib.h>
� Allocation dynamique de mémoire : malloc
� Libération d’une zone mémoire : free
� Allocation :
� Pendant l’exécution du programme : zone dont la taille n’est pas connue au moment de la compilation
� Il nous faut un pointeur pour accéder à la zone mémoire ⇒ à déclarer
� Il faut définir la taille de la zone à réserver :
taille = nb_mots × sizeof(type_variable) // (de type size_t)
� nb_mots : variable entière
� sizeof est un opérateur (pour le compilateur) et non une fonction. Correspond au nombre d’octets utilisés en mémoire pour une variable de type type_variable.
� Syntaxe
type *ptr ;
ptr = malloc (n*sizeof(type)) ;
ptr = (type*)malloc (n*sizeof(type)) ;
if (ptr == NULL) … // pas d’allocation
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Tableau à une dimension
� Copie locale du tableau
pour ne pas modifier
l’original
� Conversion forcée (int *)
pour assurer l’alignement
des octets en mémoirevoid * malloc (size_t taille)
� Ne pas oublier de libérer la
mémoire (free) sinon
allocation nouvelle à
chaque appel de la fonction
⇒ fuite de mémoire
� Après chaque appel il
faudrait tester le code de
retour (bonne exécution ?)
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Tableau à deux dimensions
� La variable a est un pointeur
de pointeurs
� Allocation en deux étapes :� Réservation d’un tableau de
pointeurs
� Réservation de chacune des lignes
� size_t : type prédéfini
� Attention les lignes ne sont
pas nécessairement rangées
dans des zones consécutives
en mémoire
� Accès simple : a[i][j]
� Libération des lignes, puis du
tableau de pointeurs� Ordre inverse de la réservation
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019
Exécution
Programmation impérative et langage C - Sylvain Tisserant - Polytech Marseille / INFO3 - 2019