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 :

Problème de compréhension de scanf


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Novembre 2006
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 167
    Par défaut Problème de compréhension de scanf
    Bonjour,

    Alors voila j'ai une question très simple et je n'arrive pas à trouver de réponse convaincante:

    dans cet exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    long age = 0;
     
    scanf("Veuillez entrer un nombre %ld", &age):
    Pourquoi faut-il fournir l'adresse de la variable "age", pourquoi faut-il le faire précéder du signe '&' ?

    Cela me gêne parce que par exemple pour fgets nous n'avons pas besoin de fournir d'adresse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fgets(chaine, TAILLE_MAX, fichier);
    Ici on lit maximum TAILLE_MAX caractères du fichier et on stocke le tout dans "chaine" sans pour autant fournir l'adresse de "chaine".

    Dans beaucoup de situation on ne fournit pas d'adresse et je trouve ça logique car j'interprète cela comme une affectation.

    J'ai lu que ce '&' est nécessaire pour pouvoir ranger correctement l'information dans "age" mais je ne considère pas ça comme une réponse suffisante, car dans ce cas là, la morale est qu'il faut l'utiliser partout...

    Voila donc si quelqu'un pouvait m'expliquer l'intérêt de fournir l'adresse à scanf, ça ferait un peu d'ordre à toutes les questions que je me pose.

    Merci d'avance !

    Raiden.

  2. #2
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Raiden1234 Voir le message
    Alors voila j'ai une question très simple et je n'arrive pas à trouver de réponse convaincante:

    dans cet exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    long age = 0;
     
    scanf("Veuillez entrer un nombre %ld", &age):
    Pourquoi faut-il fournir l'adresse de la variable "age", pourquoi faut-il le faire précéder du signe '&' ?
    Parce que scanf() va écrire le résultat de la conversion dans age. Il n'y a pas d'autre choix que de passer l'adresse de la variable de destination.

    http://emmanuel-delahaye.developpez....difie_variable



    Cela me gêne parce que par exemple pour fgets nous n'avons pas besoin de fournir d'adresse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fgets(chaine, TAILLE_MAX, fichier);
    Ben si. chaine est une adresse.

    chaine est un tableau de char. L'adresse de son premier élément est donc &chaine[0], ce qui s'écrit aussi chaine + 0, donc chaine.

    Ce qu'on passe à fgets() est donc l'adresse du premier élément de chaine. Comme c'est un char, on passe l'adresse de ce char dans un pointeur sur char (char *).

    Dans beaucoup de situation on ne fournit pas d'adresse
    Attention, c'est pas ce qu'il n'y a pas de '&' que ce n'est pas une adresse. Tout dépend de la nature de ce qu'on passe en paramètre.

    J'ai lu que ce '&' est nécessaire pour pouvoir ranger correctement l'information dans "age"
    Oui, parce que age est int, et que scanf() avec %d veut l'adresse d'un int. Donc, on met le & pour avoir l'adresse de cet int. Si on avait eu un pointeur sur int (int*), on n'aurait pas le & (faute grave, sinon !).

    mais je ne considère pas ça comme une réponse suffisante, car dans ce cas là, la morale est qu'il faut l'utiliser partout...
    ce qui n'est pas vrai comme tu le sais maintenant. ce qu'il faut toujours avec scanf(), c'est une adresse. La manière de l'obtenir dépend du contexte.

  3. #3
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    scanf va analyser les caractères saisis au clavier. Il s'attend à ce que les données fournies analysées respecte le format du 1er paramètre.

    En lisant ce 1er paramètre, il s'apercoit qui faut qu'il extraie un nombre (%ld). Une fois que ce nombre est extrait, il faut le ranger quelque part, et ce quelque part, c'est en mémoire, à une certaine adresse fournie pas le programme.

    C'est donc le deuxième paramètre, l'adresse de la variable dans laquelle stocker le nombre extrait.

    Quant à ton 2eme exemple, c'est un petit peu différent
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fgets(chaine, TAILLE_MAX, fichier);
    En effet, chaine est un tableau de caractères (je suppose car je n'ai pas tout le code). En C, un tableau est une adresse et même l'adresse du premier élément du tableau.
    Donc effectivement, on valire le fichier et mettre ce qu'on a lu dans le tableau 'chaine' dont l'adresse de début est 'chaine'.

    C'est un concept un peu délicat à saisir au début du C, un tableau est une adresse.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  4. #4
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par ram-0000 Voir le message
    C'est un concept un peu délicat à saisir au début du C, un tableau est une adresse.
    Surtout que c'est le 'nom du tableau' et non le tableau lui même qui est une adresse (celle du premier élément du tableau). Il en a la valeur et surtout le type.

    C'est pour ça que sizeof tableau <> sizeof *tableau ...

    Dans le premier cas 'tableau' désigne une variable en mémoire nommé tableau'
    Dans le 2 ème cas, 'tableau' désigne une valeur constante (adresse du premier élément du tableau).

    Les tableaux C sont la chose plus difficile à expliquer de ce langage...

  5. #5
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Surtout que c'est le 'nom du tableau' et non le tableau lui même qui est une adresse.
    Yes sir, c'est plus correct et juste de le dire comme cela
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  6. #6
    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
    Pour résumer :

    Le nom du tableau représente :

    - le tableau lui-même lorsqu'il est associé à l'opérateur unaire & ou à l'opérateur sizeof ;

    - l'adresse du premier élément du tableau (élément pouvant lui-même être un tableau) dans tous les autres cas.

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 461
    Par défaut
    Citation Envoyé par Raiden1234 Voir le message
    Pourquoi faut-il fournir l'adresse de la variable "age", pourquoi faut-il le faire précéder du signe '&' ?
    Parce que si tu mets « age » tout seul, c'est le contenu (la valeur) de « age » qui va être transmis à la fonction, ce dont elle n'a rien à faire.

    Pour être plus précis, si une fonction produit une nouvelle valeur, c'est en général la fonction elle-même qui prend cette valeur, c'est-à-dire qu'elle la transmet au porgramme appelant en la renvoyant en tant que code de retour. Mais si tu as plusieurs valeurs à retourner et que tu ne peux pas utiliser une structure pour toutes les renvoyer ensemble, tu es obligé de dire à l'avance, à la fonction, à quel endroit elle doit les mettre. Et le mieux, c'est encore d'aller la stocker directement dans les variables qui doivent les recevoir. Donc, tu passes l'adresse de chacune des variables.

    Cela me gêne parce que par exemple pour fgets nous n'avons pas besoin de fournir d'adresse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fgets(chaine, TAILLE_MAX, fichier);
    Ici on lit maximum TAILLE_MAX caractères du fichier et on stocke le tout dans "chaine" sans pour autant fournir l'adresse de "chaine".
    Non, parce que « chaine » n'est pas un type de donnée à part entière mais une « chaines d'éléments de type xxxxx ». Tu peux donc avoir une chaîne d'entiers (int), une chaîne de caractères (char), ou même une chaîne de structures ... Tous ces éléments étant stockés consécutivement en mémoire, on te file en plus un pointeur qui contient l'adresse du premier élément (donc le début de la chaîne).

    C'est donc bien, ici, le contenu de « chaine » (soit l'adresse de la chaîne) qui nous intéresse, et pas l'adresse du pointeur lui-même.



    C'est une question importante parce que beaucoup de débutants lachent le C à cause de ce problème d'approche : le C est adapté à la production de programmes en langage machine. Or, même si la gestion proprement dite de la mémoire n'est pas forcément l'objectif final du programmeur, il faudra bien qu'en bout de processus, ce travail soit fait ... et il faut donc un langage pour exprimer cela.

    Après, comme ce n'est pas plus compliqué de taper « &x » que « x », autant connaître directement le fonctionnement de la machine que l'on utilise et éviter d'impliquer des couches intermédiaires pour faire la traduction et qui coûtent des ressources au run-time.

    Cependant, la notion de référence a été introduite en C++ et dans d'autres langages à ces fins (pouvoir désigner la variable elle-même sans avoir à manipuler explicitement son adresse).

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

Discussions similaires

  1. [Débutant] problème de compréhension
    Par Sylvester dans le forum Général Java
    Réponses: 18
    Dernier message: 21/07/2005, 09h16
  2. Réponses: 5
    Dernier message: 11/04/2005, 10h21
  3. [C#] Problème de compréhension de System.Convert ET Provider
    Par papouAlain dans le forum Windows Forms
    Réponses: 5
    Dernier message: 18/11/2004, 21h52
  4. onclipevent (problème de compréhension)
    Par stephane eyskens dans le forum Flash
    Réponses: 8
    Dernier message: 24/09/2003, 15h09
  5. Problème de compréhension des ensembles
    Par Cornell dans le forum Langage
    Réponses: 6
    Dernier message: 07/02/2003, 22h07

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