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 :

Chaine et adresse


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur JAVA JEE / PHP
    Inscrit en
    Avril 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur JAVA JEE / PHP
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2008
    Messages : 151
    Par défaut Chaine et adresse
    Salut,

    J'ai deux programmes qui marchent bien, mais je ne sais pas pourquoi si on fait :

    c'est la même chose que
    voir le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    main(){
       char nom[25];
       scanf("%s", nom);
       scanf("%s", &nom);
       getch();
    }
    C'est quoi la différence ?

    Merci d'avance

  2. #2
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut
    En fait c'est quasiment pareil ^^
    Dans les 2 cas tu envoies l'adresse du premier élément de ton tableau.
    Donc les 2 expressions sont correctes

    Dans le premier cas tu envoies le tableau, ce qui reviens à envoyer l'adresse du premier élément de ce tableau.
    Dans le deuxième cas tu envoies l'adresse du tableau, qui pointe sur le premier élément du tableau.

  3. #3
    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
    La première est correcte, et la seconde ne l'est pas. Ce n'est pas une question de valeurs mais une question de type.

    Dans la première expression, nom a le type char * ce qui est correct, alors que dans la seconde, &nom a le type char(*)[25], adresse d'un tableau de 25 char. Rien n'indique d'ailleurs, à ma connaissance, que ces deux adresses aient les mêmes propriétés (représentation et alignement).

    Dans un scanf, le compilateur peut ne pas vérifier la conformité des arguments avec la chaine de format, mais pour d'autres fonctions, dont le type des paramètres est fixé par le prototype, ceci peut poser problèmes.

  4. #4
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut
    C'est vrai que ça peut porter à confusion, mais (il me semble) que la norme le dit clairement (la flème de chercher ^^).
    Sinon il suffit de faire un petit test pour montrer que c'est pareil :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #include <stdio.h>
     
    int main(void) {
    	char str[10] = "Pouet";
    	printf("str:\t%p\n", str);
    	printf("&str:\t%p\n", &str);
    	return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    str:	0x7fff5fbff7a0
    &str:	0x7fff5fbff7a0
    (gdb) x/s str
    0x7fff5fbff7a0:	 "Pouet"
    (gdb) x/s &str
    0x7fff5fbff7a0:	 "Pouet"
    Le compilateur peut indiquer des warning, mais ce n'est en aucun cas incorrect
    Le compilateur n'a pas toujours raison

  5. #5
    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
    mais (il me semble) que la norme le dit clairement (la flème de chercher ^^).
    Prend la peine de chercher, ça m'interresse !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	printf("str:\t%p\n", str);
    	printf("&str:\t%p\n", &str);
    - Mais printf() se moque pas mal du type de ses arguments. D'ailleurs, pour %p, l'argument devrait être du type void * ce qui n'est pas le cas dans ton test.
    - Ce n'est pas parce que un test semble marcher que la propriété est prouvée.


    Le compilateur n'a pas toujours raison
    A part le coté provocateur de la remarque, ce raisonnement est dangereux au possible. Si tu n'as pas confiance dans ton compilateur, il vaut mieux en changer.

  6. #6
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut
    Norme C : §6.5.2.1-2
    A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).
    Norme C : §6.5.3.2-3
    The unary & operator yields the address of its operand. If the operand has type ‘‘type’’, the result has type ‘‘pointer to type’’. If the operand is the result of a unary * operator, neither that operator nor the & operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue. Similarly, if the operand is the result of a [] operator, neither the & operator nor the unary * that is implied by the [] is evaluated and the result is as if the & operator were removed and the [] operator were changed to a + operator. Otherwise, the result is a pointer to the object or function designated by its operand.
    Pour le printf je savais que j'allais avoir une remarque sur le (void*) :p
    C'est pour ça que j'ai mis un coup de GDB derrière

    Ce code donne le même résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <stdio.h>
     
    int main(void) {
    	char str[10] = "Pouet";
    	void *p = str;
    	printf("str:\t%p\n", p);
    	p = &str;
    	printf("&str:\t%p\n", p);
    	return 0;
    }

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

Discussions similaires

  1. [Mail] Comment extraire une adresse mail d'une chaine
    Par pymouse dans le forum Langage
    Réponses: 8
    Dernier message: 29/05/2006, 11h57
  2. Détecter adresse email parmis une chaine de caractère
    Par Coussati dans le forum Langage
    Réponses: 2
    Dernier message: 15/03/2006, 22h17
  3. Réponses: 6
    Dernier message: 29/11/2005, 16h40
  4. Affichage de l'adresse d'une chaine avec cout
    Par thierryguilbert dans le forum SL & STL
    Réponses: 4
    Dernier message: 14/03/2005, 16h04
  5. Réponses: 2
    Dernier message: 14/01/2005, 15h40

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