Questions à choix multiples

Question 1. Pointeurs et tableaux

Les pointeurs peuvent être utilisés pour accéder à des tableaux. Considérons un fragment de code C utilisant un tableau d’entiers à une dimension :

int a[]={2,4,3,4,8};
int * ptr;

printf("%d %d %d %d\n",a[0],a[1],a[2],a[a[3]]);

Lors de son exécution, ce programme affiche 2 4 3 8 sur sa sortie standard.

Après exécution de ptr=&(a[0]);, une seule des instructions ci-dessous affiche la même séquence de chiffres. Laquelle ?
printf("%d %d %d %d\n",*ptr,*(ptr+1),*(ptr+2),*(ptr+*(ptr+3)));
printf("%d %d %d %d\n",*ptr,*ptr+1,*ptr+2,*(ptr+*(ptr+3)));
printf("%d %d %d %d\n",*ptr,*(ptr++),(*ptr++),*(ptr+*(ptr++)));
printf("%d %d %d %d\n",*ptr,*(ptr+0),*(ptr+1),*ptr+*(ptr+2));
printf("%d %d %d %d\n",*ptr,*ptr+1,(*ptr+1),*(ptr+(ptr+3)));

Question 2. Traitement de argv

Un programme C doit souvent pouvoir manipuler les arguments qui lui sont passés. Les variables argc et argv qui sont passées à la fonction main permettent d’accéder à ces arguments. Le fragment de programme ci-dessous affiche sur la sortie standard ses différents arguments.

while(i<argc) {
  printf("%d %p %s\n",i,&(argv[i]),argv[i]);
  i++;
}

Un exemple d’exécution de ce fragment de programme est présenté ci-dessous :

#./a.out a b cd
0 0x7fff5fbff788 ./a.out
1 0x7fff5fbff790 a
2 0x7fff5fbff798 b
3 0x7fff5fbff7a0 cd
A côté de la notation argv[i], il est aussi possible d’accéder à argv en utilisant des pointeurs. Parmi les fragments de programme ci-dessous, un seul est correct et affiche le même résultat que ci-dessus.
char **ptr;
int i=0;
ptr=argv;
while(i<argc) {
  printf("%d %p %s\n",i,&(*ptr),*ptr);
  i++;
  ptr++;
}
char **ptr;
int i=0;
ptr=argv;
while(i<argc) {
  printf("%d %p %s\n",i,&(ptr),*ptr);
  i++;
  ptr++;
}
char *ptr;
int i=0;
ptr=*argv;
while(i<argc) {
  printf("%d %p %s\n",i,&(ptr),*ptr);
  i++;
  ptr++;
}
int i=0;
while(i<argc) {
   printf("%d %p %s\n",i,&(argv+i),*(argv+i));
   i++;
}
int i=0;
while(i<argc) {
  printf("%d %p %s\n",i,&(*(argv+i)),(argv+i));
  i++;
}

Question 3. Pointeurs et tableaux à deux dimensions

En C, il est possible d’accéder aux données stockées dans un tableau à deux dimensions via la notation a[i][j] mais aussi en utilisant des pointeurs. Considérons le fragment de code ci-dessous :

int m[3][4]= { { 1, 2, 3, 4} ,
               { 5, 6, 7, 8} ,
               { 9, 10, 11, 12} };

printf("%p %d %d %d\n",m, m[1][2], m[0][5], m[2][2]);

Un compilateur Java n’accepterait pas de compiler ce programme qui tente d’accéder à l’élément m[0][5] de la matrice, élément qui n’existe pas sur base de l’initialisation du tableau m. De nombreux compilateurs C acceptent ce fragment de code sans contrainte. Lorsque le programme s’exécute il affiche :

0x7fff5fbff750 7 6 11
Parmi les fragments de programme ci-dessous, un seul utilisant la notation avec les pointeurs est correct et affiche la même sortie. Lequel ?
int *ptr;

ptr=&(m[0][0]);
printf("%p %d %d %d\n",ptr, *(ptr+4*1+2), *(ptr+4*0+5), *(ptr+2*4+2));
int **ptr=m;
printf("%p %d %d %d\n",ptr, *(ptr+4*1+2), *(ptr+4*0+5), *(ptr+2*4+2));
int *ptr=m;
printf("%p %d %d %d\n",ptr, *(ptr+4*1+2), *(ptr+4*0+5), *(ptr+2*4+2));

Question 4. Variable errno

En C, la variable errno est utilisée par le système pour fournir une indication sur une erreur qui s’est produite lors de l’exécution d’un appel système ou d’une fonction de la librairie. Parmi les fonctions ci-dessous, une seule ne modifie pas errno en cas d’erreur. Laquelle ?

getpid(2)

malloc(3)

exit(2)

setenv(3)

unsetenv(3)

pthread_join(3)

Vérifiez vos réponses