Club Informatique VINCI

Le C.I.V représente un groupement d'étudiants constituant le club informatique de la Grande École Marocaine de l'Informatique et des Réseaux du Télécom VINCI -Rabat-. (L'utilisation de Internet explorer 6/7 n'est pas recommandée, on vous propose Firefox)

Les forums du C.I.V attend vos propositions en ce qui concerne le graphique, les catégories, et les sections.

Connexion

Récupérer mon mot de passe

Sondage

Quel est votre antivirus préféré ?
16% 16% [ 4 ]
32% 32% [ 8 ]
0% 0% [ 0 ]
0% 0% [ 0 ]
0% 0% [ 0 ]
36% 36% [ 9 ]
0% 0% [ 0 ]
0% 0% [ 0 ]
8% 8% [ 2 ]
8% 8% [ 2 ]

Total des votes : 25

Qui est en ligne ?

Il y a en tout 1 utilisateur en ligne :: 0 Enregistré, 0 Invisible et 1 Invité

Aucun


[ Voir toute la liste ]


Le record du nombre d'utilisateurs en ligne est de 23 le Mer 17 Oct - 12:31

Statistiques

Nos membres ont posté un total de 1292 messages dans 373 sujets

Nous avons 437 membres enregistrés

L'utilisateur enregistré le plus récent est intellection


    Les pointeurs (A.Elghazi/S.Elhajji)

    Partagez
    avatar
    El Maligno Angelo
    Administrateur
    Administrateur

    Messages : 373
    Points : 4009
    Réputation : 8
    Date d'inscription : 25/04/2009
    Age : 28
    Localisation : ErRabat

    Les pointeurs (A.Elghazi/S.Elhajji)

    Message par El Maligno Angelo le Mer 30 Sep - 6:58

    Introduction
    Nous avons déjà été amené à utiliser l'opérateur & pour désigner l'adresse d'une lvalue. D'une manière
    générale, le langage C permet de manipuler des adresses par l'intermédiaire de variables nommées
    "pointeurs".
    En guise d'introduction à cette nouvelle notion, considérons les instructions :
    Code:
    int * ad ;
    int n ;
    n = 20 ;
    ad = &n ;
    *ad = 30 ;
    La première réserve une variable nommée ad comme étant un "pointeur" sur des entiers. Nous verrons
    que * est un opérateur qui désigne le contenu de l'adresse qui le suit. Ainsi, à titre "mnémonique", on peut
    dire que cette déclaration signifie que *ad, c'est-à dire l'objet d'adresse ad, est de type int ; ce qui signifie
    bien que ad est l'adresse d'un entier.
    L'instruction : ad = &n ; affecte à la variable ad la valeur de l'expression &n. L'opérateur & (que nous
    avons déjà utilisé avec scanf) est un opérateur unaire qui fournit comme résultat l'adresse de son opérande.
    Ainsi, cette instruction place dans la variable ad l'adresse de la variable n.
    Après son exécution.
    L'instruction suivante : *ad = 30 ; signifie : affecter à la lvalue *ad la valeur 30. Or *ad représente l'entier
    ayant pour adresse ad. Après exécution de cette instruction, la valeur de n devient 30. Bien entendu, ici,
    nous aurions obtenu le même résultat avec :n = 30 ;
    Quelques Exemple
    Voici quelques exemples d'utilisation de ces deux opérateurs. Supposez que nous ayons effectué ces
    déclarations :
    Code:
    int * ad1, * ad2, * ad ;
    int n = 10, p = 20 ;
    Les variables ad1, ad2 et ad sont donc des pointeurs sur des entiers. Considérons maintenant ces
    instructions :
    Code:
    ad1 = &n ;
    ad2 = &p ;
    * ad1 = * ad2 + 2 ;
    Les deux premières placent dans ad1 et ad2 les adresses de n et p. La troisième affecte à *ad1 la valeur de
    l'expression : * ad2 + 2.
    Autrement dit, elle place à l'adresse désignée par ad1 la valeur (entière) d'adresse ad2, augmentée de 2.
    Cette instruction joue donc ici le même rôle que : n = p + 2 ;
    De manière comparable, l'expression : * ad1 += 3
    jouerait le même rôle que : n = n + 3
    et l'expression : ( * ad1 ) ++
    jouerait le même rôle que n++
    Remarque :
    1) Si ad est un pointeur, les expressions ad et *ad sont des lvalue ; autrement dit ad et *ad sont
    modifiables. En revanche, il n'en va pas de même de &ad. En effet, cette expression désigne, non plus une
    variable pointeur comme ad, mais l'adresse de la variable ad telle qu'elle a été définie par le compilateur.
    Cette adresse est nécessairement fixe et il ne saurait être question de la modifier (la même remarque
    Langage C
    21
    s'appliquerait à &n, où n serait une variable scalaire quelconque). D'une manière générale, des
    expressions telles que : (&ad)++ ou (&p)++ seront rejetées à la compilation.
    2) Une déclaration telle que : int * ad réserve un emplacement pour un pointeur sur un entier. Elle ne
    réserve pas en plus un emplacement pour un tel entier.
    TABLEAUX ET POINTEUR
    En langage C, l'identificateur d'un tableau, lorsqu'il est employé seul (sans indices à sa suite), est
    considéré comme un pointeur (constant) sur le début du tableau.
    Tableau à un indice
    Supposons, par exemple, que l'on effectue la déclaration suivante :
    int t[10]
    La notation t est alors totalement équivalente à &t[0]. L'identificateur t est considéré comme étant de type
    pointeur sur le type correspondant aux éléments du tableau, c'est-à-dire, ici, int*.
    Ainsi, voici quelques exemples de notations équivalentes :
    t+1 ---------------- &t[1]
    t+i ---------------- &t[i]
    t[i]----------------- * (t+i)
    Pour illustrer ces nouvelles possibilités de notation, voici plusieurs façons de placer la valeur 1 dans
    chacun des 10 éléments de notre tableau t :
    Code:
    int i ;
    for (i=0 ; i<10 ; i++)
    * (t+i) = 1 ;
    ou:
    int i ;
    int * p :
    for (p=t, i=0 ; i<10 ; i++, p++)
    * p = 1 ;
    Dans la seconde façon, nous avons dû recopier la "valeur" représentée par t dans un pointeur nommé p.
    En effet, il ne faut pas perdre de vue que le symbole t représente une adresse constante (t est une
    constante de type pointeur sur des entiers). Autrement dit, une expression telle que t++ aurait été invalide,
    au même titre que, par exemple, 3++. Un nom de tableau est un pointeur constant ; ce n'est pas une lvalue.
    Remarque importante :
    Nous venons de voir que la notation t[i] est équivalente à *(t+i) lorsque t est déclaré comme un tableau.
    En fait, cela reste vrai, quelle que soit la manière dont t a été déclaré. Ainsi, avec :
    int * t ; les deux notations précédentes resteraient équivalentes. Autrement dit, on peut utiliser t[i] dans un
    programme où t est simplement déclaré comme un pointeur.
    Tableau à plusieurs indices
    Lorsque le compilateur rencontre une déclaration telle que :
    int t[3] [4] ;
    il considère en fait que t désigne un tableau de 3 éléments, chacun de ces éléments étant lui-même un
    tableau de 4 entiers.
    Autrement dit, si t représente bien l'adresse de début de notre tableau t, il n'est plus de type int * (comme
    c'était le cas pour un tableau à un indice) mais d'un type "pointeur sur des blocs de 4 entiers", type qui
    devrait se noter théoriquement :
    int [4] *
    Dans ces conditions, une expression telle que t+1 correspond à l'adresse de t, augmentée de 4 entiers (et
    non plus d'un seul !).
    Exemple
    Le tableau M à deux dimensions est défini comme suit:
    Code:
    int M[4][10] = {{ 0, 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}};
    Le nom du tableau M représente l'adresse du premier élément du tableau et pointe sur le tableau M[0] qui
    a la valeur: {0,1,2,3,4,5,6,7,8,9}. L'expres​sion(M+1) est l'adresse du deuxième élément du tableau et
    pointe sur M[1] qui a la valeur: {10,11,12,13,14,15,16,17,18,19}.
    Explication
    Au sens strict du terme, un tableau à deux dimensions est un tableau unidimensionnel dont chaque
    composante est un tableau unidimensionnel. Ainsi, le premier élément de la matrice M est le vecteur
    {0,1,2,3,4,5,6,7,8,9}, le deuxième élément est {10,11,12,13,14,15,16,17,18,19} et ainsi de suite.
    L'arithmétique des pointeurs qui respecte automatiquement les dimensions des éléments conclut
    logiquement que:
    M+I désigne l'adresse du tableau M[I]
    Problème
    Comment pouvons-nous accéder à l'aide de pointeurs aux éléments de chaque composante du tableau, c.àd.:
    aux éléments M[0][0], M[0][1], ... , M[3][9] ?
    Une solution consiste à convertir la valeur de M (qui est un pointeur sur un tableau du type int) en un
    pointeur sur int. On pourrait se contenter de procéder ainsi:
    Code:
    int M[4][10] = {{ 0, 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}};
    int *P;
    P = M; /* conversion automatique */
    Cette dernière affectation entraîne une conversion automatique de l'adresse &M[0] dans l'adresse
    &M[0][0]. (Remarquez bien que l'adresse transmise reste la même, seule la nature du pointeur a changé).
    Cette solution n'est pas satisfaisante à cent pour-cent: Généralement, on gagne en lisibilité en explicitant
    la conversion mise en oeuvre par l'opérateur de conversion forcée ("cast"), qui évite en plus des messages
    d'avertissement de la part du compilateur.
    Solution
    Voici finalement la version que nous utiliserons:
    Code:
    int M[4][10] = {{ 0, 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}};
    int *P;
    P = (int *)M; /* conversion forcée */
    Dû à la mémorisation ligne par ligne des tableaux à deux dimensions, il nous est maintenant possible
    traiter M à l'aide du pointeur P comme un tableau unidimensionnel de dimension 4*10.
    Exemple
    Les instructions suivantes calculent la somme de tous les éléments du tableau M:
    Code:
    int M[4][10] = {{ 0, 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}};
    int *P;
    int I, SOM;
    P = (int*)M;
    SOM = 0;
    for (I=0; I<40; I++)
    SOM += *(P+I);
    Attention !
    Lors de l'interprétation d'un tableau à deux dimensions comme tableau unidimensionnel il faut
    calculer avec le nombre de colonnes indiqué dans la déclaration du tableau.
    Exemple
    Pour la matrice A, nous réservons de la mémoire pour 3 lignes et 4 colonnes, mais nous utilisons
    seulement 2 lignes et 2 colonnes:
    Code:
    int A[3][4];
    A[0][0]=1;
    A[0][1]=2;
    A[1][0]=10;
    A[1][1]=20;

    L'adresse de l'élément A[I][J] se calcule alors par:
    A + I*4 + J
    Conclusion
    Pour pouvoir travailler à l'aide de pointeurs dans un tableau à deux dimensions, nous avons besoin de
    quatre données:
    a) l'adresse du premier élément du tableau converti dans le type simple des éléments du tableau
    b) la longueur d'une ligne réservée en mémoire
    (- voir déclaration - ici: 4 colonnes)
    c) le nombre d'éléments effectivement utilisés dans une ligne
    (- p.ex: lu au clavier - ici: 2 colonnes)
    d) le nombre de lignes effectivement utilisées
    (- p.ex: lu au clavier - ici: 2 lignes)
    La comparaison de pointeurs
    Il ne faut pas oublier qu'en C un pointeur est défini à la fois par une adresse en mémoire et par un type.
    On ne pourra donc comparer que des pointeurs de même type. Par exemple, voici, en parallèle, deux
    suites d'instructions réalisant la même action :
    mise à 1 des 10 éléments du tableau t :
    Code:
    int t[10] ; int t[10] ;
    int * p ; int i ;
    for (p=t ; p<t+10 ; p++) for (i=0 ; i<10 ; i++)
    *p = 1 ; t[i] = 1 ;


    _________________
    it's awesome to feel...what others can't, but i think doin' what poeple cannot do make u surpass feelings step !!
    avatar
    mezziane.souhail
    Amateur
    Amateur

    Messages : 9
    Points : 2973
    Réputation : 0
    Date d'inscription : 27/10/2009

    Re: Les pointeurs (A.Elghazi/S.Elhajji)

    Message par mezziane.souhail le Mer 6 Jan - 7:19

    mercii
    avatar
    El Maligno Angelo
    Administrateur
    Administrateur

    Messages : 373
    Points : 4009
    Réputation : 8
    Date d'inscription : 25/04/2009
    Age : 28
    Localisation : ErRabat

    Re: Les pointeurs (A.Elghazi/S.Elhajji)

    Message par El Maligno Angelo le Sam 9 Jan - 2:34

    de rien


    _________________
    it's awesome to feel...what others can't, but i think doin' what poeple cannot do make u surpass feelings step !!

    Contenu sponsorisé

    Re: Les pointeurs (A.Elghazi/S.Elhajji)

    Message par Contenu sponsorisé


      La date/heure actuelle est Mer 22 Nov - 5:58