Vraag Wat doet de C ??! ??! operator doen?


Ik zag een lijn van C die er zo uitzag:

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

Het is correct gecompileerd en lijkt goed te werken. Het lijkt erop dat het controleert of er een fout is opgetreden en als dat het geval is, wordt het afgehandeld. Maar ik weet niet echt zeker wat het eigenlijk doet of hoe het het doet. Het lijkt erop dat de programmeur zijn gevoelens over fouten probeert uit te drukken.

Ik heb het nooit gezien ??!??! voorheen in een programmeertaal, en ik kan er nergens documentatie voor vinden. (Google helpt niet met zoektermen zoals ??!??!). Wat doet het en hoe werkt het codevoorbeeld?


1603
2017-10-19 16:56


oorsprong


antwoorden:


??! is een TRIGRAPH dat vertaalt naar |. Dus het zegt:

!ErrorHasOccured() || HandleError();

die vanwege kortsluiting gelijk is aan:

if (ErrorHasOccured())
    HandleError();

Guru van de week (gaat over C ++ maar hier relevant), waar ik dit heb opgepikt.

Mogelijke oorsprong van trigraphs of zoals @DwB opmerkt in de reacties, is het waarschijnlijker dat EBCDIC (opnieuw) moeilijk is. Deze discussie over het IBM developerworks board lijkt die theorie te ondersteunen.

Uit ISO / IEC 9899: 1999 §5.2.1.1, voetnoot 12 (h / t @ Random832):

De trigraph-reeksen maken invoer van tekens mogelijk die niet zijn gedefinieerd in de invariante codeset   beschreven in ISO / IEC 646, een subset van de zeven-bits US ASCII-codeset.


1319
2017-10-19 16:58



Welnu, waarom dit in het algemeen bestaat, is waarschijnlijk anders dan waarom het in uw voorbeeld voorkomt.

Het begon allemaal een halve eeuw geleden met het herbestemmen van hardcopy communicatieterminals als computergebruikersinterfaces. In het oorspronkelijke Unix en C-tijdperk was dat het ASR-33-teletype.

Dit apparaat was traag (10 cps) en luidruchtig en lelijk en de weergave van de ASCII-tekenset eindigde op 0x5f, dus het had (kijk maar naar de foto) geen van de toetsen:

{ | } ~ 

De trigraphs werden gedefinieerd om een ​​specifiek probleem op te lossen. Het idee was dat C-programma's de ASCII-subset konden gebruiken die te vinden was op de ASR-33 en in andere omgevingen die de hoge ASCII-waarden missen.

Je voorbeeld is er eigenlijk twee van ??!, elke betekenis |, dus het resultaat is ||.

Mensen die C-code bijna per definitie schrijven, hadden echter moderne apparatuur,1 dus mijn gok is: iemand die pronkt of zichzelf amuseert, een soort paasei achterlaten in de code die je kunt vinden.

Het werkte zeker, het leidde tot een enorm populaire ZO-vraag.

ASR-33 Teletype

ASR-33 Teletype


1. De trigraphs werden trouwens uitgevonden door de ANSI-commissie, die voor het eerst bijeenkwam na C werd een weggelopen succes, dus geen van de originele C-code of codeurs zou ze hebben gebruikt.


354
2017-10-19 21:09



Het is een C TRIGRAPH. ??! is |, dus ??!??! is de operator ||


140
2017-10-19 16:58



Zoals al vermeld ??!??! is in wezen twee trigraphs (??! en ??! opnieuw) samen mushed die worden vervangen-vertaald naar ||, d.w.z. de Logische OR, door de preprocessor.

De volgende afbeelding met alle trigraphs zou moeten helpen bij het disambigueren van alternatieve trigraph-combinaties:

enter image description here (Afbeelding overgenomen van C: A Reference Manual 5th Edition)

Dus een trigraph die eruit ziet ??(??) zal uiteindelijk toewijzen aan [], ??(??)??(??) wordt vervangen door [][] en zo verder, krijg je het idee.

Aangezien trigraphs worden vervangen tijdens het voorbewerken, kunt u gebruiken cpp om de output zelf te bekijken, met behulp van een dwaze trigr.c programma:

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

en verwerken met:

cpp -trigraphs trigr.c 

U krijgt een console-uitvoer van

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

Zoals je kan opmerken, is de optie -trigraphs moet worden opgegeven of anders cpp zal een waarschuwing geven; dit geeft aan hoe triggumenten behoren tot het verleden en hebben geen moderne waarde, behalve het verwisselen van mensen die hen tegen kunnen komen.


Wat betreft de grondgedachte achter de introductie van trigraphs, is het beter begrepen bij het bekijken van de Geschiedenis gedeelte van ISO/IEC 646:

ISO / IEC 646 en zijn voorganger ASCII (ANSI X3.4) onderschreven grotendeels de bestaande praktijk met betrekking tot karaktercoderingen in de telecommunicatie-industrie.

ASCII leverde geen aantal tekens op die nodig zijn voor andere talen dan het Engels, een aantal nationale varianten werden gemaakt die enkele minder gebruikte karakters vervangen door de benodigde


79
2018-03-25 02:24