Qu'est-C! opérateur?

j'ai vu une ligne de C qui ressemblait à ceci:

!ErrorHasOccured() ??!??! HandleError();

compilé correctement et semble fonctionner correctement. On dirait qu'il vérifie si une erreur s'est produite, et si c'est le cas, il s'en occupe. Mais je ne suis pas vraiment sûr de ce qu'il fait réellement ou comment il le fait. Il semble que le programmeur essaie d'exprimer ses sentiments sur les erreurs.

Je n'ai jamais vu le ??!??! avant dans n'importe quel langage de programmation, et je ne peux pas trouver documentation pour it anywhere. (Google n'aide pas avec des termes de recherche comme ??!??! ). Que fait-il et comment fonctionne l'échantillon de code?

1642
demandé sur Nathaniel Ford 2011-10-19 20:56:59
la source

4 ответов

??! est un trigraphe qui se traduit par | . Ainsi il est dit:

!ErrorHasOccured() || HandleError();

qui, en raison de courts-circuits, est équivalent à:

if (ErrorHasOccured())
    HandleError();

gourou de la semaine (traite avec le C++ mais pertinent ici), où je l'ai récupéré.

origine Possible de trigraphs ou comme @DwB points dans les commentaires, il est plus probable en raison de EBCDIC étant difficile (encore). Ce discussion sur l'IBM developerworks conseil semble à l'appui de cette théorie.

de la norme ISO / CEI 9899: 1999 §5.2.1.1, note de bas de page 12 (h / t @Random832):

les séquences trigraphiques permettent l'entrée de caractères qui ne sont pas définis dans le code Invariant défini comme décrit dans la norme ISO / IEC 646, qui est un sous-ensemble de l'ensemble de codes ASCII américains de sept bits.

1341
répondu user786653 2012-03-21 12:52:52
la source

Eh bien, pourquoi cela existe en général est probablement différent de pourquoi il existe dans votre exemple.

tout a commencé il y a un demi-siècle avec la conversion des terminaux de communication sur papier en interfaces utilisateurs. Dans L'ère Unix et C initiale qui était le télétype ASR-33.

ce dispositif était lent (10 cps) et bruyant et laid et sa vue sur le jeu de caractères ASCII s'est terminée à 0x5f, donc il avait (regardez attentivement l'image) Aucune des clés:

{ | } ~ 

les trigraphes ont été définis pour résoudre un problème spécifique. L'idée était que les programmes C pouvaient utiliser le sous-ensemble ASCII trouvé sur L'ASR-33 et dans d'autres environnements n'ayant pas les valeurs ASCII élevées.

votre exemple est en fait deux de ??! , chaque signification | , de sorte que le résultat est || .

cependant, les gens écrire le code C presque par définition avait l'équipement moderne, 1 ainsi mon hypothèse est: quelqu'un montrant ou amusant eux-mêmes, laissant une sorte d'œuf de Pâques dans le code pour que vous trouviez.

ça a marché, ça a mené à une question très populaire.

ASR-33 Teletype

ASR-33 Teletype


1. D'ailleurs, les trigraphes ont été inventés par le Comité de L'ANSI, qui a rencontré pour la première fois après c devenir un succès galopant, de sorte qu'aucun des codes C originaux ou codeurs ne les aurait utilisés.
362
répondu DigitalRoss 2016-08-15 21:02:28
la source

C'est un C trigraph . ??! est | , donc ??!??! est l'opérateur ||

143
répondu Joel Falcou 2017-03-09 01:15:38
la source

comme déjà indiqué ??!??! est essentiellement deux trigraphes ( ??! et ??! à nouveau) mushed ensemble qui se remplacent-traduit par || , I. e le logique ou , par le préprocesseur.

l'image suivante contenant toutes les trigraphies devrait aider à distinguer les combinaisons trigraphiques alternatives:

enter image description here (Image tirée de C: manuel de référence 5e édition )

donc un trigraphe qui ressemble à ??(??) finira par correspondre à [] , ??(??)??(??) sera remplacé par [][] et ainsi de suite, vous obtenez l'idée.

puisque les trigraphes sont substitués pendant le prétraitement, vous pouvez utiliser cpp pour obtenir une vue de la sortie vous-même, en utilisant un programme stupide trigr.c :

void main(){ const char *s = "??!??!"; } 

et son traitement avec:

cpp -trigraphs trigr.c 

vous obtiendrez une sortie de console de

void main(){ const char *s = "||"; }

comme vous pouvez le voir, l'option -trigraphs doit être spécifiée ou sinon cpp émettra un avertissement; Ceci indique comment les trigraphes sont une chose du passé et de Aucune valeur moderne autre que de confondre les gens qui pourraient tomber sur eux .


quant à la raison d'être de l'introduction des trigraphes, elle est mieux comprise en regardant la section histoire ISO/IEC 646 :

ISO / IEC 646 et son prédécesseur ASCII (ANSI X3.4) a largement approuvé les pratiques existantes en matière d'encodage des caractères dans les industrie des télécommunications.

comme ASCII n'a pas fourni un certain nombre de caractères nécessaires pour les langues autres que l'anglais, un certain nombre de variantes nationales ont été faites qui ont substitué certains caractères moins utilisés avec ceux nécessaires 1519370920".

(l'emphase est mienne)

ainsi, en essence, certains caractères nécessaires (ceux pour lesquels un il existe) ont été remplacés dans certaines variantes nationales. Cela conduit à la représentation alternative à l'aide de trigraphes composés de caractères que d'autres variantes avaient encore autour.

88
répondu Jim Fasarakis Hilliard 2017-08-19 02:49:19
la source

Autres questions sur c operators trigraphs