Test & QCM Métier

Fiche Pratique : Contrôle bas niveau en langage C – QCM Corrigé

1. Définition

Le contrôle bas niveau en C fait référence à la capacité du langage à manipuler directement le matériel et la mémoire, offrant une interaction étroite avec les composants physiques d’un ordinateur. Le langage C permet aux programmeurs de travailler au plus proche du système d’exploitation et du matériel, ce qui en fait un langage particulièrement adapté pour les systèmes embarqués, les pilotes de périphériques, et les systèmes d’exploitation.

2. Caractéristiques du contrôle bas niveau en C

  • Pointeurs : Permet de manipuler directement les adresses mémoire.
  • Gestion manuelle de la mémoire : Utilisation de fonctions comme malloc() et free() pour allouer et libérer de la mémoire dynamiquement.
  • Manipulation des registres et ports : Permet d’accéder aux registres matériels pour gérer les périphériques et effectuer des opérations à bas niveau.
  • Accès direct à la mémoire : Les variables peuvent être directement associées à des adresses mémoire spécifiques.

3. Pointeurs

Les pointeurs sont l’un des principaux moyens par lesquels C permet le contrôle bas niveau. Ils permettent de travailler avec les adresses mémoire directement, ce qui est indispensable pour la manipulation efficace des données et la communication avec le matériel.

  • Déclaration d’un pointeur :
   int *p;  // Déclare un pointeur vers un entier
  • Utilisation d’un pointeur :
   int a = 5;
   int *p = &a;  // P prend l'adresse de a
   printf("%d", *p);  // Affiche la valeur pointée par p (5)
  • Arithmétique des pointeurs : Permet d’incrémenter ou de décrémenter un pointeur pour accéder à des blocs de mémoire adjacents.
    Exemple :
   p++;  // Déplace le pointeur à l'adresse suivante d’un entier

4. Gestion de la mémoire

Le contrôle de la mémoire est un aspect clé du contrôle bas niveau. En C, la mémoire n’est pas automatiquement gérée, le programmeur doit explicitement allouer et libérer de la mémoire :

  • Allocation dynamique :
  • malloc() : Alloue un bloc de mémoire. int *p = (int *)malloc(sizeof(int) * 5); // Alloue de la mémoire pour un tableau de 5 entiers
  • Libération de mémoire :
    • free() : Libère la mémoire allouée dynamiquement.
    free(p); // Libère la mémoire pointée par p
  • Reallocation :
    • realloc() : Redimensionne un bloc de mémoire précédemment alloué.
      c p = (int *)realloc(p, sizeof(int) * 10); // Redimensionne le bloc pour 10 entiers

5. Manipulation des bits

C permet la manipulation au niveau du bit, utile pour la programmation de bas niveau, comme dans les systèmes embarqués et le développement de pilotes de périphériques.

  • Opérateurs de manipulation de bits :
  • & : AND bit à bit
  • | : OR bit à bit
  • ^ : XOR bit à bit
  • ~ : Négation bit à bit
  • << : Décalage à gauche
  • >> : Décalage à droite

Exemple de manipulation des bits :

unsigned char a = 5;  // 00000101 en binaire
unsigned char b = a << 1;  // Décale à gauche : 00001010 (valeur 10)

6. Accès direct à la mémoire

En C, il est possible de référencer directement des adresses mémoire spécifiques pour interagir avec le matériel ou des zones particulières de la mémoire. Ceci est particulièrement utile pour la programmation de bas niveau.

  • Exemple d’utilisation directe d’une adresse mémoire :
   int *p = (int *)0x7ff0000;  // Assigne une adresse mémoire spécifique à un pointeur

7. Registers et ports matériels

Dans certains environnements (systèmes embarqués, pilotes, etc.), le langage C permet d’accéder directement aux registres matériels ou aux ports. Ces registres sont souvent utilisés pour lire ou écrire des données directement vers/depuis des périphériques.

Exemple de lecture/écriture dans un port matériel :

#define PORT 0x378  // Adresse du port parallèle

void ecrire_dans_port(int valeur) {
    outb(valeur, PORT);  // Écrit une valeur dans le port
}

8. Interruption de programme

En programmation bas niveau, il est souvent nécessaire de gérer des interruptions matérielles. Ces interruptions peuvent être provoquées par des périphériques comme le clavier, la souris, ou d’autres composants externes.

Bien que le langage C lui-même ne gère pas directement les interruptions (cela est souvent géré par l’assembleur ou le système d’exploitation), il permet d’écrire des programmes qui les exploitent à travers des fonctions spécifiques ou des bibliothèques.

9. Exemple : Manipulation de la mémoire via les pointeurs

Voici un exemple simple de programme qui manipule directement la mémoire via les pointeurs :

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *p;
    p = (int *)malloc(sizeof(int));  // Alloue de la mémoire pour un entier
    if (p == NULL) {
        printf("Échec de l'allocation de mémoire.\n");
        return 1;
    }

    *p = 100;  // Assigne une valeur à l'adresse pointée
    printf("La valeur de *p est : %d\n", *p);

    free(p);  // Libère la mémoire allouée
    return 0;
}

10. Applications du contrôle bas niveau

  • Systèmes embarqués : Pour interagir directement avec le matériel dans les microcontrôleurs.
  • Développement de systèmes d’exploitation : Manipulation directe de la mémoire et des registres pour gérer les processus, les interruptions et le matériel.
  • Développement de pilotes : Interface entre le matériel et le système d’exploitation.
  • Optimisation des performances : Utilisation des pointeurs et de la gestion manuelle pour optimiser la vitesse et l’utilisation de la mémoire.

QCM Corrigé : Contrôle Bas Niveau en C


1. Quelle est la principale utilité des pointeurs en C ?
  • a) Ils permettent de déclarer des fonctions.
  • b) Ils permettent de manipuler les adresses mémoire.
  • c) Ils simplifient la déclaration de variables.
  • d) Ils augmentent la vitesse de compilation.

Réponse : b) Ils permettent de manipuler les adresses mémoire.

Explication : Les pointeurs en C sont utilisés pour stocker les adresses de variables, ce qui permet une manipulation directe de la mémoire.


2. Quelle est la syntaxe correcte pour obtenir l’adresse d’une variable x ?
  • a) x&
  • b) &x
  • c) *x
  • d) address(x)

Réponse : b) &x

Explication : L’opérateur & est utilisé pour obtenir l’adresse d’une variable en C.


3. Lequel des opérateurs suivants est utilisé pour accéder à la valeur à laquelle un pointeur pointe ?
  • a) &
  • b) @
  • c) *
  • d) #

Réponse : c) *

Explication : L’opérateur * est utilisé pour déréférencer un pointeur, c’est-à-dire accéder à la valeur stockée à l’adresse pointée par ce pointeur.


4. Comment alloue-t-on dynamiquement de la mémoire pour un tableau de 10 entiers en C ?
  • a) int *p = malloc(10);
  • b) int p[10];
  • c) int *p = (int *)malloc(sizeof(int) * 10);
  • d) int p = malloc(10 * sizeof(int));

Réponse : c) int *p = (int *)malloc(sizeof(int) * 10);

Explication : La fonction malloc() alloue de la mémoire dynamique et retourne un pointeur vers cette mémoire. Il est important de multiplier la taille d’un entier (sizeof(int)) par le nombre d’éléments souhaités, ici 10.


5. Quelle fonction est utilisée pour libérer la mémoire allouée dynamiquement en C ?
  • a) delete()
  • b) remove()
  • c) free()
  • d) clear()

Réponse : c) free()

Explication : La fonction free() est utilisée pour libérer la mémoire précédemment allouée avec malloc(), calloc() ou realloc().


6. Lequel des opérateurs suivants est utilisé pour effectuer un décalage à gauche des bits en C ?
  • a) >>
  • b) <<
  • c) &
  • d) ^

Réponse : b) <<

Explication : L’opérateur << effectue un décalage à gauche, ce qui revient à multiplier une valeur par une puissance de 2.


7. Que fait l’instruction suivante : int *p = (int *)0x7ff0000; ?
  • a) Elle alloue dynamiquement de la mémoire.
  • b) Elle initialise un pointeur avec une valeur aléatoire.
  • c) Elle affecte au pointeur p l’adresse mémoire spécifique 0x7ff0000.
  • d) Elle provoque une erreur de compilation.

Réponse : c) Elle affecte au pointeur p l’adresse mémoire spécifique 0x7ff0000.

Explication : En C, il est possible d’assigner une adresse mémoire spécifique à un pointeur. Cette instruction fait pointer p à l’adresse mémoire 0x7ff0000.


8. Quelle est la taille d’un pointeur sur un système 64 bits ?
  • a) 4 octets
  • b) 8 octets
  • c) 2 octets
  • d) 16 octets

Réponse : b) 8 octets

Explication : Sur un système 64 bits, les pointeurs sont de 8 octets (64 bits), car ils doivent pouvoir représenter une adresse sur 64 bits.


9. Que se passe-t-il si vous ne libérez pas la mémoire allouée dynamiquement en C ?
  • a) Rien ne se passe, car la mémoire est automatiquement libérée.
  • b) Le programme génère une erreur.
  • c) Il se produit une fuite de mémoire, ce qui peut épuiser les ressources du système.
  • d) La mémoire devient inaccessible, mais peut être réutilisée par le programme ultérieurement.

Réponse : c) Il se produit une fuite de mémoire, ce qui peut épuiser les ressources du système.

Explication : Si la mémoire allouée dynamiquement n’est pas libérée avec free(), elle reste allouée, ce qui peut entraîner une fuite de mémoire et épuiser les ressources du système sur de longues exécutions.


10. Comment s’appelle l’opération qui consiste à modifier directement le contenu d’un registre matériel en C ?
  • a) Inlining
  • b) Accès direct à la mémoire
  • c) Manipulation de bits
  • d) Accès aux ports d’entrée/sortie

Réponse : d) Accès aux ports d’entrée/sortie

Explication : L’accès direct aux registres ou ports d’entrée/sortie (I/O) permet au programme d’interagir avec les périphériques matériels en lisant ou en écrivant dans des registres spécifiques.


11. Que signifie l’opérateur & appliqué à une variable en C ?

  • a) Il renvoie la valeur de la variable.
  • b) Il renvoie l’adresse mémoire de la variable.
  • c) Il renvoie la taille de la variable.
  • d) Il renvoie un pointeur vers la variable.

Réponse : b) Il renvoie l’adresse mémoire de la variable.

Explication : L’opérateur & est utilisé pour obtenir l’adresse mémoire d’une variable, ce qui est crucial pour l’utilisation des pointeurs.


12. Quelle est l’utilité d’une opération de masque (AND bit à bit) en programmation bas niveau ?

  • a) Elle permet de basculer tous les bits d’une valeur.
  • b) Elle permet d’annuler une variable.
  • c) Elle permet de vérifier ou de modifier certains bits spécifiques d’une valeur.
  • d) Elle effectue un décalage de bits.

Réponse : c) Elle permet de vérifier ou de modifier certains bits spécifiques d’une valeur.

Explication : L’opération AND bit à bit (&) permet de créer des masques pour isoler ou manipuler des bits spécifiques dans une valeur.


Ce QCM couvre les concepts clés du contrôle bas niveau en C, tels que les pointeurs, la gestion de la mémoire, la manipulation des bits et l’accès direct au matériel. Le contrôle bas niveau est essentiel pour développer des programmes efficaces, particulièrement dans des environnements où la gestion des ressources matérielles est cruciale.

Autres articles

Guide pour rédiger un QCM en microéconomie...
1. Structurer le QCMUn bon QCM doit être structuré autour...
Read more
Exercices Corrigés : Bilan Matière en Génie...
Fiche de Révision : Bilan Matière en Génie des ProcédésLe...
Read more
Guide : Le GRAFCET du Point de...
Le GRAFCET (Graphe Fonctionnel de Commande Étape-Transition) est un outil...
Read more

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *