Cela pourrait être un problème très fondamental, mais je ne pouvais pas réussir à. Voici ce que je travaille avec.
size of char: 1 c1: ffffff80, c2: ffffff80 true or false: 1
4 Réponses :
Le type Dans votre cas, le type Donc, un objet du type donc après ces instructions p> Les deux objets ont la même valeur égale à < Code> -128 code>. p> et la sortie p> de cet appel p> Char code> peut se comporter comme type
signé Char code> ou comme type
non signé Char code> Selon une option de compilateur ou par défaut de la compilateur.
Char code> se comporte comme type
signé Char code>. Dans ce cas,
char_min code> est égal à
-128 code> et
char_max code> est égal à
127 code>. P>
Char code> ne peut pas contenir le nombre positif 128. Cette valeur a la représentation hexadécimale suivante
0x80 code>. So stocké dans un objet du type
Char code> Il est interprété comme une valeur négative car le bit de signalisation est défini. Cette valeur négative est
-128 code>. P>
c2 code> sont favorisés au type
int code> ont la même représentation d'une valeur négative. p> < P> Faites attention à ce que c'est un comportement défini par la mise en œuvre d'attribuer un objet du type signé avec une valeur positive qui ne peut pas être représentée dans l'objet. P> P>
@Holyblackcat levant un signal signifie que le comportement est indéfini. Par exemple, vous pouvez obtenir une valeur de piège.
Merci beaucoup! Votre explication est très simple et a du sens totalement. Je suppose que je comprends. Type de caractère est 8 bits et peut contenir 128, c'est-à-dire pourquoi l'erreur de débordement ne se produit pas et 128 est simplement convertie en -128 en fonction de la définition de la mise en œuvre.
Ici c'est expliqué: https://fr.wikipedia.org/wiki/signed_number_representations p>
Si -128 et 128 et tous les nombres entre les deux étaient représentés avec un octet, nous aurions 257 numéros dans cet ensemble. Cependant, nous ne sommes pas, c'est juste 256. P>
Son mappé comme suit décimal: [0..127, -128 ..- 1] => [0b00000000..0b11111111]. Notez que le premier bit devient 1 à -128, heureux accident;). P>
Aussi votre formatage de chaîne est incorrect, votre compilateur devrait vous avertir,% X attend 4 octets! Si vous prenez en compte ce que j'ai dit plus tôt, vous voyez que 0x80 est en effet 0B10000000. P>
dans La conversion est définie par la mise en œuvre, par 6.3.1.3 3: "Sinon, le nouveau type est signé et la valeur ne peut être représentée; Soit le résultat est défini par la mise en oeuvre ou un signal défini par la mise en œuvre est soulevé. " Votre implémentation C convertie 128, qui est 10000000 2 SUB> comme chiffre binaire non signé, à -128, qui est représentée avec les mêmes bits lors de l'utilisation de deux binaires signés. Ainsi, le résultat est que in Les promotions d'argument par défaut incluent les promotions entière, conformément au 6.5.2.2 6. Lorsque la plage de Ainsi, dans La chaîne de format spécifie une conversion à l'aide de Ceci explique pourquoi "FFFFFF80" est imprimé. Ce n'est pas parce que concernant C1 = 128; code>, 128 ne correspond pas au huit bits signé
char code> que votre implémentation C utilise votre mise en œuvre. 128 est converti en
Char code> par C 2018 6.5.16.1 2: "La valeur de l'opérande droit est convertie au type d'expression d'affectation ..." p>
C1 code> contient la valeur -128. P>
printf ("C1:% x, c2:% x \ n", C1, C2); code>,
C1 code> est converti en un
int < / code>. En effet, les règles pour appeler des fonctions avec
... code> doivent appliquer les promotions d'argument par défaut aux arguments correspondants, conformément aux arguments 6.5.2.2 7: "Les promotions d'argument par défaut sont effectuées sur des arguments de fin." p>
Char code> est plus étroite que
int code>, telle qu'elle est dans la plupart des implémentations, Les Promotions entier convertissent un
char code> à un
int code>, par 6.3.1.1 2: "Si un
int code> peut représenter toutes les valeurs du type d'origine ... , la valeur est convertie en un
int code> ... " p>
printf ("C1:% x, C2:% x \ n", C1, C2); code>, un
int code> de -128 est passé comme deuxième argument. Votre implémentation C utilise le complément de deux 32 bits pour
int code>, dans lequel -128 est représenté avec les bits 111111111111111111111110000000, que nous pouvons exprimer à Hexadecimal comme Ffffff80. P>
% x code>. Le type d'argument approprié pour
% x code> est
non signé INT code>. Toutefois, votre implémentation C a accepté le
int code> et réinterprété ses bits en tant que
non signé INT code>. Ainsi, les bits 11111111111111111111111000000000 sont convertis en chaîne "FFFFFF80". P>
C1 code> a quatre octets mais car il a été converti en un type à quatre octets avant d'être transmis à
printf code>. En outre, la conversion d'une valeur négative sur ce type de quatre octets a entraîné quatre octets avec de nombreux bits. P>
c1 == C2 code> évaluant à true (1), il s'agit simplement du fait que
C1 code> a été donné la valeur -128 comme expliqué ci-dessus et
c2 = = -128; code> attribue également la valeur -128 à
c2 code>, donc
C1 code> et
c2 code> avoir la même valeur. P>
Votre explication m'a beaucoup aidé à effacer le brouillard dans mon cerveau. Maintenant, j'ai appris la conversion intégrale, la promotion et la manière d'utiliser% Identifiant X. J'ai besoin d'apprendre à lire la définition de mise en œuvre. fonctionnalité de langue. Les programmeurs recherchent-ils généralement la page Web comme ( dii.uchile.cl/~ Daecino / fichiers / iso_c_1999_definition.pdf ) Chaque fois qu'ils ont besoin de confirmer la fonction de langue? Quoi qu'il en soit, merci beaucoup pour votre aide.
@AGONGJI Cette copie est probablement, strictement parlée, une violation du droit d'auteur. Disponible publiquement et généralement suffisantes sont les brouillons, répertoriés à EN.CPPREFERGENCE.COM/W/C/LINKS . Mais oui, bon nombre des affiches ici (probablement ceux qui gagnent un revenu en tant que développeurs possèdent une copie de la norme ISO, je suppose, avec d'autres livres de texte. La plupart des questions de langage C Technical C ont été correctement répondues. Les erreurs techniques ont tendance à être corrigées rapidement et de manière fiable ici. Mais certes, il est parfois difficile de rechercher ("Promotions d'argument par défaut" !?).
@AGONGJI: Les bons praticiens apprennent les règles assez bien qu'ils n'ont pas besoin de rechercher souvent les règles et / ou de développer des habitudes de rédaction de code qui évitent de devoir rechercher les règles et recherchent les règles si nécessaire. Après un certain temps, on se familiarise avec divers documents afin que de trouver des choses en eux deviennent plus rapides.
dans la déclaration comme pour les valeurs pouvant être représentées dans un Les codages pour les membres de l'ensemble de caractères em> 1 sup> sont garantis pour être non négatifs. Les codages pour des caractères supplémentaires peuvent être négatifs ou non négatifs. p> Ainsi, en fonction de la mise en œuvre, une branche supposant p> p> sup> p> % x code> attend un argument de type
non signé INT code>, de sorte que les valeurs de
c1 < / code> et
C2 code> est en cours de promotion de
char code> à
non signé INT code>, avec le bit leader étendu. Pour imprimer la valeur numérique d'un
non signé char code> comme hex, vous devez utiliser le modificateur
HH code> dans la conversion: p>
char code>, c'est un peu plus compliqué que cela. p>
char code> peut représenter des valeurs dans au moins la plage
[- 128..127] code> (supposant que le complément de deux Représentation) ou em> strud>
[0..255] code>. Je dis "au moins" depuis
char_bit code> peut être supérieur à 8 (il existe des systèmes historiques qui ont utilisé des octets de 9 bits et des mots 36 bits). Un
signé Char code> représentera des valeurs dans au moins la plage
[- 128..127] code> (à nouveau, en supposant le complément de deux). P>
Char code> est signé et 8 bits, puis attribuant 128 à
C1 code> conduit à SIGNED INTEGER Overflow em> et le comportement sur celui-ci est indéfini em> , ce qui signifie que le compilateur et l'environnement d'exécution ne sont pas obligés de le gérer de manière particulière. tout résultat em> est "correct" en ce qui concerne la définition de la langue, que ce soit le résultat que vous attendiez ou non. P>
Il n'y a pas de promotion à non signé INT ici. c1 code>,
c2 code> subir des promotions d'argument par défaut et finir par (dans ce cas) étant
int code> s, et comme ils n'ont pas de valeur positive, Ensuite, le comportement n'est pas défini lorsqu'il est utilisé avec des macros STDARG en tant qu'Ot non signé.
Qu'est-ce que TwoS complément d'un entier de 4 octets de -128?
Je pense que vous voyez Promotion et extension de signalisation.
Je suis confondu par votre déclaration. Dans ce code, vous avez attribué 128 à un type de caractère signé, et il a fait trop de débordement. Cela correspond à votre attente que la gamme est de -128 à 127.
1)
Char CODE> Fournissez un minimum ou -128..127 ou un minimum de 0..255. Ils peuvent fournir beaucoup plus. (Il y a un système avec des caractères 32 bits.)
2)
% x code> nécessite un
non signé INT code>. Votre
Char code> est en cours de promotion.
Vous dites déjà dans votre titre que la plage est
-128 à 127 code> alors pourquoi essayez-vous d'utiliser
(+) 128 code>?
@ikegami Je crois que la plage minimale de
Char code> si signée est -127..127 selon la norme.
@Christian gibbons, oh oui, bien sûr, pour accueillir les systèmes de complément de 1
Utilisez simplement le format d'impression correct
% hhx code> 128 ne correspond pas au char et il s'agit d'un débordement entier qui est un UB.
@ikegami ou signe et magnitude.
Agongji, avec
C2 = -128; code>, qu'avez-vous espéré? Si le code est allé, quelle valeur vous attendiez-vous au
C2 code>?