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 De Syntaxe ?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Août 2007
    Messages
    93
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 93
    Par défaut Question De Syntaxe ?
    Salut à tous! Voilà je me pose une petite question à propos de ces deux déclarations:

    unsigned short* buffer = (unsigned short*)0x6000000;
    et unsigned short* buffer = 0x6000000;

    Apparement ces deux écritures sont équivalentes...
    Pour moi le second cas est plus intelligible et me semble normal, à savoir on dispose d'un pointeur contenant l'adresse 0x6000000.

    je ne comprends donc pas la première écriture,
    en effet , j'ai l'impression que buffer contient l'adresse 0x6000000 qui elle-même est un pointeur sur un unisgned short, et donc selon ce raisonnement
    *buffer devrait me donner l'adresse contenu dans la case mémoire 0x6000000... Or le résultat est le même que dans le second cas.....

    En bref je ne comprends pas tout , je suis un peu embrouillé.

    Merci !

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par swingNJava Voir le message
    Salut à tous! Voilà je me pose une petite question à propos de ces deux déclarations:

    unsigned short* buffer = (unsigned short*)0x6000000;
    et unsigned short* buffer = 0x6000000;

    Apparement ces deux écritures sont équivalentes...
    Pour moi le second cas est plus intelligible et me semble normal, à savoir on dispose d'un pointeur contenant l'adresse 0x6000000.

    je ne comprends donc pas la première écriture,
    en effet , j'ai l'impression que buffer contient l'adresse 0x6000000 qui elle-même est un pointeur sur un unisgned short, et donc selon ce raisonnement
    *buffer devrait me donner l'adresse contenu dans la case mémoire 0x6000000... Or le résultat est le même que dans le second cas.....

    En bref je ne comprends pas tout , je suis un peu embrouillé.

    Merci !
    Non. La première écriture demande juste que la valeur "0x6000000" soit castée en pointeur sur un unsigned short et dans la 2° le cast est implicite. C'est comme si t'écrivais
    double val=(double)10
    double val=10
    Les deux écritures sont équivalentes. Mais dans la 2° le cast est implicite...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    unsigned short* buffer = (unsigned short*)0x6000000;
    et unsigned short* buffer = 0x6000000;
    La seconde écriture doit provoquer un message d'alerte du compilateur car assigner une valeur entière (non nulle) à un pointeur n'est pas portable.
    La première a l'avantage d'informer le compilateur que cette magouille est faite volontairement et le dispense ainsi d'émettre un avertissement.

  4. #4
    Membre confirmé
    Inscrit en
    Août 2007
    Messages
    93
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 93
    Par défaut
    Il y a toujours une petite chose qui m'échappe.

    Faut-il comprendre par là que l'adresse 0x6000000 représente un pointeur sur elle même ?
    Ce code est utilisé pour déclarer un pointeur sur la mémoire vidéo...
    De ce que je m'étais immaginé, 0x6000000 représentait le début de la mémoire vidéo ... c'est à dire une zone mémoire contenant les pixels a allumé.

    j'aurais procédé donc comme ceci pour allumer le premier pixel en haut a gauche : 0x6000000 = color;
    Or si 0x6000000 est un pointeur , en faisant cela je ne modifie pas la couleur et seulement l'adresse pointé par 0x6000000....

    tout cela est terriblement flou dans mon esprit !

  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
    Faut-il comprendre par là que l'adresse 0x6000000 représente un pointeur sur elle même ?
    Ce code est utilisé pour déclarer un pointeur sur la mémoire vidéo...
    De ce que je m'étais immaginé, 0x6000000 représentait le début de la mémoire vidéo ... c'est à dire une zone mémoire contenant les pixels a allumé.
    Il faut entendre qu'il y a intérêt à ce que 0x6000000 soit l'adresse de quelque chose auquel on a le droit d'accéder, sinon on va au plantage.

    j'aurais procédé donc comme ceci pour allumer le premier pixel en haut a gauche : 0x6000000 = color;
    Or si 0x6000000 est un pointeur , en faisant cela je ne modifie pas la couleur et seulement l'adresse pointé par 0x6000000....
    Tu n'as pas le droit d'écrire 0x6000000 = quelque chose. 0x6000000 n'est pas un objet
    0x6000000 n'est pas un pointeur. C'est un entier que tu assimile à une adresse (pas à un objet pointeur) ou si tu préfères une constante pointeur (pas un objet pointeur constant)
    La seule constante pointeur légale est NULL


    Pour accéder à un objet dont on a l'adresse on utilise l'opérateur unaire * :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    *(unsigned short*)0x6000000 = color
    *buffer  = color

  6. #6
    Membre confirmé
    Inscrit en
    Août 2007
    Messages
    93
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 93
    Par défaut
    Tout d'abord merci pour toutes ces réponses.
    Je crois que je commence à comprendre un peu mieux, corrigez moi si je me trompe:
    En fait lorsque l'on déclare
    unsigned short * buffer = (unsigned short *) 0x6000000;
    on fait comprendre au compilateur que l'adresse (physique ??) est accessible,
    c'est a dire que le processeur en lisant le code machine va pouvoir tenter un accès directe à cette adresse... Est-ce bien çà ?

    Ce n'est en fait qu'une syntaxe pour indiquer la sémantique de ce qu'on veut faire! a savoir accéder à la partie physique commençant à l'adresse 0x6000000.

    Mais ce n'est pas la déclaration d'un simple pointeur habituel... si ?

    je ne sais pas si ce que je raconte est très intelligible.

    Merci.

  7. #7
    Membre chevronné Avatar de Pierre Maurette
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 283
    Par défaut
    Citation Envoyé par swingNJava Voir le message
    unsigned short* buffer = (unsigned short*)0x6000000;
    et unsigned short* buffer = 0x6000000;

    Apparement ces deux écritures sont équivalentes...
    Pour moi le second cas est plus intelligible et me semble normal, à savoir on dispose d'un pointeur contenant l'adresse 0x6000000.

    je ne comprends donc pas la première écriture
    C'est pourtant la seule qui est valable, et je n'aime pas un compilateur qui se contente d'avertir dans le cas de la seconde. Je n'aime pas non plus un compilateur qui ne me jetterais pas si la constante 0X6.... était trop grande.
    Vous voulez initialiser un pointeur en dur, ce qui n'est pas habituel, mais parfois indispensable, j'y reviendrai. Pour initialiser un pointeur, il n'y a comme possibilité que NULL ou un pointeur du même type, ou un void*, conversion muette. Le void* peut être vu comme ce qui correspond le mieux à la notion d'adresse, au plus bas niveau. Un pointeur void* s'obtient par exemple en retour de malloc(). Notez qu'il ne faut pas caster le retour de malloc().
    Un pointeur du même type s'obtient par l'opérateur & appliqué à une variable du même type. Et exceptionnellement en convertissant explicitement par le cast un entier.
    Autre point: 0x600000 n'est pas une valeur. C'est une constante littérale, c'est à dire un truc typé. Essayez pour vous en convaincre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%d %d %d %d\n", sizeof 0x60000000, sizeof 0x60000000LL, sizeof 0, sizeof 0LL);
    Avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int i = foo();
    unsigned short* buffer = (unsigned short*)i;
    unsigned short* buffer = i;
    quelle forme vous convient le mieux ?
    Maintenant le cas qui semble-t-il vous intéressse, celui de définir une variable à une adresse en dur donnée par la documentation de votre système. On n'est plus dans le domaine du C portable, mais c'est parfaitement légitime, puisque cette possibilité d'intervenir sur le matériel représente une des utilisations importantes de ce langage. Déjà, très certainement, vous ne devrez pas faire des hypothèses sur la taille de vos types (unsigned short sur 16 ou 32 bits ?), mais vérifier ces tailles. Ou mieux utiliser des types à taille fixe fournis par <stdint.h>. Prenons maintenant un exemple. Attention, les valeurs sont débiles, toute opération d'écriture ou même de lecture sur la mémoire pointée peut avoir des conséquences ... caca. Sur un périphérique quelconque, nous voulons accéder aux ports d'entrée et de sortie, des registres 8 bits dont nous connaissons les adresses par la documentation. Nous les écrivons:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define PORT_IN  ((uint8_t*)0X1234)
    #define PORT_OUT ((uint8_t*)0X5678)
    Mainenant nous déclarons et initialisons des pointeurs vers les registres:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    volatile const uint8_t* portIn  = PORT_IN;
    volatile uint8_t* portOut = PORT_OUT;
    /* ... */
    valeurLue = *portIn;
    *portOut = ++valeurLue;
    (ne pas tester les deux dernières lignes !).Le const est évident, le port d'entrée ne doit pas être écrit[*]. Pour le volatile (cui cui) c'est un peu plus subtil. Le compilateur fait ce qu'il veut face à volatile, mais normalement il devrait comprendre "Compilateur, cette adresse ne t'appartient pas, elle peut changer sans que tu le sache, elle peut faire des trucs sur une simple lecture, etc., alors ne fait pas de zèle, fait ce qu'on te dit de faire, ni plus ni moins, et tout ira bien". Alors, normalement, face à ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    valeurLue = *portIn;
    valeurLue = *portIn;
    *portOut = 0;
    *portOut = 103;
    le compilateur devrait générer 2 opération de lecture mémoire et deux opérations d'écriture mémoire, dans l'ordre du code source.

    [*]Les adresses des ports d'entrée et de sortie peuvent être les mêmes, le cas est classique, il faut quand même créer deux pointeurs, enfin, c'est mieux.

  8. #8
    Membre confirmé
    Inscrit en
    Août 2007
    Messages
    93
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 93
    Par défaut
    Merci beaucoup Pierre, ton explication m'a beaucoup aidé,
    je crois avoir désormais bien compris!

    Un grand merci à vous tous !

  9. #9
    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 swingNJava Voir le message
    Salut à tous! Voilà je me pose une petite question à propos de ces deux déclarations:

    unsigned short* buffer = (unsigned short*)0x6000000;
    et unsigned short* buffer = 0x6000000;

    Apparement ces deux écritures sont équivalentes...
    Pas vraiment. La conversion entier -> pointeur nécessite un cast (même en C). Quoiqu'il en soit, le résultat dépend de l'implémentation et n'est pas spécifié par le langage C.

    Pour moi le second cas est plus intelligible et me semble normal, à savoir on dispose d'un pointeur contenant l'adresse 0x6000000.
    Si ça a un sens sur ta machine, admettons.
    je ne comprends donc pas la première écriture,
    en effet , j'ai l'impression que buffer contient l'adresse 0x6000000 qui elle-même est un pointeur sur un unisgned short, et donc selon ce raisonnement
    *buffer devrait me donner l'adresse contenu dans la case mémoire 0x6000000... Or le résultat est le même que dans le second cas.....
    C'est le C qui veut ça. Avec l'opérateur 'typecast' : (unsigned short *), on indique au compilateur que la conversion est bien voulue et qu'il s'agit de convertir la valeur d'un entier constant en un pointeur de la même valeur.

    Encore une fois, le comportement résultant dépend de l'implémentation.

  10. #10
    Membre confirmé
    Inscrit en
    Août 2007
    Messages
    93
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 93
    Par défaut
    oki merci à tous ,
    je crois que j'ai à peu mieux compris de quoi il s'agissait!

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

Discussions similaires

  1. Debutant - Question de syntaxe "::" seuls devant u
    Par Caille dans le forum Débuter
    Réponses: 3
    Dernier message: 08/02/2006, 15h59
  2. Question de syntaxe
    Par dafalri dans le forum VB 6 et antérieur
    Réponses: 12
    Dernier message: 13/12/2005, 20h57
  3. [XML] Questions de syntaxe
    Par ghohm dans le forum XML/XSL et SOAP
    Réponses: 4
    Dernier message: 03/11/2005, 12h08
  4. question sur syntaxe d'une requete
    Par sparis dans le forum MS SQL Server
    Réponses: 8
    Dernier message: 29/09/2005, 11h58
  5. [C linux makefile] question de syntaxe
    Par Ultros dans le forum Systèmes de compilation
    Réponses: 7
    Dernier message: 09/04/2004, 07h58

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