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 :

probleme déclaration constante #define


Sujet :

C

  1. #21
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    => pourquoi ils ont créé le suffix 'u' si les constantes sont déjà en unsigned ?
    Elles ne le sont pas toujours

    0b101 // unisgned int (valeur binaire)
    Les constantes binaires ne sont pas dans la norme. En tant qu'extension, il est probable qu'elles suivent toujours les règles des constantes octales ou hexadécimales.

    0x12 // unsigned int (valeur hexadecimale)
    02 // unsigned int ? (valeur octal)
    Non, si les valeurs sont représentables par un int, elles ont le type int, sinon unsigned int , sinon long, sinon unsigned long,...

    2 // unsigned int ? (valeur decimale)
    -2 // int ? (valeur decimale)
    Elles sont de type int si elles sont représentables par un int sinon long, sinon long long (donc toujours d'un type signé)

    '
    \xFA' // int (valeur hexadecimale)
    Oui, mais la valeur dépend si char est signé ou non.

    => c'est pareil un int et un signed int ?
    oui
    => c'est possible que le type char soit de signe différent que le type int ?
    oui. C'est d'ailleurs souvent une option de compilation.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  2. #22
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par boboss123 Voir le message
    => pourquoi ils ont créé le suffix 'u' si les constantes sont déjà en unsigned ?
    C'est pas le cas.

    Donc pour résumer, on a bien ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    0b101 // unisgned int (valeur binaire)
    C'est pas du C, c'est une extension parfois presente. A priori ca devrait etre int si on a suivi la logique des autres constantes.

    0x12 // unsigned int (valeur hexadecimale)
    La valeur est representable dans un int donc c'est un int.

    2 // unsigned int ? (valeur decimale)
    La valeur est representable dans un int donc c'est un int.

    -2 // int ? (valeur decimale)
    C'est pas une constante, c'est une expression de type int.

    02 // unsigned int ? (valeur octal)
    La valeur est representable dans un int donc c'est un int.

    '\xFA' // int (valeur hexadecimale)
    int. De valeur -6 ou 250 suivant le fait que char soit signe ou pas.

    Note que les regles pour le type des constantes ont change entre C90 et C99, mais tu ne donne pas un exemple ou elles donnent des resultats differents.

    A chaque fois c'est le premier type qui permet de representer exactement la valeur dans

    C90:
    Sans prefixe: int, long, unsigned long
    Avec prefixe: int, unsigned, long, unsigned long

    C99:
    Sans prefixe: int, long, long long
    Avec prefixe: int, unsigned, long, unsigned long, long long, unsigned long long

    Un suffixe U ne permet que les unsigned (et on utilise la liste avec prefixe meme s'il n'y en a pas)
    Un suffixe L ou LL commence dans la liste a long ou long long.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  3. #23
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    merci pour vos explications (je m'étais encore trompé dans mon raisonnement )


    Pour le changement de type entre des char/int j'ai fait quelque test pour voir comment fonctionne ce qui dépend de l'implémentation :
    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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
     
    	signed char varsc;
    	unsigned char varsc;
    	int iVal; // int est signed int, c'est pareil
    	unsigned int uiVal;
     
     
    	varsc = -6;
    	varuc = varsc;
    	printf("signed char(-6) -> unsigned char: %u\r\n", varuc);
     
    	varsc = varuc;
    	printf("unsigned char(250) -> signed char: %i\r\n", varsc);
     
    	// ****
    	iVal = varsc;
    	uiVal = varsc;
    	printf("signed char(-6) -> int: %i\r\n", iVal);
    	printf("signed char(-6) -> unsigned int: %u\r\n", uiVal);
     
    	// ****
    	iVal = varuc;
    	uiVal = varuc;
    	printf("unsigned char(250) -> int: %i\r\n", iVal);
    	printf("unsigned char(250) -> unsigned int: %u\r\n", uiVal);
     
    	// ****
    	printf("int(250) -> unsigned char: %u\r\n", (unsigned char)iVal);
    	printf("int(250) -> signed char: %i\r\n", (signed char)iVal);
     
    	// ****
    	printf("unsigned int(250) -> unsigned char: %u\r\n", (unsigned char)uiVal);
    	printf("unsigned int(250) -> signed char: %i\r\n", (signed char)uiVal);
     
    	// ****
    	printf("\r\n");
     
    	iVal = -6;
    	uiVal = iVal;
    	printf("int(-6) -> unsigned int: %u\r\n", uiVal);
     
    	varsc = iVal;
    	varuc = iVal;	
    	printf("int(-6) -> signed char: %i\r\n", varsc);
    	printf("int(-6) -> unsigned char: %u\r\n", varuc);	
     
    	varsc = uiVal;
    	varuc = uiVal;	
    	printf("unsigned int(4294967290) -> signed char: %i\r\n", varsc);
    	printf("unsigned int(4294967290) -> unsigned char: %u\r\n", varuc);		
     
     
    	// ****
    	printf("\r\n");
     
    	iVal = -4660; // = 0xFFFF00F6u
     
    	uiVal = iVal;
    	printf("int(-4660) -> unsigned int: %u\r\n", uiVal);
     
    	varsc = iVal;
    	varuc = iVal;	
    	printf("int(-4660) -> signed char: %i\r\n", varsc);
    	printf("int(-4660) -> unsigned char: %u\r\n", varuc);

    voici ce que ça m'affiche (j'ai rajouté à la main les commentaires) :
    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
     
    signed char(-6) -> unsigned char: 250 // valeur binaire identique ('FA'h -> 'FA'h)
    unsigned char(250) -> signed char: -6 // valeur binaire identique ('FA'h -> 'FA'h)
    signed char(-6) -> int: -6 // valeur numérique identique ('FA'h -> 'FFFFFFFA'h)
    signed char(-6) -> unsigned int: 4294967290 // même valeur binaire que lorsqu'on cast en int ('FA'h -> 'FFFFFFFA'h)
    unsigned char(250) -> int: 250 // valeur numérique identique ('FA'h -> '000000FA'h)
    unsigned char(250) -> unsigned int: 250 // valeur numérique identique ('FA'h -> '000000FA'h)
    int(250) -> unsigned char: 250 // valeur numérique identique ('000000FA'h -> 'FA'h)
    int(250) -> signed char: -6 // même valeur binaire que lorsqu'on cast en unsigned char ('000000FA'h -> 'FA'h)
    unsigned int(250) -> unsigned char: 250 // valeur numérique identique ('000000FA'h -> 'FA'h)
    unsigned int(250) -> signed char: -6 // même valeur binaire que lorsqu'on cast en unsigned char ('000000FA'h -> 'FA'h)
     
     
    int(-6) -> unsigned int: 4294967290 // valeur binaire identique ('FFFFFFFA'h -> 'FFFFFFFA'h)
    int(-6) -> signed char: -6 // valeur numérique identique ('FFFFFFFA'h -> 'FA'h)
    int(-6) -> unsigned char: 250 // même valeur binaire que lorsqu'on cast en signed char ('FFFFFFFA'h -> 'FA'h)
    unsigned int(4294967290) -> signed char: -6 // même résultat que si on cast un int qui à la même valeur binaire ('FFFFFFFA'h -> 'FA'h)
    unsigned int(4294967290) -> unsigned char: 250// même résultat que si on cast un int qui à la même valeur binaire ('FFFFFFFA'h -> 'FA'h)
     
     
    int(-4660) -> unsigned int: 4294962636 // valeur binaire identique ('FFFF EDCC'h) -> 'FFFF EDCC'h)
    int(-4660) -> signed char: -52 // correspond à l'octet de poid faible de la valeur binaire (0xCC = -52) ('FFFF EDCC'h) -> 'CC'h)
    int(-4660) -> unsigned char: 204 // correspond à l'octet de poid faible de la valeur binaire (0xCC = 204) ('FFFF EDCC'h) -> 'CC'h)
    Donc en suivant les 4 règles suivantes, je peux facilement prévoir la valeur que j'aurais lors d'un changement de type, non ? Je me suis pas trompé cette fois ?
    - caster 'signed char' vers 'unsigned char' (où l'inverse), ne change pas la représentation binaire de la variable (mais change représentation numérique)
    - caster 'signed int vers unsigned int' (où l'inverse), ne change pas la représentation binaire de la variable (mais change représentation numérique)
    - caster '(signed/unsigned) char' vers '(signed/unsigned) int', ne change pas la valeur numérique de la variable (mais change la représentation binaire)
    - caster '(signed/unsigned) int' vers '(signed/unsigned) char', correspond juste à récupérer l'octet de poid faible sans faire aucune modification sur celui-ci (ex : 'FFFFFFFA'h => 'FA'h)

  4. #24
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Il faut noter que si les unsigned sont toujours codés en binaire pur, les signed ne le sont pas toujours en complément à 2 (en fait, il y a trois codages admis : complément à 2, complément à 1 et signe+valeur absolue).

    La norme adopte alors une forme plus abstraite pour couvrir ces situations et ne parle pas de la transformation des représentations en binaire lors de ces changements de type mais du changement de la valeur (qui est ce qui importe au programmeur) :

    Je résume :

    - Si la valeur peut être représentée dans le type de destination, elle est inchangée

    - Sinon, si le type de destination est unsigned, la valeur est ramenée dans la plage de validité du type de destination en ajoutant ou en soustrayant le nombre de fois qu'il faut la valeur maximum du type de destination +1

    - Sinon, le résultat dépend de l'implémentation (valeur incodable dans un type de destination signed)
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  5. #25
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    Oui je l'avais bien compris.

    Les 4 règles que j'ai citées ne sont à utiliser que pour le compilateur que j'utilise.

    le terme "résultat dépend de l'implémentation" désigne quoi exactement ? la méthode utilisé pour le traitement du signe (complément a 2...) ou ça dépend exclusivement des spécificités du compilateur ?

  6. #26
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Ca veut dire que le compilateur fait quelque chose de précis, à son choix, qui normalement devrait être mentionné et décrit dans sa documentation, mais que tous les compilateurs ne sont pas contraints à faire la même chose.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  7. #27
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    oki, merci

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. [VBA] Probleme déclaration de variable
    Par Léponge85 dans le forum Macros et VBA Excel
    Réponses: 13
    Dernier message: 11/06/2008, 14h57
  2. Où définir les constantes #define
    Par bubulemaster dans le forum Windows Forms
    Réponses: 2
    Dernier message: 14/03/2008, 12h13
  3. Probleme déclaration fonction...
    Par bixi dans le forum Langage
    Réponses: 5
    Dernier message: 30/01/2006, 19h52
  4. Réponses: 4
    Dernier message: 14/12/2005, 17h25
  5. [Delphi 2005 Perso] Probleme déclaration de méthode
    Par alk dans le forum Delphi .NET
    Réponses: 5
    Dernier message: 08/11/2005, 16h19

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