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.
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
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
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
¶
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 ?
2 3 4 8
. Sur base des règles de précédence entre les opérations, l’expression*ptr+1
équivaut en fait à(*ptr)+1
. En cas de doute, utilisez les parenthèses.