Questions à choix multiples¶
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)
// long 4 octet(s)
// unsigned long 4 octet(s)
int i;
short s;
long l;
char c;
unsigned int ui;
unsigned char uc;
unsigned long ul;
unsigned short us;
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¶
27 est 1B67 est 43La 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¶
99 est 1100011176 est 10110000La 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¶
x est un short (signé) sur 16 bits, alors la représentation binaire de -17 est 11111111 11101111x est un short (signé) sur 16 bits, alors la représentation binaire de -23 est 11111111 11101001Si 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¶
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¶
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¶
c dans la chaîne de caractères s. 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¶
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
ptrest une adresse en mémoire
- l’expression
*(ptr) + 1est 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) + 1est un nombre entier - l’expression
ptr[2]est une valeur entière - l’expression
&ptrest 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
&ptrest 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;
- l’expression
tab[i]correspond à la même valeur dans le tableau que*(tab+i)lorsque0<=i<29 - l’assignation
ptr=(tab+i)est valide et après cette assignation,*ptrretourne la même valeur quetab[i]lorsque0<=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,*ptrretourne la même valeur quetab[i]lorsque0<=i<29
- l’expression
tab[i]correspond à la même valeur dans le tableau que*(tab+i)lorsque0<=i<29 - l’assignation
tab=(tab+i)est valide et après cette assignation,*tabretourne le ième élément du tableau lorsque0<=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,*tabretourne le ième élément du tableau lorsque0<=i<29
- l’expression
tab[i]correspond à la même valeur dans le tableau que*(tab)+ilorsque0<=i<29 - l’assignation
ptr=(tab)est valide et après cette assignation,*(ptr+i)retourne le ième élément du tableau lorsque0<=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];
ptr2-ptr1 vaut 2*(ptr1-1) et *(ptr2-3) retournent toutes les deux la même valeur, 10l’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¶
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 */
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);
sest négatif, la conversion enunsigned intrisque de poser problème.