IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Cast en (int(*)[])


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut Cast en (int(*)[])
    Bonjour,

    J'ai fait une fonction récursive, pour travailler sur un tableau. Un warning de type m'a fait mettre un cast avec (int(*)[]). Voici un code minimaliste :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include <stdio.h>
     
    void recursive(int (*ptab)[], unsigned int length)
    {
        if(length>=3)
            recursive(  (int(*)[]) ((*ptab)+1), length-1 );
    }
     
    // Main
    int main(void)
    {
        int tableau[]={0,1,2,3}; // tableau de int
        int (*pTabInt)[] = &tableau; // pointeur sur  "tableau de int"
        recursive( pTabInt, 4);
        return 0;
    }
    Si j'enlève le cast avec (int(*)[]), j'obtient le warning suivant:
    Ligne 6 = warning: passing argument 1 of 'recursive' from incompatible pointer type|
    Ligne 3 = note: expected 'int (*)[]' but argument is of type 'int *'|
    int (*)[] n'est pas plutôt équivalent à un **int qu'à *int ? Si oui, j'ai du mal à comprendre comment ma fonction peut marcher.

    Si quelqu'un a une explication, je suis preneur

  2. #2
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    int (*)[] n'est pas plutôt équivalent à un **int qu'à *int ?
    Je suppose que tu veux dire int ** ou int *. De toute façon la réponse est non.

    int (*)[] est un type "adresse d'un tableau de...int
    int ** est un type "adresse d'un pointeur sur int"
    int * est un type "adresse de int"

    Dans la fonction, *ptab est donc un tableau de int. Alors, dans le contexte (ligne 6) de l'expression (*ptab)+1, *ptab est l'adresse du premier élément de ce tableau et donc de type int *. Alors que la fonction attend, lors de l'appel récursif, comme type un int (*)[]

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    C'est légal, ça, int(*)[] sans taille de tableau?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    pTabInt ou ptab sont des pointeurs sur un type incomplet (tableau de taille indéfini), ce qui est légal.
    Dans le code présenté, il n'y a pas nécessité de connaitre la taille du tableau et le code passe.
    Par contre, cela interdit d'écrire quelque chose comme pTabInt++ ou ptab++;

  5. #5
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Hop hop ! Remontée de topic !

    J'avais pas franchement compris à l'époque, j'y ai repensé souvent depuis, et hier je me suis enfin décidé à m'y replonger. Je crois que je ne comprends pas plus... Déjà, je me suis aperçu que pour ré-agencer les éléments d'un tableau, je n'avais pas besoin de l'adresse du tableau, mais juste du tableau. Un paramètre de type int[] ou int* suffit. Mais j'aimerai quand même comprendre cette histoire.

    pTabInt ou ptab sont des pointeurs sur un type incomplet (tableau de taille indéfini), ce qui est légal. [...] Par contre, cela interdit d'écrire quelque chose comme pTabInt++ ou ptab++;
    OK pour ça. On ne connait pas la taille de l’élément pointé, on ne peut donc pas décaler le pointeur de la taille de cet élément.

    Dans la fonction, *ptab est donc un tableau de int. Alors, dans le contexte (ligne 6) de l'expression (*ptab)+1, *ptab est l'adresse du premier élément de ce tableau et donc de type int *. Alors que la fonction attend, lors de l'appel récursif, comme type un int (*)[]
    OK pour ça. La fonction attend l'adresse d'un tableau, je lui passe simplement un tableau. Le cast permet juste de faire taire le warning, mais ne règle pas le problème du type.

    Je suppose que tu veux dire int ** ou int *. De toute façon la réponse est non.

    int (*)[] est un type "adresse d'un tableau de...int
    int ** est un type "adresse d'un pointeur sur int"
    int * est un type "adresse de int"
    En revanche, je bloque là dessus. Un tableau de int est de type int[] ; on peut "faire un tableau" avec un int*. Donc un pointeur sur tableau ressemble à un int** (d'où ma question de départ).

    J'ai du mal à concevoir qu'une fonction attendant l'adresse d'un tableau et qui reçoit un tableau puisse fonctionner. Voici le programme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #include <stdio.h>
     
    // Fonctions
    unsigned int position_of_min(char tableau[], unsigned int length, unsigned int position)
    {
        unsigned int tpos=position;
     
        for( ; position<length; position++)
        {
            if(tableau[position] < tableau[tpos])
            {
                tpos=position;
            }
        }
        return tpos;
    }
     
    void recursive_sort(char (*tableau)[], unsigned int length)
    {
         // Recuperation du min
        unsigned int mpos = position_of_min( (*tableau), length, 0 );
        char min = (*tableau)[mpos];
     
        // Echange
        (*tableau)[mpos] = (*tableau)[0];
        (*tableau)[0] = min;
     
        // Trier le reste du tableau
        if(length>=3)
            recursive_sort( (*tableau+1), length-1 );
    }
     
    void display_tableau(char tableau[], unsigned int length)
    {
        unsigned int i=0;
        for(printf("|"), i=0; i<length; printf(" %4d |", tableau[i++]))
            ;
        printf("\n\n");
    }
     
    // Main
    int main(void)
    {
        char tab[]={100,90,15,78,9,-66,5,10,94};
        unsigned int len = sizeof(tab)/sizeof(tab[0]);
     
        display_tableau(tab, len);
        recursive_sort(tab, len);
        //recursive_sort(&tab, len);
        display_tableau(tab, len);
     
        return 0;
    }
    Dans le main, que j'appelle avec tab ou avecv &tab, le résultat en console est le même et Dr Memory ne m'indique pas d'erreur. Pourtant, tab et &tab ne devraient pas être la même chose.

    Encore merci

  6. #6
    screetch
    Invité(e)
    Par défaut
    int* est equivalent avec int[]
    mains int* et int[] ne sont pas equivalent avec int[6] par exemple.

    int[] est un pointeur sur int, tout comme int*
    int[6] est un tableau d'entiers

    par equivalent, je veux dire qu'il est possible de caster de l'un a l'autre.

    Il est possible de caster de int[6] a int* mais pas de int* a int[6]


    pour ton probleme, tu prends l'adresse d'un pointeur donc un int** (equivalent a un (int*)[])
    puis tu fais ((*ptab)+1)
    ptab est int**
    (*ptab) est int*
    ((*ptab)+1) est int*


    ca ne fonctionne donc pas; si ca marche, c'est un coup de bol.
    j'ai essaye de compiler ton code et j'ai obtenu:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    main.cc:18:59: error: parameter 'tableau' includes pointer to array of unknown bound 'char []'
    main.cc: In function 'void recursive_sort(char (*)[], unsigned int)':
    main.cc:30:48: error: cannot convert 'char*' to 'char (*)[]' for argument '1' to 'void recursive_sort(char (*)[], unsigned int)'
    main.cc: In function 'int main()':
    main.cc:48:28: error: cannot convert 'char*' to 'char (*)[]' for argument '1' to 'void recursive_sort(char (*)[], unsigned int)'
    donc je ne comprends pas ou est le probleme; ca ne marche pas, ca n'est pas cense marcher et le compilateur refuse de le faire marcher. Il y a quelque chose que je n'ai pas suivi?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Cannot cast from int to Integer
    Par flotho dans le forum Jasper
    Réponses: 2
    Dernier message: 11/11/2009, 20h39
  2. Cast unsigned int en chaine de caractere
    Par MeWaa dans le forum C
    Réponses: 5
    Dernier message: 06/05/2009, 09h58
  3. cast Integer / int
    Par zaineb.z dans le forum Langage
    Réponses: 8
    Dernier message: 18/07/2007, 15h28
  4. [débutant] cast string->int
    Par gigigao dans le forum Visual C++
    Réponses: 8
    Dernier message: 23/08/2006, 11h47
  5. [Language]Cast de int en Object ?
    Par BouB dans le forum Langage
    Réponses: 5
    Dernier message: 22/12/2005, 17h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo