C++ vergelijking van tekenreeksletters

Ik ben een nieuweling in c++ (gewoon oldschool c). Mijn zoon heeft hierbij om hulp gevraagd en ik kan het niet uitleggen. Als hij me had gevraagd “hoe kan ik strings vergelijken”, zou ik hem hebben gezegd strcmp() te gebruiken, maar dat is niet wat me in de war brengt. Dit is wat hij vroeg:

int main() 
{ 
  cout << ("A"< "Z");
}

drukt er 1 af

int main() 
{ 
  cout << ("Z"< "A");
}

zal ook 1 afdrukken, maar

int main() 
{ 
  cout << ("Z"< "A");
  cout << ("A"< "Z");
}

zal dan 10 afdrukken. Afzonderlijk worden beide cout-statements 1 afgedrukt, maar achter elkaar uitgevoerd krijg ik een ander antwoord?


Antwoord 1, autoriteit 100%

U vergelijkt geheugenadressen. Blijkbaar plaatst je compiler de letterlijke tekenreeksen in het geheugen in de volgorde waarin hij ze tegenkomt, dus de eerste is “minder” dan de tweede.

Aangezien in het eerste fragment ‘A’ eerst en ‘Z’ als tweede wordt weergegeven, is ‘A’ kleiner. Omdat het “Z” als eerste in de tweede ziet, is “Z” minder. In het laatste fragment heeft het al letterlijke “A” en “Z” geplaatst wanneer het tweede commando rondrolt.


Antwoord 2, autoriteit 23%

Letterlijke tekenreeksen hebben een statische opslagduur. In al deze vergelijkingen zijn er vergeleken adressen van geheugen toegewezen door de compiler voor letterlijke tekenreeksen. Het lijkt erop dat de eerste letterlijke tekenreeks die de compiler tegenkomt, in het geheugen wordt opgeslagen met een lager adres in vergelijking met de volgende letterlijke tekenreeks.

Dus in dit programma

int main() 
{ 
  cout << ("Z"< "A");
  cout << ("A"< "Z");
}

De letterlijke tekenreeks “Z” is toegewezen met een lager adres dan de letterlijke tekenreeks “A”, omdat deze als eerste werd gevonden door de compiler.

Houd rekening met die vergelijking

 cout << ("A"< "A");

kan verschillende resultaten geven, afhankelijk van de opties van de compiler, omdat de compiler ofwel twee geheugengebieden kan toewijzen aan de letterlijke tekenreeksen of slechts één kopie van de letterlijke tekenreeksen kan gebruiken die hetzelfde zijn.

Van de C++-standaard (2.14.5 letterlijke tekenreeksen)

12 Of alle letterlijke tekenreeksen verschillend zijn (dat wil zeggen, worden opgeslagen in
niet-overlappende objecten) is implementatie gedefinieerd. Het effect van
proberen om een ​​letterlijke tekenreeks te wijzigen is niet gedefinieerd.

Hetzelfde geldt voor C.


Antwoord 3, autoriteit 17%

In de verklaring:

cout << ("A"< "Z");

Je hebt 2 tekenreekslettersgemaakt: "A"en "Z". Deze zijn van het type const char *wat een verwijzing is naar een null-getermineerde reeks tekens. De vergelijking hier is het vergelijken van de wijzers en niet de waarden waarnaar ze verwijzen. Het is deze vergelijking van geheugenadressen hier die je de compilerwaarschuwing geeft. Het resultaat van de vergelijking zal worden bepaald door waar de compiler het geheugen heeft toegewezen dat enigszins willekeurig zal zijn van compiler tot compiler. In dit geval lijkt het erop dat de eerste gevonden letterlijke waarde het eerste geheugenadres krijgt toegewezen door uw compiler.

Net als in C om deze letterlijke tekenreeksen goed te vergelijken, moet je strcmpdie een waardevergelijking zal doen.

Als je echter iets op de meer idiomatische c++ manier doet door het volgende te doen:

cout << (std::string("A") < std::string("Z"));

Dan krijg je de juiste vergelijking van de waarden zoals die vergelijkingsoperator is gedefinieerd voor std::string.

Other episodes