Programmation en C :

13. Types pointeurs

codecommentaire
/* prog13a.c */
#include <stdio.h>
#include <string.h>

int i;

char c='A';
int n=5;
int* p=NULL;
float x=1.25;
char* s;
char* t="@ABC";
int u[3]={1,2,3};
FILE* f=NULL;

main() {
  printf("pointeur code sur : ");
    printf("%d octets\n",sizeof(void*));
  printf("pointeur vers ...\n");
  printf(" c=\'%c\' : %p\n",c,&c);
  printf(" n=%d : %p\n",n,&p);
  p=&n;
  printf(" (*p)=%d : %p\n",(*p),p);
  printf(" x=%f : %p\n",x,&x);
  printf(" chaine vide s : %p\n",s);
  printf(" t=\"%s\" : %p\n",t,t);
  printf(" u=[1,2,3] : %p\n",u);
  printf(" fichier non alloue : %p\n",&f);
  f=fopen("tmp.txt","w");
  if (f!=NULL) {
    printf(" f-> \"tmp.txt\" : %p\n",&f);
    fclose(f);
    printf(" fichier ferme : %p\n",&f);
  }
  for (i=0;i<strlen(t);i++)
    printf("t[%d]=\'%c\'\n",i,(t+i)[0]);
  for (i=0;i<3;i++)
    printf("u[%d]=%d\n",i,(u+i)[0]);
}
Il y a un type pointeur associé à chaque type. Un pointeur est une valeur donnant une adresse en mémoire lors de l'exécution du programme1.

int* p signifie que p est un pointeur sur un entier mais aussi, si p est alloué, que *p est une variable de type entier. p a initialement la valeur NULL qui indique que ce pointeur pointe sur rien (aucune adresse mémoire).

Une variable n de type entier a pour adresse &n qui est un pointeur sur un entier. L'affectation p=&n fait pointer p sur la variable n.

char* est le type pointeur sur caractère, qui correspond en C au type chaine.

Un tableau est aussi un pointeur sur le premier élément de ce tableau. Dans une fonction, il serait équivalent de passer en paramètre int u[] ou int* u, qui correspondent à la même adresse.
Il revient donc au même d'écrire u[1] ou u+1, mais ce n'est pas recommandé!!
De ce point de vue, une chaine se comporte comme un tableau.
N.B. Selon le même principe, un tableau d'entiers à deux dimensions sera de type int**, à trois dimensions int**, etc.

Le type fichier est un type pointeur. Une variable fichier a la valeur NULL si elle n'est associée à aucun fichier.
exécutioncommentaire
→ ./executable13a
pointeur code sur : 8 octets
pointeur vers ...
 c='A' : 0x100402010
 n=5 : 0x100402014
 (*p)=5 : 0x100402014
 x=1.250000 : 0x100402018
 chaine vide s : 0x0
 t="@ABC" : 0x100403030
 u=[1,2,3] : 0x100402028
 fichier non alloue : 0x0
 f-> "tmp.txt" : 0x600048518
 fichier ferme : 0x600048518
t[0]='@'
t[1]='A'
t[2]='B'
t[3]='C'
u[0]=1
u[1]=2
u[2]=3
La valeur d'un pointeur est un entier naturel exprimée en hexadécimal (préfixe 0x). La valeur NULL correspond à zéro.
codecommentaire
/* prog13b.c */
#include <stdio.h>

int i;

main (int argc, char** argv) {
  printf("programme : %s\n",argv[0]);
  for (i=1;i<argc;i++)
    printf("%de parametre : %s\n",i,argv[i]);
}
argc est un pointeur sur un pointeur de caractère, ce qui correspond à un tableau de chaines de caractères, ou encore à un tableau à deux dimensions de caractères. argc[i] est le i-ième paramètre et le (i+1)-ième argument de la ligne de commande. argc[i][j] est le j-ième caractère de la chaine argc[i].
exécutioncommentaire
→ ./executable13b
programme : ./executable13b

→ ./executable13b un deux trois quatre
programme : ./executable13b
1e parametre : un
2e parametre : deux
3e parametre : trois
4e parametre : quatre
Le premier argument argv[0] est le nom du programme, le deuxième argument argv[0]est le premier paramètre du programme, etc.
1 Voir explications détaillées données dans l'exposé (oral) du cours.