Boris ENG

PhD Student in Computer Science, Team LoVe, LIPN (Université Sorbonne Paris Nord, France) [last name][first name]@hotmail.fr
« Return to Teaching

Informatique 2

Responsable du cours : Kaïs Klai

Chargé de TP (OMI3) : Moi (eng@lipn.fr)

TP1

Arithmétique des pointeurs

Supposons qu’on ait int T[9] = {12, 23, 34, 45, 56, 67, 78, 89, 90} avec un pointeur int* p = T se référant à la première case du tableau T. L’adresse du début de T est 5000 et celle de p est 2804.

1. *p+2 = 12+2 = 14
2. *(p+2) = *(5000+2*4) = *5008 = 34 (remarque : c'est pareil que p[2] = T[2])
3. &p+1 = 2804+1 = 2805
4. &T[4]-3 = 5000+4*4-3 = 5013
5. T+3 = 5000+3 = 5003
6. &T[7]-p = 5000+4*7-2804 = 5028-2804
7. p+(*p-10) = 2804+(12-10) = 2804+2 = 2806
8. *(p+*(p+8)-T[7]) = *(p+*(p+8)-89) = *(p+90-89) = *(p+1) = 23
9. (*(&p))[5]-(*(&p))[2] = p[5]-p[2] = 67-34 = 33 (remarque : *(&p) = p)
10. *(*(&p)+3)*(*(*(&p)+1)-13) = *(p+3)*(*(p+1)-13) = *(p+3)*(*(p+1)-13) = p[3]*(p[1]-13) = 45*(23-12) = 45*11

Compilation

gcc -c tab.h tab.c
gcc -c testTab.c
gcc tab.o testTab.o -o testTab
./testTab

tab.h

Contient les prototypes des fonctions c’est-à-dire qu’on déclare quelles sont les fonctions qu’on va utiliser, leur type de retour et le type des paramètres.

1
2
3
4
5
6
7
8
double* creerTab(int);
void remplirTab(double*, int);
void afficherTab(double*, int);
int idTab(double*, double*, int, int);
int estDansTab(double, double*, int);
int nbOccTab(double, double*, int);
int memValTab(double*, double*, int, int);
void inverserTab(double*, int);

tab.c

Contient la définition de chaque fonctions que l’on aimerait utiliser dans notre programme.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <stdlib.h>
#include <stdio.h>
#include "tab.h"

double* creerTab(int size)
{
  // Demande 'size' cases memoires pour contenir des nombres de type 'double'

  // Retourne l'adresse de la premiere case memoire de l'espace obtenu

  return (double*)malloc(size*sizeof(double));
}

void remplirTab(double* tab, int size)
{
  for (int i=0; i<size; i++)
  {
    printf("Veuillez entrer la valeur de tab[%d] :", i);
    scanf("%lg", tab+i); // Remplit la case à l'adresse tab+i (%d = type double)

  }
}

void afficherTab(double* tab, int size)
{
  for (int i=0; i<size; i++)
  {
    printf("%lg ", *(tab+i)); // On peut aussi écrire tab[i]

  }
  printf("\n");
}

// Renvoie -1 si les deux tableaux sont differents

// Renvoi 0 si les deux tableaux sont identiques

int idTab(double* tab1, double* tab2, int s1, int s2)
{
  if (s1 != s2) // S'ils n'ont pas la meme taille, ils sont differents

    return -1;
  for (int i=0; i<s1; i++)
  {
    if (tab1[i] != tab2[i])
      return -1; // Il y a au moins une difference donc ils sont differents

  }
  return 0; // Tous les tests de differences sont passes, donc ils sont identiques

}

// Renvoie -1 si l'element x n'est pas dans tab

// Sinon, renvoie la position de l'element

int estDansTab(double x, double* tab, int size)
{
  for (int i=0; i<size; i++)
  {
    if (x == tab[i])
      return i; // On l'a trouve donc on renvoit la valeur du compteur

  }
  return -1; // On ne l'a pas trouve

}

int nbOccTab(double x, double* tab, int size)
{
  int nbOcc = 0;
  for (int i=0; i<size; i++)
  {
    if (x == tab[i])
      nbOcc++;
  }
  return nbOcc;
}

// Renvoie -1 si un tableau a un element pas present dans l'autre

// Renvoie 0 si les deux tableaux ont les memes elements

int memValTab(double* tab1, double* tab2, int s1, int s2)
{
  for (int i=0; i<s1; i++)
  {
    if (!estDansTab(tab1[i], tab2, s2))
      return -1; // On a un element de tab1 qui n'est pas dans tab2

  }
  for (int i=0; i<s2; i++)
  {
    if (!estDansTab(tab2[i], tab1, s1))
      return -1; // On a un element de tab2 qui n'est pas dans tab1

  }
  return 0;
}

// On inverse chaque case avec son oppose dans le tableau

// (pour cela il faut une variable temporaire 'x' pour sauvegarder la valeur qu'on met a jour)

void inverserTab(double* tab, int size)
{
  double x;
  for (int i=0; i<size/2; i++)
  {
    x = tab[i];
    tab[i] = tab[size-1-i];
    tab[size-1-i] = x;
  }
}

testTab.c

Contient le coeur du programme où on utilise les fonctions que l’on a défini.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <stdlib.h>
#include <stdio.h>
#include "tab.h"

// Fonction affichant le menu et recuperant le choix de l'utilisateur

int menu()
{
    int choix;

    printf("Tapez 0 pour quitter le programme\n");
    printf("Tapez 1 pour creer le tableau\n");
    printf("Tapez 2 pour remplir le tableau\n");
    printf("Tapez 3 pour afficher le tableau \n");
    printf("Tapez 4 pour comparer le tableau a un autre\n");
    printf("Tapez 5 pour vérifier si un element est dans le tableau\n");
    printf("Tapez 6 pour compter un element dans le tableau\n");
    printf("Tapez 7 pour verifier si le tableau a les memes elements qu'un autre\n");
    printf("Tapez 8 pour inverser le tableau\n");

    scanf("%d", &choix);
    return choix;
}

// Programme principal qui traite des tableaux

int main()
{
    double* monTab = NULL;
    int size, choix, lsize = 0, c;

    /* declarer les autres variables dont vous aurez besoin */
    do
    {
        choix = menu();
        switch(choix)
        {
            case 0:
                printf("Au revoir\n");
                break;
            case 1:
                if (monTab != NULL)
                {
                    printf("Le tableau est deja cree ! ");
                    printf("voulez vous le supprimer et créer un autre (1: oui/ 0: non)?\n");
                    scanf("%d", &c);
                    if(c == 0)
                        break;
                    else
                    {
                        free(monTab);
                        lsize = 0;
                    }
                }
                printf("Quelle taille voulez vous pour votre tableau?\n");
                scanf("%d", &size);
                monTab = creerTab(size);
                break;
            case 2:
                if (monTab == NULL)
                    printf("Il faut d’abord creer le tableau\n");
                else
                {
                    printf("Combien de valeurs?\n");
                    scanf("%d", &lsize);
                    remplirTab(monTab, lsize);
                }
                break;
            case 3:
                afficherTab(monTab, lsize);
                break;
            case 4:
                // A Remplir...

                break;
            case 5:
                // A Remplir...

                break;
            case 6:
                // A Remplir...

                break;
            case 7:
                // A Remplir...

                break;
            case 8:
                inverserTab(monTab, lsize);
                break;
            default:
                printf("Choix erronne\n");
        }
    } while (choix != 0);

    /* n'oubliez pas de liberer les tableaux alloués dynamiquement */
    if (monTab != NULL)
        free(monTab);

    return 0;
}