Programmation impérative et langage Csylvain.tisserant.perso.luminy.univ-amu.fr/Prog_Imp_C/... ·...

Preview:

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

Recommended