liteqz.com
On appelle souvent le premier « tableau statique » et le deuxième « tableau dynamique » (bonjour la confusion). void exemple_1(void) { int tableau[] = {0, 1, 2, 3, 4, 5}; printf("tableau =%x\n", tableau); printf("&tableau =%x\n\n", &tableau);} void exemple_2(void) int *pointeur = calloc(6, sizeof(int)); printf("pointeur =%x\n", pointeur); printf("&pointeur =%x\n\n", &pointeur);} On réalise les mêmes opérations sur ces deux objets. S'ils sont équivalents, on devrait obtenir les mêmes résultats. Ô surprise! les résultats ne sont pas identiques: &tableau[0] = 22fec8 &tableau = 22fec8 pointeur = 3e2c98 &pointeur = 22feec Le constat est simple: un tableau et un pointeur sont deux objets différents avec des comportements différents. Note: cet exemple peut ne pas paraitre très intéressant. Je le donne car c'est avec un code comme ça que je me suis dit qu'il y avait vraiment quelque chose qui m'échappait entre tableaux et pointeurs. Pour schématiser, j'avais fait une fonction attendant ne paramètre un pointeur sur tableau et en lui passant un tableau ou l'adresse de ce tableau, j'obtenais le même résultat.
d'accès aux champs. En supposant que com contienne une telle commande, voici le calcul du prix total: double P_TTC, P_AvantRemise, P_Total; P_TTC = * (1 + / 100); P_AvantRemise = P_TTC * com. q; P_Total = P_AvantRemise - P_AvantRemise * / 100; Les unions se déclarent de la même manière que les structures. Elles possèdent donc elles aussi des champs typés. Mais on ne peut utiliser qu'un seul champ à la fois. En fait tous les champs d'une union se partagent le même espace mémoire. Les unions sont rarement nécessaires sauf lors de la programmation système. L'utilisation de pointeurs sur structures est très courante en C. Voici un exemple d'utilisation d'un pointeur sur un complexe: complexe a = { 3. 5, -5. 12}; complexe * p = &a; (*p) = 1; (*p) = -1; /* a vaut (1 - i) */ Nous avons été obligé de mettre des parenthèses autour de *p car l'opérateur. est plus prioritaire que l'opérateur *. Cela rend difficile la lecture d'un tel programme. Heureusement, l'utilisation de pointeurs sur structures est si courante que le C définit l'opérateur -> pour accéder aux champs d'une structure via un pointeur.
Nous pouvons maintenant accéder à chaque élément du tableau Tab en utilisant p++ pour passer d'un élément à un autre. Attention! vous ne pouvez pas décrémenter un pointeur une fois incrémenté. p-- ne fonctionnera pas. Pointeur vers un tableau (1D) Comme nous l'avons vu précédemment, nous pouvons utiliser un pointeur pour pointer sur un tableau, puis utiliser ce pointeur pour accéder aux éléments du tableau. Exemple 1: #include < stdio. h> int main(void){ int Tab[4] = {3, 2, 7, 9}, i; p = Tab; for (i = 0; i < 4; i++){ printf("%d \n", *p); p++;} return 0;} Dans le programme ci-dessus, le pointeur *p affichera une par une toutes les valeurs stockées dans le tableau. Nous pouvons également utiliser l'adresse de base (Tab dans le cas précédent) pour agir en tant que pointeur et afficher toutes les valeurs, comme dans l'exemple suivant. Exemple 2: #include < stdio. h> printf("%d \n", *(Tab + i));} La forme généralisée pour utiliser un pointeur avec un tableau, *(Tab+i) Est identique à: Tab[i] Pointeur sur un tableau multidimensionnel Un tableau multidimensionnel est de forme, Tab [i] [j].
Voyons comment nous pouvons faire pointer un pointeur vers un tel tableau. Comme nous le savons maintenant, le nom du tableau donne son adresse de base. Dans Tab[i][j], Tab donnera l'adresse de base de ce tableau. Même Tab+0+0 donnera également l'adresse de base, c'est-à-dire l'adresse de l'élément Tab[0][0]. Exemple 3: #include < stdio. h> int main(void) { int i, j; int Tab[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; for (i = 0; i < 3; i++) for (j = 0; j < 4; j++) printf("Tab[%d][%d] =%d \n", i, j, *(p + (i * 4) + j));}} Tab[0][0] = 1 Tab[0][1] = 2 Tab[0][2] = 3 Tab[0][3] = 4 Tab[1][0] = 5 Tab[1][1] = 6 Tab[1][2] = 7 Tab[1][3] = 8 Tab[2][0] = 9 Tab[2][1] = 10 Tab[2][2] = 11 Tab[2][3] = 12 Voici la forme généralisée d'utilisation du pointeur avec des tableaux multidimensionnels. *(p + (i x nb_colonnes + j)) Où, p contient l'adresse du premier élément du tableau, i et j désignent la ième ligne et la jième colonne du tableau. Et nb_colonnes indique le nombre total de colonnes dans la ligne du tableau.
Les développeurs C y ont donc souvent recours; et il vous est demandé de savoir la manipuler. Vous verrez, c'est du plus bel effet dans les discussions mondaines et c'est (presqu'aussi? ) efficace qu'un "Wind Surf" dernière génération pour frimer sur les plages. Par ailleurs, pour écrire certains algorithmes, par exemple pour parcourir plusieurs tableau avec plusieurs valeurs d'indice en même temps, utiliser des indices pointeur peut se révéler beaucoup (... vraiment très beaucoup... ) plus clair qu'utiliser des des indices entier. Vous aurez l'occasion d'avoir quelques exemples en TP. Ceci étant dit, les compilateurs actuels parviennent à optimiser les parcours par indice entier plus efficacement que les parcours par indice pointeur. *** TODO eh pourquoi donc??? j'ai jamais pigé, mais j'ai constaté. sur plusieurs archis... Ainsi, si on cherche à maximiser l'efficacité du code, il peut être préférable d'utiliser un bon vieux indice entier.
0, 2. 0, 3. 4, 17. 0, 50. 0};
double *p;
int i;
/* la sortie de chaque élément de tableau */
cout<<"Les valeurs du tableau en utilisant le pointeur p"<