56 votes

Si un tampon d'octets être signé ou non signé char buffer?

Si un tampon d'octets être signé char ou unsigned char ou tout simplement un char buffer? Les différences entre le C et le C++?

Merci.

47voto

Si vous avez l'intention de stocker des données binaires arbitraires, vous devez utiliser unsigned char. C'est le seul type de données est garanti ont pas de rembourrage bits par la Norme. Chaque autre type de données peut contenir rembourrage bits dans sa représentation d'objet (qui est celui qui contient tous les bits d'un objet, non seulement à ceux qui détermine une valeur). Le remplissage des bits d'état est indéterminée et ne sont pas utilisés pour stocker des valeurs. Donc, si vous lisez l'aide d' char des données binaires, les choses allaient être coupés à la plage de valeurs de type char (par l'interprétation que la valeur des bits), mais il existe peut-être les bits qui sont tout simplement ignorés, mais sont toujours là et lire en memcpy. Un peu comme le rembourrage de bits dans la vraie structure des objets. Type unsigned char est garanti de ne pas contenir de ceux-ci. Qui suit à partir de 5.2.4.2.1/2 (C99 TC2, n1124 ici):

Si la valeur d'un objet de type char est traité comme un entier signé lors de l'expression, la valeur de CHAR_MIN doit être la même que celle de SCHAR_MIN et le la valeur de CHAR_MAX doit être la même que celle de SCHAR_MAX. Sinon, la valeur de CHAR_MIN est 0 et la valeur de CHAR_MAX doit être le même que celui de UCHAR_MAX. La valeur UCHAR_MAX correspond 2^CHAR_BIT − 1

À partir de la dernière phrase, il s'ensuit qu'il n'y a pas d'espace à gauche pour tout remplissage bits. Si vous utilisez char que le type de votre tampon, vous avez aussi le problème de débordement: Attribuant une valeur explicitement à un tel élément, qui est dans la gamme de 8 bits, de sorte que l'on peut attendre d'une telle attribution d'être OK, mais pas dans la gamme d'un char, ce qui est CHAR_MIN..CHAR_MAXune telle conversion des débordements et des causes de la mise en œuvre des résultats, y compris l'augmentation de signaux.

Même si des problèmes concernant le ci-dessus serait probablement pas dans les mises en production (ce serait une très mauvaise qualité de la mise en œuvre), vous êtes mieux d'utiliser le bon type depuis le début, qui est - unsigned char.

Pour les cordes, cependant, le type de données de choix est - char, qui sera comprise par la chaîne de caractères et de fonctions d'impression. À l'aide de signed char , à ces fins, ressemble à une mauvaise décision pour moi.

Pour plus d'informations, lisez this proposal qui contient un correctif pour une prochaine version de la Norme C qui finira par exiger signed char n'ont aucun rembourrage bits soit. C'est déjà incorporé dans le document de travail.

34voto

dan04 Points 33306

Si un tampon d'octets être signé char ou unsigned char ou tout simplement un char tampon? Les différences entre C et C++?

Une petite différence dans la façon dont le langage de la traite. Une énorme différence dans la façon dont la convention de la traite.

  • char = ASCII (ou UTF-8, mais la ce paramètre est dans la manière, y) textuelle de données
  • unsigned char = octet
  • signed char = rarement utilisé

Et il y a du code qui s'appuie sur cette distinction. Tout juste une semaine ou deux il ya, j'ai rencontré un bug où les données de format JPEG a été corrompu parce qu'il a été transmis à l' char* version de notre Base64 encode la fonction qui "utilement" remplacé tous les UTF-8 non valide dans la "chaîne". Changer d' BYTE aka unsigned char , il n'en fallait pour le fixer.

12voto

RBerteig Points 23331

Il dépend.

Si la mémoire tampon est destiné à contenir du texte, alors il est probablement de sens que de le déclarer comme un tableau d' char et de laisser la plate-forme de décider pour vous si c'est signé ou non signé par défaut. Qui vous donnera le moins de difficulté à passer les données dans et hors de la mise en œuvre de l'exécution de la bibliothèque, par exemple.

Si la mémoire tampon est destiné à contenir des données binaires, ensuite, cela dépend de comment vous avez l'intention de l'utiliser. Par exemple, si les données binaires est vraiment un panier éventail d'échantillons de données qui sont signés sur 8 bits à virgule fixe ADC mesures, signed char serait le mieux.

Dans la plupart du monde réel des cas, le tampon est un tampon, et vous n'avez pas vraiment sur les types de l'individu octets parce que vous avez rempli le tampon dans une opération en bloc, et vous êtes sur le point de passer à un analyseur d'interpréter la structure de données complexe et de faire quelque chose d'utile. Dans ce cas, le déclarer de la manière la plus simple.

9voto

Pete Kirkham Points 32484

Si c'est réellement une mémoire tampon de 8 bits, octets, plutôt qu'une chaîne de caractères dans la machine locale par défaut, puis j'utiliserais uint8_t. Pas qu'il y a de nombreuses machines où un char n'est pas un octet (ou un octet un octet), mais qui fait la déclaration "c'est un tampon d'octets' plutôt que 'ceci est une chaîne' est souvent utile de documentation.

4voto

Naveen Points 37095

Il est préférable de la définir comme unsigned char. Enfait Win32 OCTET de type est défini comme un unsigned char. Il n'y a pas de différence entre C et C++ entre ce.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X