Les Pointeurs et les Tableaux Statiques et Tableaux Dynamiques

Slides:



Advertisements
Présentations similaires
Premier programme en C :
Advertisements

La boucle for : init7.c et init71.c
Cours de C – Séance dexercices 12 Octobre Exercice 5 Idem quexercice 1 : lire une ligne au clavier Sans limitation de la longueur de la ligne (utilisez.
Cours de C – Séance dexercices 25 Septembre 2007.
Introduction Langage très répandu Noyau Linux VLC … Des avantages indéniables mais aussi des contraintes ! Ceci nest quun rapide tour.
Rappels C.
Développement logiciel sur micro-contrôleurs PIC en C
Formation C débutant. Notion de compilation source.c executable Phase de compilation Fichier de texte brut, inexploitable directement par la machine Fichier.
GEF 243B Programmation informatique appliquée Types dérivés, structures et tableaux §
GEF 243B Programmation informatique appliquée
C.
Paramètres et pointeurs
Structures et unions types énumérés Qu'est-ce qu'une structure
Les pointeurs Manipulation d'adresses et de ce qui est contenu dans ces adresses Très important, fondamental même en C mauvaise réputation : 'dur à comprendre',
Tableaux Certains problèmes nécessitent beaucoup de variables du même type. Exemple : relevé de températures matin et soir dans 10 villes pour 10 jours.
FLSI602 Génie Informatique et Réseaux
FLSI602 Génie Informatique et Réseaux
Regrouper des éléments de même type et pouvoir y accéder à laide dun identificateur et dun indice. Objectif des tableaux.
Cours 7 - Les pointeurs, l'allocation dynamique, les listes chaînées
Récursivité.
8PRO100 Éléments de programmation Allocation dynamique de la mémoire.
La fonction alloue un bloc de taille size. Il faut indiquer la taille du bloc que lon veut allouer. Le premier exemple: #include void main()
Programme de baccalauréat en informatique Algorithmique et programmation IFT-1001 Thierry EUDE Hatem Mahbouli Laboratoire #12 Département dinformatique.
TRAITEMENT DE STRUCTURES
Séances de soutien Projet informatique 2A
1 Les pointeurs et quelques rappels sur certains éléments du langage C.
Les pointeurs Enormément utilisé en C/C++ ! Pourquoi? A quoi ça sert?
Les pointeurs Modes d’adressage de variables. Définition d’un pointeur. Opérateurs de base. Opérations élémentaires. Pointeurs et tableaux. Pointeurs et.
IFT-2000: Structures de données
Structures de données IFT-2000
Sixième cours Les chaînes de caractères et le passage de paramètres par référence Passage de paramètres par référence String.h.
Les enregistrements (struct) suite. Struct Rappel Enregistrement : Suite de données pouvant être de types différents, accessibles via une seule variable.
IFT 6800 Atelier en Technologies d’information
8PRO100 Éléments de programmation Les types composés.
Christine Bonnet SOURCES : « Samples » dOracle, « Oracle 8 » R. Chapuis PRO*C – C ++
Plan cours La notion de pointeur et d’adresse mémoire.
La librairie assert.h.
L’essentiel du langage C
Structures des données
Le langage C Structures de données
2.1 - Historique Chapitre 2 : Introduction au langage C++
Les pointeurs L'opérateur &.
Le langage C Rappel Pointeurs & Allocation de mémoire.
Programmation Système et Réseau (sous Linux)
LES PILES ET FILES.
CYCLE 6 : FONCTIONS Faire un programme en C avec des FONCTIONS 1- A quoi servent les FONCTIONS ? 2- Comment écrire un programme avec FONCTIONS ? 3- Comment.
La notion de type revisitée en POO
et quelques rappels sur certains éléments du langage C
Les adresses des fonctions
SIF-1053 Architecture des ordinateurs
ALGORITHMIQUE ET PROGRAMMATION C
Argc et argv Utilisation des paramètres de la ligne de commande.
Autres éléments du langage
Un survol du language C.
1 Structures des données. 2  Le tableau permettait de désigner sous un seul nom un ensemble de valeurs de même type, chacune d'entre elles étant repérée.
La fonction alloue un bloc de taille size. Il faut indiquer la taille du bloc que l’on veut allouer. Le premier exemple: #include void main()
TABLEAUX des POINTEURS TRAITEMENT DE STRUCTURES
ISBN Chapitre 10 L'implémentation des sous- programmes.
8PRO100 Éléments de programmation Les pointeurs de caractères.
Cours LCS N°4 Présenté par Mr: LALLALI
Classe 1 CSI2572 Autres modificateurs de déclaration de variables: & volatile & register & static & auto & extern & const volatile Indique au compilateur.
Conception de Programmes - IUT de Paris - 1ère année Quelques éléments du langage C++ Les références La surcharge de fonctions Les fonctions «
8PRO107 Éléments de programmation Les adresses et les pointeurs.
Exercices.
PRO-1027 Programmation Scientifique en C
3ième Classe (Mardi, 23 Septembre) CSI2572. O jourd'8: E Allocation de mémoire E Déallocation de mémoire E Tableaux (n dimensions) E Arithmetique des.
Informatique 2A Langage C 5ème séance. Déroulement de la séance 5 1 ère partie Étude des chaînes de caractères 2 ème partie Les structures 3.
Informatique 1A Langage C 6 ème séance 1. Objectifs de la séance 6  Allocation dynamique de mémoire  Application à la création de tableaux 2.
Informatique 2A Langage C 3 ème séance.
Transcription de la présentation:

Les Pointeurs et les Tableaux Statiques et Tableaux Dynamiques

Tableaux Statiques et Tableaux Dynamiques Les tableaux statiques nécessitent de maximiser lors de l'écriture du programme la dimension des tableaux. Il serait plus utile de ne réserver, pour chaque exécution, que la taille nécessaire à l'application en cours. Déclaration d’un tableau statique #define composante float composante tab[dim]; composante*tab; tab=(composante *)malloc(taille*sizeof(composante)); free(tab); tab=NULL; Déclaration d’un tableau dynamique (si on a besoin du tableau) Si le tableau redevient inutile.

Tableaux Statiques et Tableaux Dynamiques Si on a l'une ou l'autre des déclarations on peut écrire: float t[100]; float *t = (float*)malloc(10*sizeof(float)); On doit connaître la dimension d'un tableau dynamique (taille) avant sa première utilisation. t[0] ou *t t[i] ou *(t+i)

Tableaux Statiques et Tableaux Dynamiques Remarque 1. La similitude entre un tableau et un pointeur est grande, notamment dans la partie exécutable des fonctions. Mais il subsiste des différences, surtout dans les déclarations. Il ne faut pas oublier que les déclarations: introduisent p comme une variable pointeur et t comme une constante pointeur. Ainsi, les expressions p = t et p++ sont légitimes, mais t = p et t++ sont illégales, car elles tentent de modifier une non variable (un nom de tableau n'est pas une lvalue). int *p, t[100];

Tableaux Statiques et Tableaux Dynamiques Remarque 2. Dans ce mème esprit, rappelons la difference qu'il peut y avoir entre les deux déclarations suivantes : s est l'adresse d'un tableau de caractères char s[ ] = "Bonsoir"; et char *t = "Bonsoir";

Tableaux Statiques et Tableaux Dynamiques Remarque 2. tandis que t est l'adresse d'un tableau de caractère(s)

Tableaux Statiques et Tableaux Dynamiques On pourra référencer ces caractères par: Cependant, dans le premier cas le compilateur a alloué un vrai tableau de 8 caractères, et y a copié la chaîne donnée. Dans le second cas, la chaîne a été rangée avec les autres constantes littérales et le compilateur n'a alloué qu'une variable de type pointeur dans laquelle il a rangé l'adresse de cette constante. Par suite, s n'est pas une variable mais *s, s[i] et *(s + i) en sont, tandis que t est une variable mais *t, t[i] et *(t + i) n'en sont pas. s[i], *(s + i) t[i], *(t + i)

Tableaux Statiques et Tableaux Dynamiques Exemple classique : La fonction strcpy(dest, srce) copie la chaîne de caractères srce dans l'espace pointé par dest. char *strcpy(char *dest, char *srce) { char *d = dest, *s = srce; while ((*d++ = *s++) != '\0'); return dest; }

Tableaux Statiques et Tableaux Dynamiques Example: utilisation de la fonction strcpy La longueur de t <= de celle de s #include <stdio.h> char *strcpy(char *dest, char *srce); void main() { char s[ ] = "AAAAAAA"; char *t = "Bonjour"; puts (strcpy(s,t)); } char *strcpy(char *dest, char *srce) { char *d = dest, *s = srce; while ((*d++ = *s++) != '\0'); return dest; Bonjour

Tableaux Statiques et Tableaux Dynamiques Example: utilisation de la fonction strcpy La longueur de t > de celle de s #include <stdio.h> char *strcpy(char *dest, char *srce); void main() { char s[ ] = "AAAA"; char *t = "Bonjour"; puts (strcpy(s,t)); } char *strcpy(char *dest, char *srce) { char *d = dest, *s = srce; while ((*d++ = *s++) != '\0'); return dest; Erreur! #include <stdio.h> #include <string.h> #include <stdlib.h> char *strcpy(char *dest, char *srce); void main() { char *t = "Bonjour"; int len=strlen(t); char *s=(char *)malloc((len+1)*sizeof(char)); puts (strcpy(s,t)); } Bonjour

Tableaux Statiques et Tableaux Dynamiques L'équivalence entre les tableaux et les pointeurs permet de réaliser des tableaux dynamiques, c'est-à-dire des tableaux dont la taille n'est pas connue au moment de la compilation mais uniquement lors de l'exécution, lorsque le tableau commence à exister. Pour cela il suffit de: remplacer la déclaration du tableau par celle d'un pointeur; allouer l'espace à l'exécution, avant toute utilisation du tableau, par un appel de malloc ou calloc; dans le cas d'un tableau local, libérer l'espace à la fin de l'utilisation.

Tableaux Statiques et Tableaux Dynamiques Programmation avec un tableau statique Faire un programme à afficher le triangle de Pascal (Rappelons que les coeficients de la neme ligne du triangle de Pascal sont définis récursivement à partir de ceux de la n-1eme ligne). #include <stdio.h> 1/3 #include <stdlib.h> #define N_MAX 50 void Blaise(int n); Le prototype de la fonction

Tableaux Statiques et Tableaux Dynamiques Programmation avec un tableau statique void main() 2/3 { int n; do { printf("Entrer n="); scanf("%d",&n); }while(n<=0 || n > N_MAX); Blaise(n); } Entrer n=3 1 1 2 1 1 3 3 1 La fonction main, appelante la fonction Blaise

Tableaux Statiques et Tableaux Dynamiques Programmation avec un tableau statique void Blaise(int n) 3/3 { int j, p, i; int tab[N_MAX + 1]; /* N_MAX est une constante connue à la compilation */ for (j = 0; j <= n; j++) { tab[0] = tab[j] = 1; for (p = j - 1; p > 0; p--) tab[p] += tab[p - 1]; /* exploitation de tab ; par exemple, afichage : */ for (i = 0; i <= j; i++) printf("%5d", tab[i]); printf("\n"); } La définition de la fonction Blaise

Tableaux Statiques et Tableaux Dynamiques Programmation avec un tableau dynamique Faire le même programme #include <stdio.h> 1/3 #include <stdlib.h> void Blaise(int n); Le prototype de la fonction

Tableaux Statiques et Tableaux Dynamiques Programmation avec un tableau dynamique void main() 2/3 { int n; printf("Entrer n="); scanf("%d",&n); Blaise(n); } Entrer n=3 1 1 2 1 1 3 3 1 La fonction main, appelante la fonction Blaise

Tableaux Statiques et Tableaux Dynamiques Programmation avec un tableau dynamique void Blaise(int n) { 3/3 int j, p, i; int *tab; /* ici, pas besoin de constante connue à la compilation */ tab =(int *) malloc((n + 1) * sizeof(int)); if (tab == NULL) exit(1); for (j = 0; j <= n; j++) { *(tab+0) = *(tab+j) = 1; for (p = j - 1; p > 0; p--) *(tab+p) += *( tab+p-1); /* exploitation de tab ; par exemple, afichage : */ for (i = 0; i <= j; i++) printf("%5d", *(tab+i)); printf("\n"); } free(tab); tab=NULL; /* à ne pas oublier ( tab est une variable locale) */ La réservation dynamique de la mémoire La définition de la fonction Blaise

Tableaux Dynamiques Unidimensionnels Exemple 1 Réserver de la mémoire pour un tableau de n nombres entiers. Remplir le tableau en dialogue. Modifier la taille de la mémoire préalablement alloué pour qu’on puisse ajouter la somme des éléments entrés. Afficher le tableau au début et après l’ajout de la somme. La réservation initialle de la mémoire #include <stdio.h> 1/3 #include <stdlib.h> void main() { int *p,*q,n,s; printf("Entrer n="); scanf("%d",&n); p=(int*)malloc(n*sizeof(int)); if(p == NULL) { printf("Pas de place!\n"); exit(1); } printf("Apres malloc p=%p\n",p); Entrer n=3 Apres malloc p=245F:00F2

Tableaux Dynamiques Unidimensionnels Exemple 1 for(q=p,s=0;q<p+n;q++) 2/3 {printf("Entrer un nombre:"); scanf("%d",q); s+=*q; } for(q=p;q<p+n;q++) printf("%3d",*q); printf("\n"); Remplir le tableau dynamique. Faire la somme des éléments entrés. Entrer un nombre:11 Entrer un nombre:22 Entrer un nombre:33 11 22 33 Affichage du tableau initial

Tableaux Dynamiques Unidimensionnels Exemple 1 Modification de la taille p=(int*)realloc(p,(n+1)*sizeof(int)); 3/3 if(p == NULL) { printf("Pas de place!\n"); exit(1); } printf("Apres realloc p=%p\n",p); *(p+n)=s; for(q=p;q<p+n+1;q++) printf("%3d",*q); printf("\nLa somme=%3d\n",*(p+n)); free(p); p=NULL; Affichage du tableau après l’ajout de la somme Apres realloc p=245F:00E6 11 22 33 66 La somme=66

Tableaux Dynamiques Unidimensionnels Exemple 2 Réserver de la mémoire pour un tableau (chaîne) de n caractères . Remplir la chaîne en dialogue. Modifier la taille s’il y a besoin. Afficher la chaîne et le nombre de caractères entrés. Trouver la chaîne miroir et l’afficher. 1/4 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <conio.h> #define NUM 2 char *entrer(int n); void miroir(char *s,char *t); Les prototypes des fonctions

Tableaux Dynamiques Unidimensionnels Exemple 2 void main() 2/4 { int n,len; char *str,*rez; printf("Entrer n="); scanf("%d",&n); str=entrer(n); printf("\n"); len=strlen(str); puts(str); printf("Le nombre de caracteres=%d\n",len); rez=(char *) calloc((len + 1) , sizeof(char)); miroir(rez,str); printf("La chaine miroir est:\n"); puts(rez); free(rez); rez=NULL; }

Exemple 2 La définition de la fonction d’entré char * entrer(int n) 3/4 { int i=0,len; char *s,c; s =(char *) calloc((n + 1) , sizeof(char)); if (s == NULL) { printf("Pas de place!|n"); exit(1); } do { fflush(stdin); printf("\nEntrer un car.:"); c=getchar(); if(i >= n) {len=n+NUM; s =(char *) realloc(s,len * sizeof(char)); { printf("Pas de place!\n"); exit(1); } n=len; } s[i++]=c; printf("Entrer car suivant - O/N?"); } while(toupper (getche()) == 'O'); s[i]='\0'; free(s); /* ne ne pas oublier ( s est une variable locale) */ return (s);

Tableaux Dynamiques Unidimensionnels Exemple 2 La définition de la fonction de miroir void miroir(char *s,char *t) 4/4 { int n=strlen(t); t+=n-1; while(n) { *s++=*t--; n--; } *s='\0';

Tableaux Multidimensionnels Réflexions sur la double indexation. Supposons que nous ayons à écrire un programme qui opère sur des matrices à L lignes et C colonnes. Un tableau à deux dimensions A est à interpréter comme un tableau (uni-dimensionnel) de dimension L dont chaque composante est un tableau (uni-dimensionnel) de dimension C. On appelle L le nombre de lignes du tableau et C le nombre de colonnes du tableau. L et C sont alors les deux dimensions du tableau. Un tableau à deux dimensions contient donc L*C composantes.

Tableaux Multidimensionnels On dit qu'un tableau à deux dimensions est carré, si L est égal à C. En faisant le rapprochement avec les mathématiques, on peut dire que "A est un vecteur de L vecteurs de dimension C", ou mieux: "A est une matrice de dimensions L et C".

Tableaux Multidimensionnels Exemple Pour mémoriser les notes des 20 élèves dans les 10 devoirs d'un trimestre, nous pouvons rassembler plusieurs des tableaux uni-dimensionnels dans un tableau NOTE à deux dimensions. Dans une ligne nous retrouvons les notes de tous les élèves dans un devoir. Dans une colonne, nous retrouvons toutes les notes d'un élève.

Tableaux Multidimensionnels Exemple Déclaration et mémorisation Comme pour les tableaux à une dimension, le nom d'un tableau est le représentant de l'adresse du premier élément du tableau (c.-à-d. l'adresse de la première ligne du tableau). Les composantes d'un tableau à deux dimensions sont stockées ligne par ligne dans la mémoire. int NOTE[10][20] = { {45, 34, ... , 50, 48}, {39, 24, ... , 49, 45}, ... ... ... {40, 40, ... , 54, 44} }; <TypeSimple> <NomTabl>[<DimLigne>][<DimCol>];

Tableaux Multidimensionnels Exemple En supposant qu'une variable du type double occupe 8 octets (c.-à-d: sizeof(double)=8), pour le tableau T déclaré par: double T[10][15]; C réservera L*C*M = 10*15*8 = 1200 octets en mémoire. Initialisation Lors de la déclaration d'un tableau, on peut initialiser les composantes du tableau, en indiquant la liste des valeurs respectives entre accolades. float B[3][2] = { {-1.05, -1.10 }, {86e-5, 87e-5 }, {-12.5E4, -12.3E4} };

Tableaux Multidimensionnels Initialisation Lors de l'initialisation, les valeurs sont affectées ligne par ligne en passant de gauche à droite. Nous ne devons pas nécessairement indiquer toutes les valeurs. Les valeurs manquantes seront initialisées par zéro. Il est cependant défendu d'indiquer trop de valeurs pour un tableau. Réservation automatique Si le nombre de lignes L n'est pas indiqué explicitement lors de l'initialisation, l'ordinateur réserve automatiquement le nombre d'octets nécessaires. float B[ ][2] = { {-1.05, -1.10 }, {86e-5, 87e-5 }, {-12.5E4, -12.3E4} }; Réservation de 3*2*4 = 24 octets

Tableaux Multidimensionnels Accès aux composantes Affichage du contenu d'un tableau à deux dimensions NomTableau>[<Ligne>][<Colonne>] #include <stdio.h> main() { int a[4][4]={{1},{1},{1},{1}}; int i,j; /* Pour chaque ligne ... */ for (i=0; i<4; i++) { /*considerer chaque composante */ for (j=0; j<4; j++) printf("%3d", a[i][j]); /* Retour a la ligne */ printf("\n"); } return 0; 1 0 0 0

Tableaux Multidimensionnels Affectation avec des valeurs provenant de l'extérieur #include <stdio.h> main() { int a[3][4]; int i,j; for (i=0; i<3; i++) { for (j=0; j<4; j++) { printf("a[%d][%d]:",i,j); scanf("%d",&a[i][j]); } { for (j=0; j<4; j++) printf("%3d", a[i][j]); printf("\n"); return 0; a[0][0]:1 a[0][1]:2 a[0][2]:3 a[0][3]:4 a[1][0]:5 a[1][1]:6 a[1][2]:7 a[1][3]:8 a[2][0]:9 a[2][1]:10 a[2][2]:11 a[2][3]:12 1 2 3 4 5 6 7 8 9 10 11 12

Tableaux Multidimensionnels Un élément particulier de la matrice (m1) sera noté m1[i][j]. D'après ce que nous savons déjà, on peut l'interpréter de la manière suivante (Pour alléger les formules, nous supposons ici que la taille d'un int, et donc celle d'un unsigned, sont égales à celle d'un pointeur): m1[i] est un pointeur sur i-ème ligne float m1[NL][NC]; m1[i][j] = *(m1[ i ] + j) = *(float *)((unsigned int) m1[ i ] + j * sizeof(float))

Tableaux Multidimensionnels Etudions une autre manière d'accéder aux éléments de cette même matrice. Soient les déclarations: La variable m2 est donc déclarée comme un tableau de NL pointeurs vers des nombres flottants. Pour réaliser la matrice dont nous avons besoin, il nous sufit d'initialiser correctement ces pointeurs : chacun sera l'adresse d'une ligne de la matrice précédente. float m1[NL][NC], *m2[NL];

Tableaux Multidimensionnels Il est remarquable qu'un élément de la nouvelle matrice ainsi déclarée se note encore m2[i][j]

Tableaux Multidimensionnels L’expression m2[i][j] se traduira (en continuant à négliger les conversions des types pointeurs) par : Il nous faut initialiser le tableau de pointeurs m2. La matrice m1 est la matrice existante. m2[i][j] = *(m2[i] + j * sizeof(float)) = *(*(m2 + i * sizeof(float *)) + j * sizeof(float)) for (i = 0; i < NL; i++) m2[i] = m1[i];

Tableaux Multidimensionnels Dynamiques Il n'y a pas en C d'équivalence d'écriture permettant une utilisation directe de l'allocation dynamique pour les tableaux multidimensionnels. En effet, NC doit être connu à la compilation pour que l'expression i * NC + j ait un sens. Pour allouer dynamiquement une matrice de taille (NL,NC), on réserve un tableau unidimensionnel de taille NL*NC.

Tableaux Multidimensionnels Dynamiques Supposons que la fonction void unCalcul(int nl, int nc) implémente un algorithme qui requiert une matrice locale à nl lignes et nc colonnes. Version statique #define NL 20 #define NC 30 . . . void unCalcul(int nl, int nc) { double mat[NL][NC]; /* en espérant que nl <= NL et nc <= NC */ int i, j; /* utilisation de la matrice mat. Par exemple : */ for (i = 0; i < nl; i++) for (j = 0; j < nc; j++) mat[i][j] = 0; etc. }

Tableaux Multidimensionnels Dynamiques void unCalcul(int nl, int nc) { double **mat; int i, j; /* initialisation des pointeurs */ mat =(double **) malloc(nl * sizeof(double *)); for (i = 0; i < nl; i++) mat[i] = (double *) malloc(nc * sizeof(double)); /* utilisation de la matrice mat. Par exemple : */ for (j = 0; j < nc; j++) mat[i][j] = 0; etc. /* libération (indispensable dans le cas d'une variable locale) */ { free(mat[i]); mat[i]=NULL; } free(mat); mat=NULL; } Version dynamique

Tableaux Multidimensionnels Dynamiques Dans cette manière de procéder, les lignes de la matrice sont allouées à l'occasion de nl appels distincts de malloc. La matrice est réalisée par des morceaux de mémoire. lignes allouées séparément

Tableaux Multidimensionnels Dynamiques Exemple : Faire un programme de: 1) création d’une matrice dynamique de nombres entiers de l lignes, c colonnes; 2) affichage de la matrice. Utiliser les fonctions differentes de création et d’affichage. Les prototypes des fonctions #include <stdio.h> 1/4 #include <stdlib.h> int **creation(int l,int c); void affichage(int l, int c, int **a);

Tableaux Multidimensionnels Dynamiques Exemple void main() 2/4 { int **x,l,c; printf("nombre de lignes: "); scanf("%d",&l); printf("nombre de colonnes: "); scanf("%d",&c); x=creation(l,c); printf("La matrice cree.\n"); affichage(l,c,x); } nombre de lignes: 2 nombre de colonnes: 3 el[0][0]:1 el[0][1]:2 el[0][2]:3 el[1][0]:4 el[1][1]:5 el[1][2]:6 La matrice cree. 1 2 3 4 5 6 La fonction main, appelante les fonctions

Tableaux Multidimensionnels Dynamiques Exemple int **creation(int l,int c) 3/4 { int **t,i,j; t=(int **)malloc(l*sizeof(int *)); for(i=0;i<l;i++) t[i]=(int *)malloc(c*sizeof(int)); for(j=0;j<c;j++) { printf("el[%d][%d]:",i,j); scanf("%d",(t[i]+j)); } free(t); return t; La définition de la fonction de création

Tableaux Multidimensionnels Dynamiques Exemple void affichage(int l, int c, int **a) 4/4 { int i,j; for(i=0;i<l;i++) { for(j=0;j<c;j++) printf("%3d",*(a[i]+j)); printf("\n"); } La définition de la fonction d’affichage

Tableaux Multidimensionnels Dynamiques #include <stdio.h> #include <stdlib.h> void main() { int **t,i,j; t=(int **)malloc(2*sizeof(int*)); for(i=0;i<2;i++) t[i]=(int *)calloc(3,sizeof(int)); *(t[i]+2)=6; { for(j=0;j<3;j++) printf("%d%c",*(t[i]+j),' '); printf("\n"); } Exercice

Tableaux Multidimensionnels Dynamiques #include <stdio.h> #include <stdlib.h> void main() { int **t,i,j; t=(int **)malloc(2*sizeof(int*)); for(i=0;i<2;i++) t[i]=(int *)calloc(3,sizeof(int)); { *(t[i]+1)=i; *(t[i]+2)=i+1; } { for(j=0;j<3;j++) printf("%d%c",*(t[i]+j),' '); printf("\n"); Exercice

Tableaux de Tableaux Dynamiques (matrices non pleines) On gère en fait un ensemble de lignes de longueur différente (donc des tableaux dynamiques). On utilise alors la même méthode que pour les matrices pleines, en changeant simplement le calcul pour accéder à une composante. Chaque ligne est allouée dynamiquement (l'adresse et la longueur de chaque ligne étant stockée dans un tableau statique ou dynamique). Les manipulations de composantes (dans les lignes) restent des manipulations de type tableaux.

Tableaux de Tableaux Dynamiques (matrices non pleines) Les manipulations de lignes se font par manipulation d'adresses (par exemple pour échanger deux lignes, il suffit d'échanger les deux adresses de lignes, les lignes elles-mêmes n'étant physiquement pas déplacées). Ces tableaux de tableaux dynamiques permettent toujours un accès presque direct à un élément l,c. tab[ adresse_ligne[l] ][c]

Tableaux de Tableaux Dynamiques (Tableaux de chaînes de caractères) Le remplacement d'un tableau à deux indices par un tableau de pointeurs se révèle encore plus utile dans le traitement des tableaux de chaînes de caractères. Cette technique permet de remplacer un tableau rectangulaire dont la largeur est déterminée par la plus grande longueur possible d'une chaîne par un espace linéaire dans lequel chaque chaîne n'occupe que la place qui lui est nécessaire.

Tableaux de Tableaux Dynamiques (Tableaux de chaînes de caractères) A. Matrice de caractères

Tableaux de Tableaux Dynamiques (Tableaux de chaînes de caractères) B. Tableau de chaînes de caractères

Tableaux de Tableaux Dynamiques (Tableaux de chaînes de caractères) Mot0 Mot1 Mot2 10 mots longueur maximale: 50 caractères Mot9 char *Mot[10]

Tableaux de Tableaux Dynamiques (Tableaux de chaînes de caractères) Exemple - Ecrire un programme qui lit des mots (nombre des mots quelconque) au clavier (longueur maximale: 50 caractères). On attribue leurs adresses à un tableau dynamique a deux dimensions text. Afficher les mots saisies.

char **text Mot0 text[0] text[1] Mot1 text[2] Mot2 text[i] Motn text[n]

Tableaux de Tableaux Dynamiques (Tableaux de chaînes de caractères) Exemple #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <conio.h> #define L_MOT 51 #define NUM 2 void entrer_sortir(char **text,int *n_m,int *n_el); void main() { char **text; int n_m=0,n_el=NUM; text=(char **)malloc(n_el*sizeof(char *)); if(text==NULL) { printf("Error!Memory not allocated!\n"); exit(1); } entrer_sortir(text,&n_m,&n_el); }

Tableaux de Tableaux Dynamiques (Tableaux de chaînes de caractères) Exemple void entrer_sortir(char **text, int *n_m, int *n_el) { char temp[51]; int i; char *mot; printf("Introduire des mots terminees par un retour a la ligne\n"); fflush(stdin); do{ printf("\nmot %d:",*n_m); fgets(temp,sizeof(temp),stdin); mot=(char *)malloc((strlen(temp)+1)*sizeof(char)); if(mot==NULL) exit(1); strcpy(mot,temp); if(*n_m==*n_el) { *n_el+=NUM; text=(char**)realloc(text,*n_el*sizeof(char*)); if(text==NULL) exit(1); }

Tableaux de Tableaux Dynamiques (Tableaux de chaînes de caractères) Exemple text[(*n_m)++]=mot; printf("\nMot suivant? Y/N:"); } while(toupper(getch()) == 'Y'); strcat(*(text+*n_m-1),"\n"); printf("\nLes mots sont\n"); for(i=0;i<*n_m;i++) puts(text[i]); free(mot); mot=NULL; }