- Pourquoi utiliser des pointeurs plutôt que des variables normales ?
La réponse courte est : Ne le faites pas. ;-) Les pointeurs doivent être utilisés lorsque vous ne pouvez pas utiliser autre chose. C'est soit parce qu'il n'y a pas de fonctionnalité appropriée, soit parce qu'il manque des types de données, soit par pur souci de performance. Plus d'informations ci-dessous...
- Quand et où dois-je utiliser les pointeurs ?
La réponse courte ici est : Lorsque vous ne pouvez pas utiliser autre chose. En C, vous ne disposez d'aucun support pour les types de données complexes tels que les chaînes de caractères. Il n'y a pas non plus de moyen de passer une variable "par référence" à une fonction. C'est là que vous devez utiliser des pointeurs. De plus, vous pouvez les utiliser pour pointer vers n'importe quoi, des listes liées, des membres de structures, etc. Mais ne parlons pas de cela ici.
- Comment utiliser les pointeurs avec les tableaux ?
Avec peu d'efforts et beaucoup de confusion ;-) Si nous parlons de types de données simples tels que int et char, il y a peu de différence entre un tableau et un pointeur. Ces déclarations sont toutes deux identiques
char* a = "Hello";
char a[] = "Hello";
Vous pouvez atteindre n'importe quel élément du tableau comme ceci
printf("Second char is: %c", a[1]);
Index 1 puisque le tableau commence par l'élément 0. :-)
Ou vous pouvez également faire ceci
printf("Second char is: %c", *(a+1));
L'opérateur pointeur (le *) est nécessaire puisque nous disons à printf que nous voulons imprimer un caractère. Sans le *, la représentation de l'adresse mémoire elle-même serait imprimée. Maintenant, nous utilisons le caractère lui-même à la place. Si nous avions utilisé %s au lieu de %c, nous aurions demandé à printf d'imprimer le contenu de l'adresse mémoire pointée par 'a' plus un (dans l'exemple ci-dessus), et nous n'aurions pas eu besoin de mettre le * devant :
printf("Second char is: %s", (a+1)); /* WRONG */
Mais cela n'aurait pas seulement imprimé le deuxième caractère, mais tous les caractères des adresses mémoire suivantes, jusqu'à un caractère nul ( \0 ) ont été trouvés. Et c'est là que les choses commencent à devenir dangereuses. Que se passe-t-il si vous essayez accidentellement d'imprimer une variable de type integer au lieu d'un pointeur char avec le formateur %s ?
char* a = "Hello";
int b = 120;
printf("Second char is: %s", b);
Cela imprimerait ce qui se trouve à l'adresse mémoire 120 et continuerait à imprimer jusqu'à ce qu'un caractère nul soit trouvé. L'exécution de cette instruction printf n'est ni erronée ni illégale, puisqu'un pointeur est en fait du type int. Imaginez les problèmes que vous pourriez causer si vous utilisiez sprintf() à la place et si vous assigniez ce "tableau de caractères" bien trop long à une autre variable, qui ne dispose que d'un espace limité. Vous finirez très probablement par écrire sur quelque chose d'autre dans la mémoire et vous ferez planter votre programme (si vous avez de la chance).
Oh, et si vous n'assignez pas une valeur de chaîne de caractères au tableau de chars / pointeur lorsque vous le déclarez, vous DEVEZ lui allouer une quantité suffisante de mémoire avant de lui donner une valeur. En utilisant malloc, calloc ou similaire. Ceci puisque vous n'avez déclaré qu'un seul élément dans votre tableau / une seule adresse mémoire à pointer. Voici donc quelques exemples :
char* x;
/* Allocate 6 bytes of memory for me and point x to the first of them. */
x = (char*) malloc(6);
x[0] = 'H';
x[1] = 'e';
x[2] = 'l';
x[3] = 'l';
x[4] = 'o';
x[5] = '\0';
printf("String \"%s\" at address: %d\n", x, x);
/* Delete the allocation (reservation) of the memory. */
/* The char pointer x is still pointing to this address in memory though! */
free(x);
/* Same as malloc but here the allocated space is filled with null characters!*/
x = (char *) calloc(6, sizeof(x));
x[0] = 'H';
x[1] = 'e';
x[2] = 'l';
x[3] = 'l';
x[4] = 'o';
x[5] = '\0';
printf("String \"%s\" at address: %d\n", x, x);
/* And delete the allocation again... */
free(x);
/* We can set the size at declaration time as well */
char xx[6];
xx[0] = 'H';
xx[1] = 'e';
xx[2] = 'l';
xx[3] = 'l';
xx[4] = 'o';
xx[5] = '\0';
printf("String \"%s\" at address: %d\n", xx, xx);
Notez que vous pouvez toujours utiliser la variable x après avoir effectué un free() de la mémoire allouée, mais vous ne savez pas ce qu'elle contient. Notez également que les deux printf() peuvent vous donner des adresses différentes, car il n'y a aucune garantie que la deuxième allocation de mémoire soit effectuée dans le même espace que la première.
8 votes
Discuté précédemment à l'adresse suivante cette question J'espère que cela vous aidera !
0 votes
Une autre discussion sur les pointeurs ici .
4 votes
Pour une liste de livres, voir stackoverflow.com/questions/388242/ . Après Java, j'ai trouvé C++ accéléré très utile.
262 votes
Nous utilisons des pointeurs parce qu'il est plus facile de donner à quelqu'un l'adresse de votre maison que de donner une copie de votre maison à tout le monde.
28 votes
@RishiDua C'est la meilleure explication d'un pointeur que j'ai jamais vue. Merci pour cela, cela a amélioré ma compréhension :)
3 votes
Les pointeurs peuvent également être utilisés lorsque vous souhaitez renvoyer plus d'une valeur/d'un objet.
2 votes
Dans le prolongement de Rishi Dua, les liens dans les commentaires ci-dessus sont comme des pointeurs. Imaginez qu'au lieu de cela, ils aient copié et collé des articles ou des discussions entières ici. Nous serions rapidement "à court d'espace" sur la page
0 votes
@RishiDua si seulement j'avais vu cette phrase quand j'ai commencé à apprendre le C... tellement de temps gagné... Merci :)