Les chaînes ASCII et endianness
D'un stagiaire qui travaille avec moi m'a montré un examen qu'il avait pris en informatique à propos de l'endianness questions. Il y avait une question qui a montré une chaîne de caractères ASCII "Mon-Pizza", et l'élève avait à montrer comment cette chaîne serait représenté en mémoire sur un little endian ordinateur. Bien sûr, cela sonne comme une question piège, car les chaînes ASCII ne sont pas affectés par endian questions.
Mais étonnamment, le stagiaire affirme que son professeur insiste sur le fait que la chaîne serait représenté comme:
P-yM azzi
Je sais que cela peut ne pas être juste. Il n'existe aucun moyen d'une chaîne de caractères ASCII qui serait représenté comme ça sur n'importe quelle machine. Mais apparemment, le professeur insiste sur ce point. Alors, j'ai écrit un petit programme en C et a dit à la stagiaire de le donner à son professeur.
#include <string.h>
#include <stdio.h>
int main()
{
const char* s = "My-Pizza";
size_t length = strlen(s);
for (const char* it = s; it < s + length; ++it) {
printf("%p : %c\n", it, *it);
}
}
Cela démontre clairement que la chaîne est stockée comme "Ma-Pizza" dans la mémoire. Un jour plus tard, le stagiaire obtient de nouveau à moi et me dit le professeur prétend maintenant que C est automatiquement convertir les adresses pour afficher la chaîne de caractères dans le bon ordre.
Je lui ai dit que son professeur est fou, et c'est clairement faux. Mais juste pour ma propre santé mentale ici, j'ai décidé de poster ceci sur stackoverflow pour que je puisse obtenir d'autres pour confirmer ce que je dis.
Donc, je pose la question : qui est là?
- Avez-vous accès à un débogueur pour montrer au prof? Est-ce que linux ou windows?
- Assurez-vous. La même chose pourrait être démontrée à l'aide de gdb sur linux, en examinant chaque octet dans la mémoire
- Pas besoin d'un débogueur: le cas des OP (bien joué) utilisation de la
%p
spécificateur de format vous indique tous vous avez vraiment besoin de savoir. - Bien que
strlen()
dans unfor()
boucle conditionnelle me fait grincer des dents. - SÉRIEUSEMENT? Qui est ce gars? (et +1 pour Chris).
- M. Lutz -- Conscient de l' %p j'ai senti qu'il ne sera pas assez pour le professeur en question. Après tout, le professeur se sent déjà que l'opérateur ++ n'quelque chose d'intelligent avec char * de "jump around", il pourrait aussi bien aussi une sorte de renuméroter lui-même lorsqu'il est passé à printf(). Un débogueur est un autre de mise en oeuvre et indépendant de la langue, j'ai pensé qu'il pourrait éduquer le prof. 😉
- Vérifier l'assembleur & écrire votre propre routine assembleur. Aussi...j'espère ne jamais rencontrer le prof.
- Je ne pense pas que vous voudriez nom de ce professeur.
- Bien qu'il n'est pas question, dans cette question, j'ai enlevé le strlen appel de la boucle, de sorte que moins de gens écrire comme ça quand venir pour une entrevue.
- Peut-être que je suis en train de faire le prof trop de crédit, mais le fait que le "humanisé de sortie de l'explication" n'a pas eu lieu à quiconque me fait penser que SI a vraiment bâclé la réponse à celui-ci...
- Je pense que vous êtes à côté de la question; ce professeur de réclamations, pour quelque raison que endianness questions (qui, par définition, n'affectent types de plus de 8 bits) affectent de données de 8 bits. Pouvez-vous expliquer ce que vous pensez qu'il essaie de dire?
- J'ai juste donné un exemple dans ma réponse. Bien sûr, je ne peux pas lire le prof de l'esprit, mais le fait que cette autre explication n'a même pas les gens, c'est .. un sujet de préoccupation.
- Une autre explication est que le prof et la foule sont "pas tout faire". Si le prof est mauvais, il doit avoir au moins eu à vous les gars pourquoi il pourrait avoir été mal. Je pense toujours que c'est juste une question de la représentation. Je suppose que nous aurions interview du prof pour savoir à coup sûr.
- $ cat > /tmp/Ma pizza-Pizza$ $ od-X /tmp/pizza 0000000 502d794d 617a7a69 0000010 $ Pour l'enregistrement, y == 79, M == 4d. Faire le point?
- Ouais je vois que dans votre réponse ci-dessous, mais je ne vois pas comment vous pouvez obtenir cette interprétation de la question. Il semble assez clair pour moi ce qu'il se passe. Si le prof a eu tort et nettoyé jusqu'au lieu d'essayer de perpétuer, avec son jour le plus tard réponse, je pense que ce serait une autre histoire.
- vous êtes l'amalgame entre la façon dont la chaîne peut être représenté dans un certain format, par rapport à comment il est stocké en mémoire, ce qui est le problème ici. Par votre logique, une traduction en espagnol de la chaîne serait également valable "représentation", parce que c'est une façon pour une application particulière peut "interpréter" la chaîne.
Vous devez vous connecter pour publier un commentaire.
Sans doute, vous avez raison.
C ANSI standard 6.1.4 spécifie que les littéraux de chaîne sont stockés dans la mémoire par la "concaténation" des personnages dans le littéral.
Norme ANSI 6.3.6 spécifie également l'effet de l'addition sur une valeur de type pointeur:
Si l'idée attribuée à cette personne était correcte, alors le compilateur aurait aussi du singe autour avec math entier lorsque les entiers sont utilisés comme indices de tableau. Beaucoup d'autres erreurs se traduirait également, qui sont laissés à l'imagination.
La personne peut être confus, parce que (contrairement à une chaîne d'initialiseur), multi-octets chacter constantes telles que 'ABCD' sont stockées dans endian commande.
Il y a beaucoup de raisons pour lesquelles une personne pourrait être confus au sujet de ce. Comme d'autres l'ont suggéré ici, il peut être mal interpréter ce qu'il voit dans une fenêtre du débogueur, où le contenu a été octets échangés pour des raisons de lisibilité de valeurs int.
Le professeur est confus. Afin de voir quelque chose comme 'P-yM azzi' vous avez besoin de prendre un peu de mémoire outil d'inspection qui affiche la mémoire en 'entier de 4 octets en mode et en même temps donne un caractère "interprétation" de chaque entier d'ordre supérieur octet de poids faible octet de mode.
Cela, bien sûr, n'a rien à voir avec la chaîne elle-même. Et dire que la chaîne elle-même est représenté de cette façon sur un little-endian machine est une absurdité totale.
Le professeur est faux si l'on parle d'un système qui utilise 8 bits par caractère.
Je travaille souvent avec les systèmes embarqués qui utilisent vraiment des caractères 16 bits, chaque mot est little-endian. Sur un tel système, la chaîne "Ma-Pizza" serait en effet être stockées en tant que "yMP-ziaz".
Mais tant que c'est un 8 bits par caractère du système, la chaîne sera toujours stocké comme "Ma-Pizza" indépendant de la endian-ness de la hausse du niveau de l'architecture.
CHAR_BIT
, qui doit être supérieur ou égal de 8. Donc, si la plus petite mémoire adressable de l'unité de la DSP est un 16 bits mot, sur ce système, un octet est 16 bits de large.Endianness définit l'ordre des octets dans les multi-octets valeurs. Les chaînes de caractères sont des tableaux de simples valeurs d'octets. De sorte que chaque valeur (caractère de la chaîne) est le même sur les deux little-endian et big-endian architectures, et boutisme n'affecte pas l'ordre des valeurs dans une structure.
Vous pouvez très facilement prouver que le compilateur fait aucune "magie" des transformations, en faisant de l'impression dans une fonction qui ne sait pas qu'elle a été passée une chaîne de caractères:
L'enfer, vous pouvez même le compiler à l'assemblée avec
gcc -S
et de déterminer de façon concluante l'absence de la magie.Il serait représenté comme, représentée comme quoi? représenté à l'utilisateur que 32 bits entier dump? ou représentés/mise en mémoire de l'ordinateur en tant que P-yM azzi?
Si le professeur a dit "Mon-Pizza" serait représenté/mise en page comme "P-yM azzi" dans la mémoire de l'ordinateur, parce que l'ordinateur est de little endian architecture, quelqu'un, s'il vous plaît, appris à enseigner que le professeur comment utiliser un débogueur! Je pense que c'est là où tous les professeur de confusions tiges à partir, j'ai une petite idée que le professeur n'est pas un codeur(non pas que je suis à la recherche vers le bas sur le professeur), je pense qu'il n'ont pas un moyen de prouver dans le code, ce qu'il a appris au sujet de endian-ness.
Peut-être que le professeur a appris le endian-ness des trucs juste sur une semaine, alors il suffit d'utiliser un débogueur de manière incorrecte, rapidement séduite par son nouvel éclairage unique sur les ordinateurs et ensuite de le prêcher à ses étudiants immédiatement.
Si le professeur dit-boutiste " de la machine a une influence sur la façon dont les chaînes ascii serait représenté en mémoire, il faut nettoyer son acte, quelqu'un doit le corriger.
Si le professeur a donné un exemple sur la façon dont les entiers sont représentés/mise en page dans les machines différemment en fonction de la machine endianness, ses étudiants pourraient goûtent ce qu'il est de l'enseignement tout au sujet.
Je suppose que le professeur essayait de faire un point par analogie sur la endian/NUXI problème, mais vous avez raison quand vous l'appliquez à de véritables chaînes de caractères. Ne vous laissez pas faire dérailler le fait qu'il a essayé d'enseigner à des élèves d'un point et de réfléchir à un problème d'une certaine manière.
Vous pourriez être intéressés, il est possible d'émuler un little-endian architecture sur un big-endian machine, ou vice-versa. Le compilateur émet code auto-magiquement mess avec le moins de bits significatifs de
char*
pointeurs quand il déréférence eux: sur une machine 32 bits, vous auriez carte 00 <-> 11 et 01 <-> 10.Ainsi, si vous écrivez le nombre
0x01020304
sur un big-endian machine, et de lire le dos de la "première" de l'octet de que avec cette adresse-munging, puis vous obtenez l'octet le moins significatif,0x04
. L'implémentation C est little-endian, même si le matériel est big-endian.Vous avez besoin d'une astuce similaire pour les courts accède. Non alignés accès (si pris en charge) ne peut pas saisir les octets adjacents. Vous aussi vous ne pouvez pas utiliser natif de magasins pour les types plus gros qu'un mot, car ils me semblent mot échangé lu un octet à la fois.
Évidemment toutefois, little-endian machines de ne pas faire cela tout le temps, c'est un très spécialiste de la disposition et vous empêche d'utiliser le native ABI. Me semble que si le professeur pense de nombres réels comme étant "en fait" big-endian, et est profondément troublé ce qu'est un "little endian" l'architecture est vraiment et/ou la façon dont sa mémoire est représentée.
Il est vrai que la chaîne est "représenté par"
P-yM azzi
sur 32 bits l-e machines, mais seulement si par "représenté" tu veux dire "lire les mots de la représentation dans l'ordre croissant de l'adresse, mais l'impression de les octets de chaque mot big-endian". Comme d'autres l'ont dit, c'est ce que certains débogueur mémoire de vues pourraient faire, il est en effet un représentation du contenu de la mémoire. Mais si vous allez à représenter la personne octets, alors il est plus courant de la liste dans l'ordre croissant de l'adresse, peu importe si les mots sont stockées être ou l-e, plutôt que de représenter chaque mot comme un multi-char littérale. Certainement il n'y a pas de pointeur-manipulation en cours, et si le professeur a choisi de représentation qui l'a conduit à penser qu'il y en a, puis il a induit en erreur.Aussi (Et je n'ai pas joué avec cela dans un temps long, alors j'ai peut-être mal), Il pourrait être la pensée de pascol, où les chaînes sont représentés sous forme de "paniers de matrices" qui, autant que je me souvienne sont des personnages emballé dans 4 octets entiers?
Autant que je sache, endianness n'a de sens que lorsque vous voulez briser une grande valeur dans les petits. Donc je ne pense pas que C chaîne de style sont touchés avec elle. Parce qu'ils sont, après tout juste des tableaux de caractères. Lors de la lecture d'un seul octet, comment pourrait-il en question si vous le lire à partir de la gauche ou de droite?
Il est difficile de lire le prof de l'esprit et certainement le compilateur n'est pas faire autre chose que de stocker les octets adjacents augmentation des adresses à la fois ÊTRE et des systèmes de CHIERS, mais il est normal de mémoire d'affichage dans word taille des nombres, quelle que soit la taille de mot est, et nous l'avons écrit un millier de 1 000. Pas 000,1.
Pour l'enregistrement, y == 79, M == 4d.
Je suis tombé sur ce et a ressenti le besoin de clarifier les choses. Personne ici ne semble avoir abordé la notion de
byte
s etword
s ou comment adresse eux. Un octet est 8-bits. Un mot est une collection d'octets.Si l'ordinateur est:
alors en effet, le professeur serait correct. Son absence, cela prouve qu'il ne veut pas savoir exactement de quoi il parle, mais il l'a fait comprendre le concept de base.
D'Ordre d'octet à l'Intérieur des Mots: (a) en Big Endian, (b) Little Endian
Caractère Entier et les Données en Termes: (a) en Big Endian, (b) Little Endian
Références
Le professeur "C" du code a l'air de rien comme ça? Si oui, il doit mettre à jour son compilateur.