DS 4 (MP2I 2022-2023) — C et mémoire¶
Devoir surveillé · MP2I · 2022-2023 · partie I du DS 4 (2 h 30 au total)
Cours : Gestion de la mémoire
Autres parties : II. Placement des convives
Tout document interdit. Tout dispositif électronique interdit.
On vous demande d'écrire lisiblement et de bien présenter. Les programmes en particulier doivent être bien indentés et lisibles.
C et mémoire¶
On considèrera dans ce sujet que tous les en-têtes ont déjà été inclus en C.
Question 1
Expliquer brièvement l'organisation de la mémoire d'un programme compilé.
On tachera de faire un diagramme indiquant les différentes zones mémoire ainsi que leur rôle.
Corrigé
Voir cours.
Question 2
Si i est une valeur du type int et que p et q
sont des pointeurs du type int *, indiquez les instructions
d'affectation licites :
a) p = i; b) *p = &i; c) &p = q;
d) p = &q; e) p = *&q; f) p = q;
g) p = *i; h) *p = q; i) *p = *q;
Corrigé
Les instructions e, f et i sont licites.
Pour s'en convaincre, on pouvait faire un tableau en indiquant les types à
gauche et à droite du symbole = :
| gauche | droite | ||
|---|---|---|---|
| a | int * |
= | int |
| b | int |
= | int * |
| c | int ** |
= | int * |
| d | int * |
= | int ** |
| e | int * |
= | int * |
| f | int * |
= | int * |
| g | int * |
= | invalide |
| h | int |
= | int * |
| i | int |
= | int |
Question 3
-
Écrire une fonction de prototype
void max_min(int a[], int n, int *min, int *max);qui prend en entrée un tableau
tdenentiers, supposé non vide, et place la plus petite valeur dansminpassé par pointeur, et sa plus grande valeur dansmax. -
Écrire une fonction
maintypique qui testerait cette fonction sur le tableau{1, 5, -1, 3}en affichant la réponse sous la formemin=-1 max=5
Corrigé
void max_min(int a[], int n, int *min, int *max)
{
*min = a[0];
*max = a[0];
for (int i = 1; i < n; i++)
{
if (*min > a[i])
*min = a[i];
if (*max < a[i])
*max = a[i];
}
}
int main(void) {
int t[] = { 1, 5, -1, 3 };
int max, min;
max_min(t, 4, &min, &max);
printf("min=%d max=%d\n", min, max);
}
Question 4
Écrire une fonction de prototype
void find_two_largest(int a[], int n,
int *largest, int *second_largest);
qui prend en entrée un tableau t de n entiers,
en supposant \(n > 1\),
et place la plus grande valeur présente dans largest
et la seconde plus grande dans second_largest.
Exemple : pour { 1, 4, 5, 2, 4 } on va donc avoir 5 dans
largest et 4 dans second_largest.
Corrigé
Un classique des fausses questions faciles. Il y a deux pièges :
- on ne peut pas initialiser aux deux premières valeurs parce qu'elles peuvent être égales. Il faut donc chercher les deux premières valeurs différentes.
- il faut bien faire attention à ne pas faire deux
ifsuccessifs dans la boucle car le premierifperturbe le second.
void find_two_largest(int a[], int n,
int *largest, int *second_largest)
{
*largest = a[0];
int i = 1;
while (a[i] == *largest)
i++;
if (a[i] > *largest) {
*second_largest = *largest;
*largest = a[i];
} else {
*second_largest = a[i];
}
for (int j = i + 1; j < n; j++) {
if (a[j] > *largest) {
*second_largest = *largest;
*largest = a[j];
} else if (a[j] < *largest && a[j] > *second_largest)
*second_largest = a[j];
}
}
On suppose ici que le tableau contient au moins deux valeurs distinctes,
sinon la boucle while sort du tableau.
Question 5
On considère les structures suivantes :
struct point {
int x;
int y;
};
struct rectangle {
struct point upper_left;
struct point lower_right;
};
Écrire une fonction de prototype
rectangle *mon_rectangle();
qui alloue et renvoie un rectangle de coin supérieur gauche de
coordonnées \((10, 25)\) et de coin inférieur bas \((20, 15)\).
Corrigé
Faute de typedef, il faut écrire struct rectangle (ou ajouter
typedef struct rectangle rectangle;).
struct rectangle *mon_rectangle() {
struct rectangle *r = malloc(sizeof(struct rectangle));
r->upper_left.x = 10;
r->upper_left.y = 25;
r->lower_right.x = 20;
r->lower_right.y = 15;
return r;
}
Question 6
Écrire une fonction de prototype
int *create_array(int n, int initial_value);
qui alloue un tableau de \(n\) entiers et initialise chaque case
avec la valeur initial_value.
Corrigé
int *create_array(int n, int initial_value)
{
int *t = malloc(n * sizeof(int));
for (int i = 0; i < n; i++)
t[i] = initial_value;
return t;
}