Questions à choix multiples

La matière couverte cette semaine la section relative aux types de données (jusque et y compris la section relative aux expressions de manipulation de bits

Question 1. Conversion de types

En C tout comme dans des langages comme Java, il est possible de convertir des nombres d’un type primitif vers un autre. Cependant, alors que le compilateur Java vérifie si la conversion est sans risque, le compilateur C ne fait aucune vérification et suppose que si le programmeur a effectué une conversion explicite entre types, il a pris ses précautions. Sur une architecture où les types de données sont stockés comme suit :

// char                     1 octet(s)
// unsigned char            1 octet(s)
// short                    2 octet(s)
// unsigned short           2 octet(s)
// int                      4 octet(s)
// unsigned int             4 octet(s)


int i;
short s;
long l;
char c;
unsigned int ui;
unsigned char uc;
unsigned long ul;
unsigned short us;
Un seul des fragments de code ci-dessous contient des conversions de type qui sont sans risque. Lequel ?
i=(int ) s;
s=(short) uc;
l=(long )i;
ui=(unsigned int) us;
s=(short) c;
ul=(unsigned long )ui;
ui=(unsigned int ) s;
us=(unsigned short) uc;
l=(long )i;
i=(int ) us;
us=(unsigned short) i;
l=(long )c;
ui=(int) s;
s=(short) c;
ul=(unsigned long )ui;

Question 2. Notation hexadécimale

Parmi les affirmations suivantes relatives aux nombres en représentation hexadécimale, une seule est vraie. Laquelle ?
La représentation hexadécimale du nombre entier positif 27 est 1B
La représentation hexadécimale du nombre entier positif 67 est 43

La représentation hexadécimale du nombre entier positif 67 est 34

La représentation hexadécimale du nombre entier positif 27 est B1

La représentation hexadécimale du nombre entier positif 62 est B1

La représentation hexadécimale du nombre entier positif 128 est FF

Question 3. Notation binaire

Parmi les affirmations suivantes relatives aux nombres en représentation binaire, une seule est vraie. Laquelle ?
La représentation binaire du nombre entier positif 99 est 1100011
La représentation binaire du nombre entier positif 176 est 10110000

La représentation binaire du nombre entier positif 90 est 1100011

La représentation binaire du nombre entier positif 176 est 10110001

La représentation binaire du nombre entier positif 166 est 10110001

La représentation binaire d’un nombre entier positif impair a toujours 0 comme bit de poids faible.

Question 4. Notation binaire

Parmi les affirmations suivantes relatives aux nombres signés en représentation binaire, une seule est vraie. Laquelle ?
Si la variable x est un short (signé) sur 16 bits, alors la représentation binaire de -17 est 11111111 11101111
Si la variable x est un short (signé) sur 16 bits, alors la représentation binaire de -23 est 11111111 11101001

Si la variable x est un short (signé) sur 16 bits, alors la représentation binaire de -17 est 00000000 00010001

Si la variable x est un short (signé) sur 16 bits, alors la représentation binaire de -17 est 10000000 00010001

Si la variable x est un short (signé) sur 16 bits, alors la représentation binaire de -23 est 00000000 00010111

Si la variable x est un short (signé) sur 16 bits, alors la représentation binaire de -23 est 11111111 11100110

Question 5. Manipulations de bits

Si la variable c est de type unsigned char sur 8 bits, laquelle des suites d’instructions ci-dessous permet d’en échanger les 4 bits de poids faible avec les 4 bits de poids fort ?
unsigned char temp1, temp2;
temp1 = c & 0x0F;
temp2 = c & 0xF0;
temp1=temp1 << 4;
temp2=temp2 >> 4;
c= temp2|temp1;
unsigned char temp1, temp2;
temp1=c << 4;
temp2=c >> 4;
c= temp2|temp1;
unsigned char temp1, temp2;
temp1=c << 4;
temp2=c >> 4;
c= temp2||temp1;
unsigned char temp1, temp2;
temp1=4 << temp1;
temp2=4 >> temp2;
c= temp2|temp1;
unsigned char temp1, temp2;
temp1 = c && 0x0F;
temp2 = c && 0xF0;
temp1=temp1 << 4;
temp2=temp2 >> 4;
c= temp2|temp1;

Question 6. Multiplication entière

Parmi les expressions suivantes, une seule permet de calculer x*7 lorsque x est un nombre entier. Laquelle ?
(x<<3)-x
(x>>3)-x
(x<<3)+x
(x<<7)
(x>>7)

Question 7. Extraction de bits

Il est parfois nécessaire en C de manipuler directement la représentation binaire d’un nombre. Si f est un nombre de type float stocké sur 32 bits, laquelle des expressions ci-dessous peut-elle être intégrée dans ce code pour afficher positif ou négatif en fonction du signe de ce nombre ?

if(<à compléter>)
  printf("positif\n");
else
  printf("negatif\n");
!(((unsigned int) f) & 0x80000000)
!(((unsigned int) f) >> 31)
!(((unsigned int) f) & 0x10000000)
!(((unsigned int) f) << 31)
!(((unsigned int) f) > 31)
!(((unsigned int) f) & 31)

Question 8. Chaînes de caractères

Une seule des fonctions ci-dessous retourne correctement le nombre d’occurrences du caractère c dans la chaîne de caractères c. Laquelle ?
int count1(char *s, char c) {
  int i=0;
  int count=0;
  while(*(s+i)!='\0') {
    if(*(s+i)==c) {
      count++;
    }
    i++;
  }
  return(count);
}
int count(char *s, char c) {
   int count=0;
   while(*(s)!='\0') {
     if(*(s)==c) {
       count++;
     }
     s++;
   }
   return(count);
}
int count1(char *s, char c) {
  int i=0;
  int count=0;
  while(i<s.length) {
    if(*(s+i)==c) {
       count++;
    }
    i++;
  }
  return(count);
}
int count1(char *s, char c) {
  int i=0;
  int count=0;
  while(*s!=`\0`) {
    if(*(s+i)==c) {
      count++;
    }
    i++;
  }
  return(count);
}
int count(char *s, char c) {
  int count=0;
  while(*(s)!='\0') {
    s++;
    if(*(s)==c) {
      count++;
    }
  }
  return(count);
}
int count(char *s, char c) {
  int count=0;
  while(s!='\0') {
    if(s==c) {
      count++;
    }
    s++;
  }
  return(count);
}

Question 9. Pointeurs

Si ptr a été déclaré sous la forme int *ptr, un seul des groupes d’affirmations suivantes est vrai, lequel ?
  • l’expression *(ptr + 1) est une valeur entière
  • l’expression ptr[1] est une valeur entière
  • l’expression ptr est une adresse en mémoire
  • l’expression *(ptr) + 1 est une valeur entière
  • l’expression ptr[2] est une valeur entière
  • l’expression ptr++ est une adresse en mémoire
  • l’expression &(ptr) + 1 est un nombre entier
  • l’expression ptr[2] est une valeur entière
  • l’expression &ptr est une adresse en mémoire
  • l’expression *(ptr+1)==ptr[1] est syntaxiquement invalide
  • l’expression ptr[2] est une valeur entière
  • l’expression &ptr est une adresse en mémoire
  • l’expression *(ptr+1)==ptr[1] est toujours vraie
  • l’expression ptr-- est syntaxiquement invalide

Question 10. Pointeurs et tableaux

Considérons le tableau tab déclaré comme suit :

#define SIZE 30
int tab[SIZE];
int *ptr;
Dans une architecture 32 bits, un seul des groupes d’affirmations ci-dessous est vrai. Lequel ?
  • l’expression tab[i] correspond à la même valeur dans le tableau que *(tab+i) lorsque 0<=i<29
  • l’assignation ptr=(tab+i) est valide et après cette assignation, *ptr retourne la même valeur que tab[i] lorsque 0<=i<29
  • l’expression tab[0] correspond à la même valeur dans le tableau que *(tab)
  • l’assignation ptr=(tab+i) est valide et après cette assignation, *ptr retourne la même valeur que tab[i] lorsque 0<=i<29
  • l’expression tab[i] correspond à la même valeur dans le tableau que *(tab+i) lorsque 0<=i<29
  • l’assignation tab=(tab+i) est valide et après cette assignation, *tab retourne le ième élément du tableau lorsque 0<=i<29
  • l’expression tab[0] correspond à la même valeur dans le tableau que &(tab)
  • l’assignation tab=(tab+i) est valide et après cette assignation, *tab retourne le ième élément du tableau lorsque 0<=i<29
  • l’expression tab[i] correspond à la même valeur dans le tableau que *(tab)+i lorsque 0<=i<29
  • l’assignation ptr=(tab) est valide et après cette assignation, *(ptr+i) retourne le ième élément du tableau lorsque 0<=i<29

Question 11. Pointeurs

Considérons le fragment de code ci-dessous.

int tab[]={ 10, 20, 30, 40 };
int *ptr1=&tab[1];
int *ptr2=&tab[3];
Dans ce code, une seule des affirmations suivantes est vraie, laquelle ?
l’expression ptr2-ptr1 vaut 2
les expressions *(ptr1-1) et *(ptr2-3) retournent toutes les deux la même valeur, 10

l’expression ptr2-ptr1 vaut 20

les expressions *(ptr1-1) et *(ptr2-3) retournent toutes les deux la même valeur, 1

l’expression *(ptr2-ptr1) retourne la valeur 20

Question 12. Pointeurs et fonctions

En C, il est parfois nécessaire d’échanger le contenu de deux variables. Si a et b sont des variables de type int, laquelle des fonctions ci-dessous permet de réaliser cette échange entre les contenu des variables ?
void swap(int *i, int *j) {
  int k;
  k=*i;
  *i=*j;
  *j=k;
}
//échange
swap(&a,&b);
void swap(int *i, int *j) {
  int k;
  k=*j;
  *j=*i;
  *i=k;
}
//échange
swap(&a,&b);
void swap(int i, int j) {
  int k;
  k=i;
  i=j;
  j=k;
}
//échange
swap(a,b);
void swap(int i, int j) {
  int k;
  k=i;
  i=j;
}
//échange
swap(&a,&b);
void swap(int i, int j) {
  int k;
  int *i_ptr=&i;
  int *j_ptr=&j;
  k=i;
  *(i_ptr)=j;
  *(j_ptr)=k;
}
//échange
swap(a,b);

Question 13. Pointeurs et structures

Dans un programme de manipulation de fractions, on définit la structure suivante pour représenter une fraction entière :

struct fract_t {
     int num;
     int denum;
};

On veut pouvoir facilement écrire une fonction de type void qui remplace la valeur stockée dans la fraction par le résultat de l’addition de la fraction et un nombre entier passé en fragment. La spécification de cette fonction pourrait être :

/*
 * augmente la fraction passé en argument de l'entier n et place
 * la somme calculée dans la fraction
 * Exemples
 *  Si f vaut 1/3, alors l'application de la fonction avec f et 2 comme
 *  arguments a comme résultat de stocker la valeur 7/3 dans f
 *  Si f vaut 2/1, alors l'application de la fonction avec f et 1 comme
 *  arguments a comme résultat de stocker la valeur 3/1 dans f
 */
Laquelle des signatures ci-dessous peut-elle être utilisée pour effectuer cette opération et modifier la fraction passé en argument ?
void scale(struct *fract_t f, int s);
// appel à la fonction :
// scale(&f,3);
void scale(struct fract_t f, int s);
// appel à la fonction :
// scale(f,3);
void scale(int num, int den, int s);
// appel à la fonction :
// scale(f.num, f.denum,3);

Verifiez vos réponses