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 :

question sur les pointeurs


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2011
    Messages : 24
    Points : 15
    Points
    15
    Par défaut question sur les pointeurs
    je viens d'ecrire une fonction qui doit retourner un tableau de caractere (en gros retourner un mot)

    mais j'ai un doute sur ce quelle retourne, est ce l'adresse du tableau quel retourne ou juste le tableau?
    voici mon code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    char *tab_car(char c){
    	char *tab = malloc(28*sizeof(char));
    	int n = 0;
    	while(n<28){
    		tab[n]=c;
    		n++;
    	}
    	return tab;
    }

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 629
    Points : 10 554
    Points
    10 554
    Par défaut
    Citation Envoyé par chrislains Voir le message
    est ce l'adresse du tableau quel retourne ou juste le tableau?
    en C un tableau c'est juste l'adresse de la première case

    Donc l'adresse d'un tableau c'est char**

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par foetus Voir le message
    en C un tableau c'est juste l'adresse de la première case

    Donc l'adresse d'un tableau c'est char**
    FAUX dans les deux cas.

    Un tableau est implicitement convertible en un pointeur sur sa première case:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char tableau[10];
    char* pointeur = tableau;
    Mais un tableau n'est pas un pointeur. Et l'adresse d'un tableau de char n'aura pas le type char**, mais le type char [TAILLE]*. Malheureusement, le langage n'accepte pas cette écriture, et il faut l'écrire char (*)[TAILLE] à la place.

    Exemples:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    char tableau[10];
    /*Le langage C est assez permissif pour qu'il n'y ait peut-être pas d'erreur, 
      mais un compilo bien configuré donnera au moins un warning "pointeurs de types incompatibles" ou un truc du genre.
    Et tenter d'utiliser mauvais_pointeur sera un comportement indéfini.*/
    char** mauvais_pointeur = &tableau;
     
    /*Ici, pas d'erreur ni de warning, ni de comportement indéfini/*/
    char (*bon_pointeur)[10] = &tableau;

    Après le case de malloc() est plus compliqué: Après tout, malloc() alloue une zone mémoire sans déterminer son type (et retourne un void*), et avec un alignement suffisant pour n'importe quel type que le compilo supporte; ainsi, les deux formulations suivantes sont identiquement correctes, et on choisit alors généralement la plus simple à utiliser (la seconde):
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void* zoneAllouee = malloc(10*sizeof(int));
    int *ptrEntiers = zoneAllouee;
    int (*ptrTableau)[10] = zoneAllouee;

    En fin de compte, le type des données allouées est le type du pointeur utilisé pour écrire à cet endroit; et on est à l'abri des comportements indéfinis (ou définis par l'implémentation) tant qu'on lit ce qu'on a écrit via des pointeurs du même type (et il y a peut-être des stipulations spéciales pour unsigned char, je ne suis pas sûr).


    Edit: À noter, la conversion implicite d'un tableau en pointeur marche également à travers un pointeur de tableau:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int tab[10];
    int (*pTab)[10] = &tab;
    int *pInt = *pTab; /* La valeur de *pTab est le tableau, et la conversion implicite en int* marche.*/
    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 éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 629
    Points : 10 554
    Points
    10 554
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Mais un tableau n'est pas un pointeur. Et l'adresse d'un tableau de char n'aura pas le type char**, mais le type char [TAILLE]*. Malheureusement, le langage n'accepte pas cette écriture, et il faut l'écrire char (*)[TAILLE] à la place.
    J'ai le souvenir d'une discussion dans laquelle les intervenants disaient que la notation avec la taille du tableau n'est visible par le compilateur que dans le fichier .c qui le contient.

  5. #5
    Membre éprouvé
    Avatar de Aooka
    Homme Profil pro
    Scripting Powershell & Wlangage
    Inscrit en
    Juillet 2015
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Scripting Powershell & Wlangage

    Informations forums :
    Inscription : Juillet 2015
    Messages : 227
    Points : 1 095
    Points
    1 095
    Par défaut
    Ici avec return tab; tu retourne le tableau (donc la chaîne entière) que tu pourra réutiliser par la suite.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par foetus Voir le message
    J'ai le souvenir d'une discussion dans laquelle les intervenants disaient que la notation avec la taille du tableau n'est visible par le compilateur que dans le fichier .c qui le contient.
    Dans une fonction du genre void foo(int tab[10]), c'est le cas, dû à des choix que K&R regrettent quant au passage d'un tableau en paramètre (en fait, il est converti en pointeur et c'est le pointeur qui est passé; un tableau en paramètre de fonction est un faux tableau).

    Par contre, un pointeur de tableau ne peut pas être ignoré aussi facilement; en fait, seule la "première" dimension d'un tableau peut ainsi être effacée. C'est pourquoi pour un tableau à deux dimensions, on peut déclarer une fonction void foo(int tab2d[][10]), qui sera en fait compilée en void foo(int (*tab2d)[10])
    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.

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

Discussions similaires

  1. Question sur les pointeurs génériques
    Par mikedavem dans le forum C
    Réponses: 16
    Dernier message: 24/05/2006, 11h56
  2. question sur les pointeurs
    Par jd.baculard dans le forum Langage
    Réponses: 3
    Dernier message: 18/03/2006, 02h30
  3. [Debutant] Nouvelle question sur les pointeurs
    Par etiennegaloup dans le forum Débuter
    Réponses: 3
    Dernier message: 11/01/2006, 09h55
  4. Question sur les pointeurs.
    Par Chrisemi dans le forum C++
    Réponses: 5
    Dernier message: 28/10/2005, 23h47
  5. questions sur les pointeurs
    Par Hyoga dans le forum C++
    Réponses: 17
    Dernier message: 08/01/2005, 23h25

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