QCM Notions avancées de C

De Ensiwiki
Aller à : navigation, rechercher

1. Pour déclarer un tableau T non-constant de caractères constants, on peut utiliser

const char *T
Oui. const s'applique à ce qui le suit immédiatement. Ici, ce sont les caractères (char) qui sont constants.
char const *T
Cette syntaxe est équivalente à la précédente. On peut dire que *T est constant.
char * const T
Ici, c'est la variable T qui est constante (i.e. T = ...; est interdit)

2. Si a et b sont de type char *, alors le code while (*a++ = *b++); effectue ...

Une comparaison de chaines de caractères
Rien d'intéressant
Une copie de chaine de caractères
Oui, on pourrait l'écrire while (true) { *a = *b; if (*a == NULL) break; a++; b++ };

3. Pour obtenir le 23ème bit d'un mot de 32 bits X (i.e. 0 si le bit est à 0, et autre chose si le bit est à 1), on peut écrire :

(1 << 23) & X
Oui, on crée un masque sur le 23ème bit avec (1 << 23) et on fait un et bit-à-bit
0x800000 & X
C'est équivalent, on peut s'en rendre compte en écrivant 0x800000 = 8 * (0x100000) = 2^3 * 2^20 = 2^23
(X << 9) >> 31
Ça ne marchera que si X est effectivement sur 32 bits, et cette syntaxe est peu recommandée.

4. Le programme

int *f() {
        int x = 42;
        return &x;
}
Provoque une erreur à la compilation
Non, même si on aura sans doute un warning
Provoque une erreur à l'édition de liens
Aucune chance : l'édition de liens s'occupe de trouver les symboles externes (fonctions, variables globales, ... définies en dehors d'un fichier)
Provoque une erreur à l'exécution
En fait, pas forcément une erreur, mais un comportement indéfini (i.e. n'importe quoi peut arriver !)

5. Un bon programmeur C écrirait plutôt :

#define MAX(a, b) (a >= b) ? a : b
Imaginez comment s'expansent les macros 3*MAX(x, y) ou MAX(x=3, Z) ...
#define MAX(a, b) (((a) >= (b)) ? (a) : (b))
On ne peut pas prévoir comment MAX sera appelé. Donc, on met toujours des parenthèses autour du résultat et autour des arguments.

6. Un bon programmeur C écrirait plutôt :

#define SWAP(x, y) tmp = x; x = y; x = tmp
Non, avec cette syntaxe, un simple
if (foo) SWAP(a, b);
va tout casser !
#define SWAP(x, y) { int tmp = x; x = y; x = tmp; }
Non, avec cette syntaxe, on va avoir des surprises si on écrit
if (foo) SWAP(a, b); else whatever();
#define SWAP(x, y) do { int tmp = (x); (x) = (y); (x) = tmp; } while (0)
Oui. Cette syntaxe est bien connue et permet de garantir que la macro se comportera bien où qu'elle soit appelée. On compte sur le compilateur pour optimiser le tout. Les parenthèses autour de x et y ne sont pas vraiment utiles ici : x et y doivent être des variables. Mais on garde les bonnes habitudes ...
cf. [1] pour plus de détails.

Votre pointage est 0 / 0