EXAMEN LANGAGE C ( PROGRAMMATION C ) TEST  16 /XX annee acaDEMIQUE 2024

EXAMEN + CORRIGE EN LANGAGE C

EXERCICE 1 : gENERALITES 13 pts

A) Questions de cours sur le doublet pointeur-tableau-2D

On suppose que tab est déclaré comme suit : int tab[4][5]

  1. 1) Schématiser la déclaration « int tab[4][5]»
  2. 2) Quelle est la nature du contenu de tab ?
  3. 2) Que désigne tab[i][j], 0<=i<4 et 0<=j<5 ?
  4. 3) Que désigne tab[i] ?
  5. 4) Que désigne (tab[i]+j), 0<=i<4 et 0<=j<5 ?
  6. 5) Que désigne *(tab[i]+j) ?
  7. 6) Peut on modifier la valeur de tab[i][j] ?
  8. 7) Que désigne &(tab[i][j]) ?

B:  Expressions équivalentes sur le doublet pointeur-vecteur

On suppose que tab est déclaré comme suit : int tab[4][5]

1) Donner deux syntaxes pour désigner l'adresse de début de la ligne i (c'est à dire l'adresse de la première case de la ligne i).

2) Donner deux syntaxes différentes pour désigner l'adresse  de la case située à l'intersection de la ligne i et de la colonne j de tab.

3) Donner deux syntaxes différentes pour désigner le contenu  de la case située à l'intersection de la ligne i et de la colonne j de tab.

C : Soit le code suivant :

void test(){

  int *ptint;

  int tab1[]={1, 2, 3, 4, 5, 6};

  int tab2[6]={23, 20, 900, 4, 5, 26};

  int *ptint1;

  int *tab3=(int *)calloc(6,sizeof(int));

  for (int p=0 ; p<=6 ; ++p) tab3[p]=p*3;

 

  return ;

}

 

Validez les instructions ou affirmations correctes et celles incorrectes avec justifications a l'appuie :

ptint=tab1;

ptint=&tab1;

ptint=&tab1[0];

ptint1=tab3;

ptint1=&tab3;

tab1, tab2 et tab3 sont des tableaux de 6 entiers.

++tab1;

++tab3;

 

EXERCICE 2 : 7pts

  1. Nom le plus long : Ecrire un programme qui lit une serie de noms terminée par le marqueur "fin" et affiche le nom le plus long.
  2. Produit scalaire : Ecrire un programme qui lit les coefficients de deux vecteurs de taille N=5 et retourne la valeur de leur produit scalaire.
  3. Matrice identité : Déclarer une matrice carrée d'ordre N=10 et l'initialiser à la matrice identité.
  4. Egalité matricielle : Ecrire un programme qui lit les coefficients de deux matrices carrées d'ordre N=3 et dit si elles sont égales. Deux matrices sont égales si elles ont exactement les mêmes coefficients
  5. Produit matrice-vecteur : Ecrire un programme qui lit les coefficients d'une matrice carrée A d'ordre N=10 et d'un vecteur X de taille N et affiche le résultat du produit matrice-vecteur AX.
  6. Produit matrice-matrice : Ecrire un programme qui lit les coefficients de deux  matrices carrées A  et B d'ordre N=10 et affiche le résultat du produit matriciel AB.
  7. Nombre de coefficients : égaux Ecrire un programme qui lit les coefficients de deux  matrices carrées A  et B d'ordre N=10 et affiche le nombre de coefficients égaux.

 

SOLUTION : CORRECTION

EXERCICE 01 :

A) --------------

1) La déclaration int tab[4][5] crée un tableau à deux dimensions de 4 lignes et 5 colonnes, contenant des entiers. Chaque élément du tableau est identifié par deux indices, le premier pour la ligne et le second pour la colonne. Voici une représentation schématique du tableau :

 

2) Le contenu de tab est un ensemble de valeurs entières, stockées dans la mémoire de l'ordinateur. En C, un tableau à deux dimensions est en fait un tableau de tableaux, c'est-à-dire que chaque élément de tab est lui-même un tableau d'entiers. Le nom tab représente l'adresse du premier élément du tableau, c'est-à-dire le tableau tab[0].

3) tab[i][j] désigne la valeur de l'élément situé à la ligne i et à la colonne j du tableau tab, avec 0<=i<4 et 0<=j<5. Par exemple, tab[2][3] désigne la valeur de l'élément en troisième ligne et quatrième colonne.

4) tab[i] désigne le tableau d'entiers situé à la ligne i du tableau tab, avec 0<=i<4. Par exemple, tab[1] désigne le tableau [tab[1][0], tab[1][1], tab[1][2], tab[1][3], tab[1][4]]. Le nom tab[i] représente l'adresse du premier élément du tableau, c'est-à-dire tab[i][0].

5) (tab[i]+j) désigne l'adresse de l'élément situé à la ligne i et à la colonne j du tableau tab, avec 0<=i<4 et 0<=j<5. Par exemple, (tab[2]+3) désigne l'adresse de l'élément tab[2][3]. Cette expression est équivalente à &tab[i][j].

6) *(tab[i]+j) désigne la valeur de l'élément situé à la ligne i et à la colonne j du tableau tab, avec 0<=i<4 et 0<=j<5. Par exemple, *(tab[2]+3) désigne la valeur de l'élément tab[2][3]. Cette expression est équivalente à tab[i][j].

7) Oui, on peut modifier la valeur de tab[i][j] en utilisant une instruction d'affectation, comme par exemple tab[i][j] = 42;. Cela va remplacer la valeur précédente de l'élément par la nouvelle valeur.

8) &(tab[i][j]) désigne l'adresse de l'élément situé à la ligne i et à la colonne j du tableau tab, avec 0<=i<4 et 0<=j<5. Par exemple, &(tab[2][3]) désigne l'adresse de l'élément tab[2][3]. Cette expression est équivalente à (tab[i]+j).

B) ---------------

1) Deux syntaxes possibles pour désigner l'adresse de début de la ligne i sont :
    - tab[i] : le nom du tableau correspondant à la ligne i
    - &tab[i][0] : l'adresse du premier élément de la ligne i
2) Deux syntaxes possibles pour désigner l'adresse de la case située à l'intersection de la ligne i et de la colonne j de tab sont :
    - (tab[i]+j) : l'addition de l'adresse de début de la ligne i et de l'indice j
    - &tab[i][j] : l'opérateur d'adressage appliqué à l'élément tab[i][j]
3) Deux syntaxes possibles pour désigner le contenu de la case située à l'intersection de la ligne i et de la colonne j de tab sont :
    - tab[i][j] : l'accès direct à l'élément du tableau par ses deux indices
    - *(tab[i]+j) : la déréférenciation de l'adresse de la case.

C)-------------

1) Valide , ptint=tab1;

Nous savons que le nom d'un tableau donne accès à l'adresse de la zone occupée par le tableau. Cette instruction est donc correcte.

2) inValide, ptint=&tab1;

tab1 est un tableau de taille fixe, réservé au moment de la compilation. L'utilisation du nom donne accès à l'adresse de la zone réservée. Demander l'adresse de cette adresse par l'emploi de l'opérateur n'a pas de sens, car cette valeur est une constante adresse.

L'utilisation de l'opérateur & n'a pas de signification. Dans ce cas, le compilateur gcc signale cette utilisation inadéquate et l'ignore. C'est pourquoi une telle instruction ne provoque pas l'arrêt de la compilation.

3)valide, ptint=&tab1[0];

Cette instruction permet d'affecter à ptint l'adresse du 1er élément du tableau.

Elle est équivalent à ptint=&tab1.

 

4) valide, ptint1=tab3;

Affectation simple entre 2 pointeurs de même type.

5) invalide, ptint1=&tab3;

tab3 est un pointeur sur un entier. &tab3 est donc l'adresse d'un tableau d'entiers. Le type de cette donnée est int **. Les types des opérandes de l'affectation sont différents et aucune conversion implicite n'est possible. C'est une erreur !

6) tab1, tab2 et tab3 sont des tableaux de 6 entiers.

Valide, tab1 et tab2 sont des tableaux et, à ce titre, leurs adresses sont des constantes. tab3 est un pointeur sur un entier qui peut être modifié. Il existe une conversion implicite entre pointeur et tableau permettant d'utiliser l'opérateur [ ] sur un pointeur.

7)++tab1;

non valide, tab1 est un tableau. Le nom peut être utilisé pour l'application de l'opérateur [ ] ou dans une expression adresse. Une expression ne peut être incrémentée.

8) valide, ++tab3;

tab3 est une variable pointeur qui peut être incrémentée.

 

EXERCICE 2 :

Nom le plus long
#include <stdio.h>
#include <string.h>

int main() {
    char nom[100]; // un tableau pour stocker le nom saisi
    char plus_long[100] = ""; // un tableau pour stocker le nom le plus long
    int longueur; // une variable pour stocker la longueur du nom saisi
    int max = 0; // une variable pour stocker la longueur maximale

    printf("Entrez une serie de noms terminee par le marqueur \"fin\":\n");
    do {
        scanf("%s", nom); // lire le nom saisi
        longueur = strlen(nom); // calculer la longueur du nom
        if (longueur > max && strcmp(nom, "fin") != 0) { // si le nom est plus long que le maximum et n'est pas le marqueur
            max = longueur; // mettre à jour le maximum
            strcpy(plus_long, nom); // copier le nom dans le tableau plus_long
        }
    } while (strcmp(nom, "fin") != 0); // répéter tant que le nom n'est pas le marqueur

    printf("Le nom le plus long est : %s\n", plus_long); // afficher le nom le plus long
    return 0;
}

2------

- Le principe du produit scalaire est de multiplier les coefficients correspondants de deux vecteurs de même taille et de faire la somme des produits obtenus. Le résultat est un nombre réel. Par exemple, si $$\vec{u} = (u_1, u_2, u_3)$$ et $$\vec{v} = (v_1, v_2, v_3)$$, alors le produit scalaire de $$\vec{u}$$ et $$\vec{v}$$ est $$\vec{u} \cdot \vec{v} = u_1v_1 + u_2v_2 + u_3v_3$$.
- Un programme qui lit les coefficients de deux vecteurs de taille N=5 et retourne la valeur de leur produit scalaire est :


#include <stdio.h>

#define N 5 // la taille des vecteurs

int main() {
    double u[N]; // le premier vecteur
    double v[N]; // le deuxième vecteur
    double ps = 0; // le produit scalaire
    int i; // une variable pour parcourir les vecteurs

    printf("Entrez les coefficients du premier vecteur:\n");
    for (i = 0; i < N; i++) { // pour chaque coefficient du premier vecteur
        scanf("%lf", &u[i]); // lire la valeur saisie
    }
    printf("Entrez les coefficients du deuxième vecteur:\n");
    for (i = 0; i < N; i++) { // pour chaque coefficient du deuxième vecteur
        scanf("%lf", &v[i]); // lire la valeur saisie
    }
    for (i = 0; i < N; i++) { // pour chaque coefficient des deux vecteurs
        ps += u[i] * v[i]; // ajouter le produit des coefficients au produit scalaire
    }
    printf("Le produit scalaire des deux vecteurs est : %lf\n", ps); // afficher le produit scalaire
    return 0;
}

3----------

- La matrice identité est une matrice carrée dont tous les éléments sont nuls sauf ceux de la diagonale principale qui sont égaux à 1. Par exemple, la matrice identité d'ordre 3 est :

$$
\begin{pmatrix}
1 & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & 1
\end{pmatrix}
$$

- Un programme qui déclare une matrice carrée d'ordre N=10 et l'initialise à la matrice identité est :
#include <stdio.h>

#define N 10 // l'ordre de la matrice

int main() {
    int mat[N][N]; // la matrice carrée
    int i, j; // des variables pour parcourir la matrice

    for (i = 0; i < N; i++) { // pour chaque ligne de la matrice
        for (j = 0; j < N; j++) { // pour chaque colonne de la matrice
            if (i == j) { // si on est sur la diagonale principale
                mat[i][j] = 1; // mettre la valeur 1
            } else { // sinon
                mat[i][j] = 0; // mettre la valeur 0
            }
        }
    }
    printf("La matrice identite d'ordre %d est :\n", N);
    for (i = 0; i < N; i++) { // pour chaque ligne de la matrice
        for (j = 0; j < N; j++) { // pour chaque colonne de la matrice
            printf("%d ", mat[i][j]); // afficher l'élément de la matrice
        }
        printf("\n"); // passer à la ligne suivante
    }
    return 0;
}

4---------

Egalité matricielle

- Deux matrices sont égales si elles ont la même taille et les mêmes coefficients. Par exemple, les matrices $$A = \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{pmatrix}$$ et $$B = \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{pmatrix}$$ sont égales, mais les matrices $$C = \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 10 \end{pmatrix}$$ et $$D = \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{pmatrix}$$ ne le sont pas.
- Un programme qui lit les coefficients de deux matrices carrées d'ordre N=3 et dit si elles sont égales est :


#include <stdio.h>

#define N 3 // l'ordre des matrices

int main() {
    int A[N][N]; // la première matrice
    int B[N][N]; // la deuxième matrice
    int egal = 1; // une variable pour indiquer si les matrices sont égales
    int i, j; // des variables pour parcourir les matrices

printf("Entrez les coefficients de la premiere matrice:\n");
    for (i = 0; i < N; i++) { // pour chaque ligne de la première matrice
        for (j = 0; j < N; j++) { // pour chaque colonne de la première matrice
            scanf("%d", &A[i][j]); // lire la valeur saisie
        }
    }
    printf("Entrez les coefficients de la deuxieme matrice:\n");
    for (i = 0; i < N; i++) { // pour chaque ligne de la deuxième matrice
        for (j = 0; j < N; j++) { // pour chaque colonne de la deuxième matrice
            scanf("%d", &B[i][j]); // lire la valeur saisie
        }
    }
    for (i = 0; i < N; i++) { // pour chaque ligne des matrices
        for (j = 0; j < N; j++) { // pour chaque colonne des matrices
            if (A[i][j] != B[i][j]) { // si les coefficients sont différents
                egal = 0; // mettre la variable à 0
                break; // sortir de la boucle
            }
        }
        if (egal == 0) { // si la variable est 0
            break; // sortir de la boucle
        }
    }
    if (egal == 1) { // si la variable est 1
        printf("Les matrices sont egales.\n"); // afficher que les matrices sont égales
    } else { // sinon
        printf("Les matrices ne sont pas egales.\n"); // afficher que les matrices ne sont pas égales
    }
    return 0;
}

5---------

#include <stdio.h>

#define N 10

int main() {
    int A[N][N], X[N], result[N];

    // Entrée : Saisie des coefficients de la matrice A et du vecteur X

    // Affichage de la matrice A
    printf("Matrice A:\n");
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            // Saisie des coefficients pour A[i][j]
            scanf("%d", &A[i][j]);
            printf("%d ", A[i][j]);
        }
        printf("\n");
    }

    // Affichage du vecteur X
    printf("\nVecteur X:\n");
    for (int i = 0; i < N; i++) {
        // Saisie des coefficients pour X[i]
        scanf("%d", &X[i]);
        printf("%d\n", X[i]);
    }

    // Calcul du produit matrice-vecteur
    printf("\nRésultat du produit matrice-vecteur AX:\n");
    for (int i = 0; i < N; i++) {
        result[i] = 0;
        for (int j = 0; j < N; j++) {
            result[i] += A[i][j] * X[j];
        }
        printf("%d\n", result[i]);
    }

    return 0;
}

6----------

#include <stdio.h>

#define N 10

int main() {
    int A[N][N], B[N][N], result[N][N];

    // Entrée : Saisie des coefficients des matrices A et B

    // Affichage de la matrice A
    printf("Matrice A:\n");
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            // Saisie des coefficients pour A[i][j]
            scanf("%d", &A[i][j]);
            printf("%d ", A[i][j]);
        }
        printf("\n");
    }

    // Affichage de la matrice B
    printf("\nMatrice B:\n");
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            // Saisie des coefficients pour B[i][j]
            scanf("%d", &B[i][j]);
            printf("%d ", B[i][j]);
        }
        printf("\n");
    }

    // Calcul du produit matrice-matrice
    printf("\nRésultat du produit matrice-matrice AB:\n");
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            result[i][j] = 0;
            for (int k = 0; k < N; k++) {
                result[i][j] += A[i][k] * B[k][j];
            }

}

   for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            printf("%d ", result[i][j]);
        }
        printf("\n");
    }

    return 0;
}

7---------

#include <stdio.h>

#define N 10

int main() {
    int A[N][N], B[N][N];
    int countEqual = 0;

    // Entrée : Saisie des coefficients des matrices A et B

    // Comparaison des coefficients
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            // Saisie des coefficients pour A[i][j] et B[i][j]
            scanf("%d", &A[i][j]);
            scanf("%d", &B[i][j]);

            if (A[i][j] == B[i][j]) {
                countEqual++;
            }
        }
    }

    // Affichage du nombre de coefficients égaux
    printf("Nombre de coefficients égaux : %d\n", countEqual);

    return 0;
}

 

 
Aucune note. Soyez le premier à attribuer une note !

Ajouter un commentaire

Anti-spam