Prioriteit en volgorde van uitvoering van C-bewerkingen. Prioriteit en volgorde van uitvoering. Elementaire I/O in C

Prioriteit en uitvoeringsvolgorde

De prioriteit en associativiteit van C-operatoren beïnvloeden de volgorde waarin operanden worden gegroepeerd en bewerkingen worden geëvalueerd in een expressie. De prioriteit van operaties is alleen relevant als er meerdere operaties zijn met verschillende prioriteiten. Expressies met operatoren met een hogere prioriteit worden eerst geëvalueerd.

Tabel 4.1 geeft een overzicht van de handelingen in afnemende volgorde van prioriteit. Bewerkingen die zich in dezelfde tabelrij bevinden of in één groep zijn gecombineerd, hebben dezelfde prioriteit en dezelfde associativiteit.

Tabel 4.1.

Voorrang en associativiteit van bewerkingen in de C-taal

Operatie teken Naam Associativiteit
() . -> Primair Van links naar rechts
+ - ~! * & ++ -- grootte van typecast Unair Van rechts naar links
* / % Multiplicatief Van links naar rechts
+ - Additief Van links naar rechts
>> << Verschuiving Van links naar rechts
< > <= >= Houding Van links naar rechts
== != Houding Van links naar rechts
& Bitsgewijs EN Van links naar rechts
^ Bitwise exclusief OR Van links naar rechts
| Bitsgewijze inclusief OR Van links naar rechts
&& Logisch EN Van links naar rechts
|| Logische OF Van links naar rechts
?: Voorwaardelijk Van rechts naar links
= *= /= %= += -= <<= >>= &= |= ^= Eenvoudige en samengestelde opdracht Van rechts naar links
, Sequentiële berekening Van links naar rechts

Uit tabel 4.1. Hieruit volgt dat de operanden die de functieaanroep, de indexexpressie, de elementselectie-expressie en de expressie tussen haakjes vertegenwoordigen, de hoogste prioriteit en associativiteit van links naar rechts hebben. Type casting heeft dezelfde prioriteit en uitvoeringsvolgorde als unaire bewerkingen.

Een expressie kan meerdere bewerkingen met dezelfde prioriteit bevatten. Wanneer meerdere operators met hetzelfde prioriteitsniveau in een uitdrukking voorkomen, worden deze toegepast op basis van hun associativiteit: van rechts naar links of van links naar rechts.

Opgemerkt moet worden dat de C-taal voor sommige bewerkingen een ongelukkige prioriteitsvolgorde aanneemt, met name voor de shift- en bitsgewijze bewerkingen. Ze hebben een lagere prioriteit dan rekenkundige bewerkingen(toevoeging, enz.). Daarom de uitdrukking

a = b & 0xFF + 5

berekend als

a = b & (0xFF + 5),

en de uitdrukking

a+c >> 1

berekend als

(a + c) >> 1

Multiplicatieve, additieve en bitsgewijze bewerkingen hebben de eigenschap van commutativiteit. Dit betekent dat het resultaat van het evalueren van een uitdrukking die meerdere commutatieve bewerkingen met dezelfde prioriteit omvat, niet afhangt van de volgorde waarin deze bewerkingen worden uitgevoerd. Daarom behoudt de compiler zich het recht voor om dergelijke expressies in elke volgorde te evalueren, zelfs als de expressie haakjes bevat die de volgorde van evaluatie specificeren.

SP TS implementeert de unaire plus-bewerking, waarmee u de volgorde van berekening van uitdrukkingen tussen haakjes kunt garanderen.

Operatie opeenvolgende berekening, logische operaties AND en OR, de voorwaardelijke operator en de functieaanroepoperator garanderen een specifieke volgorde waarin hun operanden worden geëvalueerd. Een sequentiële evaluatiebewerking zorgt ervoor dat de operanden achtereenvolgens worden geëvalueerd, van links naar rechts (een komma die argumenten scheidt in een functieaanroep is geen sequentiële evaluatiebewerking en biedt dergelijke garanties niet). Het is alleen gegarandeerd dat tegen de tijd dat de functie wordt aangeroepen, alle argumenten al zijn berekend.

Een voorwaardelijke bewerking evalueert eerst de eerste operand en vervolgens, afhankelijk van de waarde, de tweede of derde.

Logische bewerkingen evalueren hun operanden ook van links naar rechts. Bij logische bewerkingen wordt echter het minimumaantal operanden geëvalueerd dat nodig is om het resultaat van een expressie te bepalen. Het is dus mogelijk dat de tweede operand van de expressie helemaal niet wordt geëvalueerd.

int x, y, z, f();

z = x > y || f(x, y);

Eerst wordt de uitdrukking x>y berekend. Als dit waar is, krijgt de variabele z de waarde 1 en wordt de functie f niet aangeroepen. Als de waarde van x niet groter is dan y, wordt de uitdrukking f(x,y) berekend. Als de functie f een waarde teruggeeft die niet nul is, krijgt de variabele z de waarde 1, anders 0. Merk ook op dat bij het aanroepen van de functie f gegarandeerd is dat de waarde van het eerste argument groter is dan de tweede.

Het beschouwde voorbeeld toont de belangrijkste mogelijkheden om de volgorde van uitvoering van logische bewerkingen te gebruiken. Dit is in de eerste plaats een verhoging van de efficiëntie door de meest waarschijnlijke omstandigheden als de eerste operanden van logische bewerkingen te plaatsen. Ten tweede is het mogelijk om controles in een expressie in te voegen. Als deze onwaar zijn, worden daaropvolgende acties niet uitgevoerd. Dus in de volgende voorwaardelijke operator als het lezen van het volgende teken uit het bestand wordt alleen uitgevoerd als het einde van het bestand nog niet is bereikt:

als(!feof(pf)) && (c = getc(pf)) ...

Hier feof- einde-bestandscontrolefunctie, krijgc- functie voor het lezen van een symbool uit een bestand (zie paragraaf 12).

Ten derde kunnen we dat in de uitdrukking garanderen f(x)&&g(y) functie F wordt vóór de functie aangeroepen G. Voor expressie f(x)+g(y) Dit kan niet gezegd worden.

De volgende voorbeelden tonen de groepering van operanden voor verschillende expressies.

Uitdrukking Operandgroepering
a&b || C (a en b) || C
a = b || C een = (b || c)
q && r || S-- (q && r) || (S--)
p == 0 ? p+= 1: p+= 2 (p == 0 ? p += 1: p) += 2

In het eerste voorbeeld heeft de bitsgewijze AND-operator (&) een hogere prioriteit dan de -logische OR-operator (||), dus de uitdrukking a&b is de eerste operand van de logische OR-bewerking.

In het tweede voorbeeld heeft de logische OR-operator (||) een hogere prioriteit dan de eenvoudige toewijzingsoperator, dus de expressie b||c vormt de rechter operand van de toewijzingsbewerking. (Merk op dat de toegewezen waarde A, is nul of één.)

C++ voor beginners

4.13. Prioriteiten

Bewerkingsprioriteiten specificeren de volgorde van berekeningen in een complexe expressie. Welke waarde krijgt ival bijvoorbeeld?

Int ival = 6 + 3 * 4 / 2 + 2;

Als je de bewerkingen van links naar rechts berekent, krijg je 20. Andere mogelijke resultaten zijn 9, 14 en 36. Het juiste antwoord is 14.
In C++ hebben vermenigvuldigen en delen een hogere prioriteit dan optellen, dus worden ze eerst geëvalueerd. Hun eigen prioriteiten zijn gelijk, dus vermenigvuldigen en delen worden van links naar rechts geëvalueerd. Dus de volgorde van berekening uitdrukking gegeven is:

1. 3 * 4 => 12 2. 12 / 2 => 6 3. 6 + 6 => 12 4. 12 + 2 => 14

Het volgende ontwerp gedraagt ​​zich niet zoals je zou verwachten. De prioriteit van de toewijzingsbewerking is kleiner dan die van de vergelijkingsbewerking:

Terwijl (ch = nextChar() != "\n")

De programmeur wilde een waarde toekennen aan de variabele ch en vervolgens controleren of deze gelijk was aan het teken nieuwe lijn. De expressie vergelijkt echter eerst de waarde die wordt geretourneerd door nextChar() met "\n" en wijst het resultaat (true of false) toe aan de variabele ch.
Bedieningsprioriteiten kunnen worden gewijzigd met behulp van haakjes. Uitdrukkingen tussen haakjes worden eerst geëvalueerd. Bijvoorbeeld:

4 * 5 + 7 * 2 ==> 34 4 * (5 + 7 * 2) ==> 76 4 * ((5 + 7) * 2) ==> 96

Hier ziet u hoe u haakjes kunt gebruiken om het gedrag van het vorige voorbeeld te corrigeren:

Terwijl ((ch = nextChar()) != "\n")

Exploitanten hebben en prioriteit, En associativiteit. De toewijzingsoperator is rechtsassociatief en wordt dus van rechts naar links geëvalueerd:

Ival = jval = kva1 = lval

Eerst krijgt kval de waarde van lval, daarna krijgt jval de waarde van het resultaat van die toewijzing, en ten slotte krijgt ival de waarde van jval.
Rekenkundige bewerkingen daarentegen blijven associatief. Daarom in de uitdrukking

Ival + jval + kva1 + 1va1

eerst worden ival en jval opgeteld, daarna wordt kval opgeteld bij het resultaat, en dan lval.
Tabel 4.4 laat zien volle lijst C++-operatoren in aflopende volgorde van prioriteit. Operators binnen dezelfde tabelsectie hebben dezelfde prioriteit. Alle operators in een sectie hebben een hogere prioriteit dan operators in de daaropvolgende secties. Vermenigvuldigings- en delingsbewerkingen hebben dus dezelfde prioriteit, en deze is hoger dan de prioriteit van alle vergelijkingsbewerkingen.

Oefening 4.18

In welke volgorde worden de volgende expressies geëvalueerd? Gebruik Tabel 4.4 om te antwoorden.

(A) ! ptr == ptr->volgende (b) ~ uc ^ 0377 & ui<< 4 (c) ch = buf[ bp++ ] != "\n"

Oefening 4.19

Alle drie de expressies uit de vorige oefening worden niet geëvalueerd in de volgorde die de programmeur blijkbaar wilde specificeren. Schik de haakjes om zijn oorspronkelijke bedoeling te bereiken.

Oefening 4.20

De volgende expressies veroorzaken een compilatiefout als gevolg van verkeerd begrepen operatorprioriteit. Leg uit hoe u deze kunt corrigeren aan de hand van Tabel 4.4.

(a) int i = doeiets(), 0; (b) uit<< ival % 2 ? "odd" : "even";

Tabel 4.4. Operationele prioriteiten

Exploitant Betekenis Gebruik
:: Mondiale reikwijdte ::naam
:: Klasse reikwijdte naam van de klasse
:: Naamruimtebereik naamruimte::naam
. Toegang voor leden object.lid
-> Toegang tot een lid via de aanwijzer pointer->lid
Het nemen van de index variabel
() Een functie aanroepen naam(expr_lijst)
() Constructie van betekenis type(expr_lijst)
++ postfix-verhoging lwaarde++
postfix-verlaging Waardeer--
getypt type-identificatie typeid(type)
getypt expressietype-ID typeid(expr)
soort conversie const_cast (expr)
soort conversie dynamische_cast (expr)
herinterpreteer_cast gieten herinterpreteer_cast (expr)
statische_cast gieten statische_cast (expr)
De grootte van objectgrootte grootte van expr
De grootte van soort maat groottevan(type)
++ verhoging van het voorvoegsel ++lwaarde
-- voorvoegsel verlagen --lwaarde
~ bitsgewijs NIET ~ expr
! logisch NIET !expr
- unair min -expr
+ unair plus +uitr
* dereferentie verwijderen *uitr
& adres &uitr
() gieten (type)expr
nieuw geheugen toewijzing nieuw type
nieuw geheugentoewijzing en initialisatie nieuw type(exprlijst)
nieuw Toewijzing van geheugen voor een array alle vormen
verwijderen geheugen vrijmaken alle vormen
verwijderen geheugen vrijmaken uit een array alle vormen
->* toegang krijgen tot een klaslid via een aanwijzer pointer-> *pointer_naar_lid
.* toegang krijgen tot een klaslid via een aanwijzer object.*pointer_naar_lid
* Vermenigvuldiging expr * expr
/ Divisie expr/expr
% modulo-verdeling expr % expr
+ toevoeging uitdr + uitdr
- aftrekken expr - expr
<< naar links verschuiven uitspr<< expr
>> naar rechts verschuiven uitdr >> uitdr
< minder uitspr< expr
<= minder of gelijk uitspr<= expr
> meer uitdr > uitdr
>= meer of gelijk uitdr >= uitdr
== gelijk aan expr == expr
!= niet gelijk uitdr!= uitdr
& bitsgewijze EN expr & expr
^ bitsgewijs EXCLUSIEVE OF expr^expr
| bitsgewijze OF expr | uitspr
&& logisch EN uitdr && uitdr
|| logisch OF expr || uitspr
?: voorwaardelijke operator expr? expr * expr
= opdracht l-waarde = expr
=, *=, /=, %=, +=, -=, <<=, >>=, &=, |=, ^= samengestelde opdracht l-waarde += expr enz.
gooien een uitzondering opwerpen gooi expr
, komma expr, expr

Om uitdrukkingen (zoals 4 + 2 * 3) goed te kunnen evalueren, moeten we weten welke operatoren wat betekenen en in welke volgorde ze moeten worden toegepast. Deze volgorde waarin ze worden uitgevoerd, wordt genoemd prioriteit van de operaties. Als vervolg op normale regels wiskunde (waarin vermenigvuldiging moet worden gedaan vóór optelling), wordt de bovenstaande uitdrukking opgelost als - 4 + (2 * 3), het resultaat is de waarde 10.

In C++ hebben alle operators (bewerkingen) hun eigen prioriteitsniveau. Degenen waarin het hoger is, worden als eerste uitgevoerd. In onderstaande tabel kun je zien dat de prioriteit van vermenigvuldigings- en delingsbewerkingen (5) hoger is dan die van optel- en aftrekkingsbewerkingen (6). De compiler gebruikt dit om de volgorde te bepalen waarin expressies worden verwerkt.

Maar wat als twee operatoren in een expressie hetzelfde prioriteitsniveau hebben en naast elkaar worden geplaatst? Welke handeling moet u als eerste uitvoeren? En hier zal de compiler gebruiken regels van associativiteit, die de richting van de activiteiten aangeven: van links naar rechts of van rechts naar links. In 3 * 4/2 hebben vermenigvuldigings- en delingsbewerkingen bijvoorbeeld hetzelfde prioriteitsniveau: 5. En de associativiteit op niveau 5 is van links naar rechts, dus we zullen het als volgt oplossen: (3 * 4) / 2 = 6.

Prioriteitstabel voor bewerkingen

Opmerkingen:

1 is het hoogste prioriteitsniveau en 17 is het laagste. Transacties met meer hoog niveau prioriteit worden eerst uitgevoerd.

L -> R betekent van links naar rechts.

R -> L betekent van rechts naar links.

Associativiteit Exploitant Beschrijving Voorbeeld
1. Nee :: Mondiale reikwijdte (unair) ::naam
:: Klassenbereik (binair) klassenaam::lidnaam
2. L->R () Ronde beugels (uitdrukking)
() Een functie aanroepen functie_naam(parameters)
() Initialisatie typenaam(expressie)
{} Uniforme initialisatie (C++11) typenaam(expressie)
type() Functionele cast nieuw_type(expressie)
type() Functionele cast (C++11) nieuw_type(expressie)
Array-index wijzer
. Toegang krijgen tot een objectlid object.lid_naam
-> Toegang krijgen tot een objectlid via een aanwijzer object_pointer->lidnaam
++ Post-verhoging lwaarde++
–– Post-verlaging lwaarde––
getypt Informatie over runtimetype typeid(type) of typeid(expressie)
const_cast Weggooien const const_cast(expressie)
dynamische_cast Door runtime type gecontroleerde cast dynamische_cast(expressie)
herinterpreteer_cast Cast het ene type naar het andere herinterpreteer_cast(expressie)
statische_cast Gecompileerde cast met typecontrole static_cast(expressie)
3. R->L + Unair plus +expressie
Unair min -uitdrukking
++ Voorverhogen ++lwaarde
–– Vooraf verlagen ––lwaarde
! Logisch NIET (NIET) !uitdrukking
~ Bitsgewijs NIET (NIET) ~ expressie
(type) C-stijl cast (new_type)expressie
De grootte van Grootte in bytes sizeof(type) of sizeof(expressie)
& Adres &lwaarde
* Dereferentie *uitdrukking
nieuw Dynamische geheugentoewijzing nieuw type
nieuw Dynamische array-toewijzing nieuw type
verwijderen Dynamische geheugenverwijdering aanwijzer verwijderen
verwijderen Dynamische array-verwijdering aanwijzer verwijderen
4. L->R ->* Selectie van ledenaanwijzer object_pointer->*pointer_naar_lid
.* Lidobjectselector object.*pointer_naar_lid
5. L->R * Vermenigvuldiging uitdrukking * uitdrukking
/ Divisie expressie / expressie
% Rest expressie % expressie
6. L->R + Toevoeging expressie + expressie
Aftrekken uitdrukking - uitdrukking
7. L->R << Verschuif bitsgewijs naar links uitdrukking<< expression
>> Bitsgewijs naar rechts verschuiven uitdrukking >> uitdrukking
8. L->R < Vergelijking. Minder dan uitdrukking< expression
<= Vergelijking. Minder dan of gelijk uitdrukking<= expression
> Vergelijking. Meer dan expressie > expressie
>= Vergelijking. Groter dan of gelijk aan expressie >= expressie
9. L->R == Gelijk aan uitdrukking == uitdrukking
!= Niet gelijk expressie != expressie
10. L->R & Bitsgewijs EN expressie & expressie
11. L->R ^ Bitwise exclusief OR (XOR) uitdrukking ^ uitdrukking
12. L->R | Bitsgewijze OF uitdrukking | uitdrukking
13. L->R && Logische EN (EN) expressie && expressie
14. L->R || Logische OF uitdrukking || uitdrukking
15. R->L ?: Ternaire voorwaardelijke operator (zie opmerking hieronder) uitdrukking ? uitdrukking: uitdrukking
= Opdracht lwaarde = expressie
*= Vermenigvuldigen met toewijzing lwaarde *= expressie
/= Afdeling met opdracht lvalue /= expressie
%= Deling met rest met opdracht lwaarde %= expressie
+= Toevoeging met opdracht lvalue += expressie
-= Aftrekken met toewijzing lwaarde -= expressie
<<= Bitsgewijze toewijzing naar links waarde<<= expression
>>= Bitsgewijze rechter shift-toewijzing lwaarde >>= expressie
&= Toewijzing met bitsgewijze AND-bewerking lwaarde &= expressie
|= Toewijzing met bitsgewijze OF-bewerking lwaarde |= expressie
^= Toewijzing met bitgewijze exclusieve OR (XOR)-bewerking lwaarde ^= expressie
16. R->L gooien Handmatig een uitzondering maken expressie gooien
17. L->R , Komma-operator (komma) expressie, expressie

Opmerking: Een expressie in het midden van een voorwaardelijke instructie?: wordt uitgevoerd alsof deze tussen haakjes staat.

Enkele operatoren die u al kent: +, -, *, /, (), =,<,>, <= и >=. Hun betekenissen zijn hetzelfde in zowel wiskunde als C++.

Als u echter geen ervaring heeft met andere programmeertalen, zullen de meeste van deze operators u op dit moment niet duidelijk zijn. Dit is goed. We behandelen de meeste ervan in dit hoofdstuk en behandelen de rest indien nodig.

Deze tabel is in de eerste plaats bedoeld zodat u deze op elk moment kunt raadplegen om het probleem op te lossen eventuele problemen prioriteit of associativiteit.

Hoe verheffen tot een macht in C++?

Het zou je al moeten zijn opgevallen dat de ^-operator, die vaak wordt gebruikt om machtsverheffen in de gewone wiskunde weer te geven, er niet één is in C++. In C++ is het bitgewijs XOR-bediening. Dus wat dan in plaats van ^? En in plaats daarvan de functie pow(), die zich in het headerbestand bevindt :

#erbij betrekken dubbel x = pow(3,0, 4,0); // 3 tot de macht 4

#erbij betrekken

dubbel x = pow (3,0, 4,0); // 3 tot de macht 4

Houd er rekening mee dat de parameters en retourwaarden van de pow()-functie van het dubbele type zijn. En aangezien typen met drijvende komma bekend staan ​​om hun afrondingsfouten, kunnen de resultaten van pow() enigszins onnauwkeurig zijn (iets minder of iets meer).

Als u een geheel getal tot een macht wilt verheffen, kunt u dit beter gebruiken eigen functie, Bijvoorbeeld:

// opmerking: de exponent mag niet negatief zijn int pow(int base, int exp) ( int result = 1; while (exp) ( if (exp & 1) result *= base; exp >>= 1; base *= basis ) retourresultaat;

// let op: exponent mag niet negatief zijn

int pow(int basis, int exp)

int-resultaat = 1;

terwijl(exp)

als (exp & 1)

resultaat * = basis;

exp >> = 1;

basis * = basis;

resultaat teruggeven;

Het hier gebruikte algoritme is "Exponentiatie door kwadrateren".

Maak je geen zorgen als iets niet duidelijk is. Houd wel rekening met het probleem van overflow, wat kan gebeuren als een van de argumenten te groot is.

Test

1) Van schoolwiskunde je weet dat de expressies tussen de haakjes eerst worden uitgevoerd. In (2 + 3) * 4 wordt bijvoorbeeld het (2 + 3) deel als eerste uitgevoerd.

Er zijn vier uitdrukkingen in deze opdracht waarbij haakjes ontbreken. Gebruik de operatorprioriteit- en associativiteitsregels in de bovenstaande tabel en voeg haakjes toe aan elke expressie alsof deze door de compiler zijn verwerkt.

Aanwijzing: Gebruik kolom Voorbeeld in de bovenstaande tabel om te bepalen of de operator unair is (heeft één operand) of binair (twee operanden). Als je vergeten bent wat unair of binair is, zie dan les 17.

Voorbeeldoplossing: x = 2 + 3% 4

De binaire operator % heeft een hogere prioriteit dan de + of = operator, dus wordt deze eerst toegepast: x = 2 + (3 % 4);

De binaire operator + heeft een hogere prioriteit dan = en wordt daarom als volgende gebruikt.

Taken

a) x = 3 + 4 + 5;
b) x = y = z;
c) z *= ++y + 5;
d) een || b && c || D;

Antwoord

A) Prioriteitsniveau binaire operator+ hoger dan in =:

x = (3 + 4 + 5);

Associativiteit van de binaire operator + van links naar rechts:

Antwoord: x = ((3 + 4) + 5).

B) Associativiteit van de binaire operator = van rechts naar links:

Antwoord: x = (y = z).

V) De unaire operator ++ heeft de hoogste prioriteit:

De binaire operator + heeft de op een na hoogste prioriteit:

Antwoord: z *= ((++y) + 5).

G) De binaire operator && heeft een hogere prioriteit dan ||:

een || (b && c) || D;

Associativiteit van de binaire operator || van links naar rechts:

Antwoord: (a || (b && c)) || D.

De volgorde van bewerkingen bij het berekenen van de waarde van een uitdrukking wordt bepaald door opstelling van bedieningsborden, haakjes En prioriteit van de operaties . Bewerkingen met de hoogste prioriteit worden als eerste uitgevoerd. Als een expressie meerdere bewerkingen met dezelfde prioriteit op hetzelfde niveau bevat, worden deze verwerkt in overeenstemming met de volgorde van uitvoering: van rechts naar links of van links naar rechts. Als u de volgorde van bewerkingen in een uitdrukking wilt wijzigen, moet u haakjes gebruiken, bijvoorbeeld (x + y) * z .

Een prioriteit komma-bewerkingen lager dan alle andere operaties.

In de volgende tabel worden de C++-taalbewerkingen weergegeven in aflopende volgorde van prioriteit. Bewerkingen met verschillende prioriteiten worden gescheiden door een lijn.

Prioriteitstabel voor bewerkingen

Operatie tekenen

Namen van bewerkingen

Uitvoeringsbevel

prioriteit verhogen

postfix-verhoging

postfix-verlaging

van links naar rechts

De grootte van

( type ) expressie en

type (uitdrukking)

operandgrootte in bytes

verhoging van het voorvoegsel

voorvoegsel verlagen

bitsgewijs N E

logisch NIET

unaire min, plus

soort conversie

rechts links

vermenigvuldiging

rest na deling van gehele getallen

van links naar rechts

toevoeging

aftrekken

van links naar rechts

naar links verschuiven

naar rechts verschuiven

van links naar rechts

minder of gelijk

meer of gelijk

van links naar rechts

van links naar rechts

bitsgewijs EN

van links naar rechts

bitgewijs exclusief OF

van links naar rechts

bitsgewijs OF

van links naar rechts

logisch EN

van links naar rechts

logisch OF

van links naar rechts

? :

voorwaardelijk

rechts links

*= , /= , %=

+= , - =

<<= , >>=

&= , |= , ^=

opdracht (eenvoudig en

verbinding)

rechts links

komma-bewerking

van links naar rechts

Type gieten

Programmeertaal C++, omdat het een getypte taal is, kunt u toch heel vrijelijk omgaan met expressies die op verschillende gegevenstypen werken. In dit geval worden de operanden van de expressie omgezet naar een algemeen type.

Alleen conversies die operanden met een kleiner waardenbereik omzetten naar operanden met een groter waardenbereik worden automatisch uitgevoerd, aangezien dit gebeurt zonder enig informatieverlies. Bijvoorbeeld als in de uitdrukking ival + fval variabel ival type int en de variabele Fval– typen vlot , en vervolgens bij het uitvoeren activiteiten(+ ) variabele waarde ival wordt naar type gegoten vlot .

Expressies waarbij mogelijk informatie verloren gaat, zoals bij het toewijzen van lange gehele getallen aan kortere of reële gehele getallen, kunnen waarschuwingen opleveren, maar ze zijn geldig (zie toewijzingsoperator).

Voor elke expressie kunt u expliciet een conversie van het betreffende type opgeven met behulp van een unaire operator genaamd brengen (door transformatie) type . De bewerking kan in twee formaten worden geschreven:

(type) uitdrukking

type(uitdrukking)

Operand activiteitensoort casts is de uitdrukking die moet worden geconverteerd. Een prioriteit type cast-bewerkingen hetzelfde als andere unaire operaties. Bijvoorbeeld: (langdubbele) 5; (int) F ; (dubbele) een/2 .

Als de uitdrukking in kwestie een vrij complexe vorm heeft, is het raadzaam om deze tussen haakjes te plaatsen om er zeker van te zijn dat het type resultaat van de gehele uitdrukking wordt gewijzigd, en niet slechts een deel ervan. Bijvoorbeeld,

(int) x + b * c

(int) (x + b * c )

In het eerste geval is de transformatie relatief ten opzichte van de variabele X , in de tweede – voor de hele uitdrukking X+b*c.

Prioriteit en uitvoeringsvolgorde

De prioriteit en associativiteit van C-operatoren beïnvloeden de volgorde waarin operanden worden gegroepeerd en bewerkingen worden geëvalueerd in een expressie. De prioriteit van operaties is alleen relevant als er meerdere operaties zijn met verschillende prioriteiten. Expressies met operatoren met een hogere prioriteit worden eerst geëvalueerd.

Tabel 4.1 geeft een overzicht van de handelingen in afnemende volgorde van prioriteit. Bewerkingen die zich in dezelfde tabelrij bevinden of in één groep zijn gecombineerd, hebben dezelfde prioriteit en dezelfde associativiteit.

Tabel 4.1.

Voorrang en associativiteit van bewerkingen in de C-taal

Operatie teken Naam Associativiteit
() . -> Primair Van links naar rechts
+ - ~! * & ++ -- grootte van typecast Unair Van rechts naar links
* / % Multiplicatief Van links naar rechts
+ - Additief Van links naar rechts
>> << Verschuiving Van links naar rechts
< > <= >= Houding Van links naar rechts
== != Houding Van links naar rechts
& Bitsgewijs EN Van links naar rechts
^ Bitwise exclusief OR Van links naar rechts
| Bitsgewijze inclusief OR Van links naar rechts
&& Logisch EN Van links naar rechts
|| Logische OF Van links naar rechts
?: Voorwaardelijk Van rechts naar links
= *= /= %= += -= <<= >>= &= |= ^= Eenvoudige en samengestelde opdracht Van rechts naar links
, Sequentiële berekening Van links naar rechts

Uit tabel 4.1. Hieruit volgt dat de operanden die de functieaanroep, de indexexpressie, de elementselectie-expressie en de expressie tussen haakjes vertegenwoordigen, de hoogste prioriteit en associativiteit van links naar rechts hebben. Type casting heeft dezelfde prioriteit en uitvoeringsvolgorde als unaire bewerkingen.

Een expressie kan meerdere bewerkingen met dezelfde prioriteit bevatten. Wanneer meerdere operators met hetzelfde prioriteitsniveau in een uitdrukking voorkomen, worden deze toegepast op basis van hun associativiteit: van rechts naar links of van links naar rechts.

Opgemerkt moet worden dat de C-taal voor sommige bewerkingen een ongelukkige prioriteitsvolgorde aanneemt, met name voor de shift- en bitsgewijze bewerkingen. Ze hebben een lagere prioriteit dan rekenkundige bewerkingen (optellen, enz.). Daarom de uitdrukking

a = b & 0xFF + 5

berekend als

a = b & (0xFF + 5),

en de uitdrukking

a+c >> 1

berekend als

(a + c) >> 1

Multiplicatieve, additieve en bitsgewijze bewerkingen hebben de eigenschap van commutativiteit. Dit betekent dat het resultaat van het evalueren van een uitdrukking die meerdere commutatieve bewerkingen met dezelfde prioriteit omvat, niet afhangt van de volgorde waarin deze bewerkingen worden uitgevoerd. Daarom behoudt de compiler zich het recht voor om dergelijke expressies in elke volgorde te evalueren, zelfs als de expressie haakjes bevat die de volgorde van evaluatie specificeren.

SP TS implementeert de unaire plus-bewerking, waarmee u de volgorde van berekening van uitdrukkingen tussen haakjes kunt garanderen.

De sequentiële evaluatiebewerking, de logische EN- en OF-bewerkingen, de voorwaardelijke bewerking en de functieaanroepbewerking garanderen een specifieke volgorde waarin hun operanden worden geëvalueerd. Een sequentiële evaluatiebewerking zorgt ervoor dat de operanden achtereenvolgens worden geëvalueerd, van links naar rechts (een komma die argumenten scheidt in een functieaanroep is geen sequentiële evaluatiebewerking en biedt dergelijke garanties niet). Het is alleen gegarandeerd dat tegen de tijd dat de functie wordt aangeroepen, alle argumenten al zijn berekend.

Een voorwaardelijke bewerking evalueert eerst de eerste operand en vervolgens, afhankelijk van de waarde, de tweede of derde.

Logische bewerkingen evalueren hun operanden ook van links naar rechts. Bij logische bewerkingen wordt echter het minimumaantal operanden geëvalueerd dat nodig is om het resultaat van een expressie te bepalen. Het is dus mogelijk dat de tweede operand van de expressie helemaal niet wordt geëvalueerd.

int x, y, z, f();

z = x > y || f(x, y);

Eerst wordt de uitdrukking x>y berekend. Als dit waar is, krijgt de variabele z de waarde 1 en wordt de functie f niet aangeroepen. Als de waarde van x niet groter is dan y, wordt de uitdrukking f(x,y) berekend. Als de functie f een waarde teruggeeft die niet nul is, krijgt de variabele z de waarde 1, anders 0. Merk ook op dat bij het aanroepen van de functie f gegarandeerd is dat de waarde van het eerste argument groter is dan de tweede.

Het beschouwde voorbeeld toont de belangrijkste mogelijkheden om de volgorde van uitvoering van logische bewerkingen te gebruiken. Dit is in de eerste plaats een verhoging van de efficiëntie door de meest waarschijnlijke omstandigheden als de eerste operanden van logische bewerkingen te plaatsen. Ten tweede is het mogelijk om controles in een expressie in te voegen. Als deze onwaar zijn, worden daaropvolgende acties niet uitgevoerd. Dus in de volgende voorwaardelijke verklaring als het lezen van het volgende teken uit het bestand wordt alleen uitgevoerd als het einde van het bestand nog niet is bereikt:

als(!feof(pf)) && (c = getc(pf)) ...

Hier feof- einde-bestandscontrolefunctie, krijgc- functie voor het lezen van een symbool uit een bestand (zie paragraaf 12).

Ten derde kunnen we dat in de uitdrukking garanderen f(x)&&g(y) functie F wordt vóór de functie aangeroepen G. Voor expressie f(x)+g(y) Dit kan niet gezegd worden.

De volgende voorbeelden tonen de groepering van operanden voor verschillende expressies.

Uitdrukking Operandgroepering
a&b || C (a en b) || C
a = b || C een = (b || c)
q && r || S-- (q && r) || (S--)
p == 0 ? p+= 1: p+= 2 (p == 0 ? p += 1: p) += 2

In het eerste voorbeeld heeft de bitsgewijze AND-operator (&) een hogere prioriteit dan de -logische OR-operator (||), dus de uitdrukking a&b is de eerste operand van de logische OR-bewerking.

In het tweede voorbeeld heeft de logische OR-operator (||) een hogere prioriteit dan de eenvoudige toewijzingsoperator, dus de expressie b||c vormt de rechter operand van de toewijzingsbewerking. (Merk op dat de toegewezen waarde A, is nul of één.)

Het derde voorbeeld toont een syntactisch correcte expressie die een onverwacht resultaat kan opleveren. De logische AND-operator (&&) heeft een hogere prioriteit dan de logische OR-operator (||), dus schrijven vragen&en vormt een operand. Omdat logische operatoren eerst hun linkeroperand evalueren, wordt de expressie vragen&en wordt vooraf berekend S--. Echter, als vragen&en geeft dan een waarde die niet nul is S-- wordt niet berekend en S wordt niet verlaagd. Het zou betrouwbaarder zijn om te plaatsen S-- in plaats van de eerste operand van de uitdrukking of verlaging S een aparte operatie.

In het vierde voorbeeld ziet u een ongeldige expressie die een compilatiefout veroorzaakt. De gelijkheidsoperator (==) heeft dus de hoogste prioriteit p==0 gegroepeerd in een operand. Ternaire operatie ?: heeft de volgende prioriteit. De eerste operand is de uitdrukking p==0, de tweede operand is de uitdrukking p+=1. Er wordt echter rekening gehouden met de laatste operand van een ternaire operatie P, maar niet p+=2. sinds in in dit geval identificatie P in termen van operatorprioriteit is het nauwer verwant aan de ternaire operator dan aan de samengestelde bewerking van optellen met toewijzing. Als gevolg hiervan ontstaat er syntax error, omdat de linkeroperand van een samengestelde toewijzingsbewerking geen L-expressie is.

Om dit soort fouten te voorkomen en om het programma duidelijker te maken, is het aan te raden om haakjes te gebruiken. Het vorige voorbeeld kan als volgt correct worden opgemaakt:

(p== 0) ? (p+= 1) : (p+= 2)

Uit het boek EMBEDDED SYSTEMS SOFTWARE. Algemene vereisten tot ontwikkeling en documentatie auteur Gosstandart van Rusland

Uit het Delphi-boek. Leren door het goede voorbeeld te geven auteur Parizjski Sergej Michajlovitsj

Uitvoeringsvolgorde van uitspraken B complexe uitdrukkingen de instructies worden in de volgende volgorde uitgevoerd: 1. ().2. niet.3. *, /, div, mod en, shl, shr, as.4. +, –, of, xor.5. =,<>, <, >, <=, >=,in,

Uit het boek Windows Script Host voor Windows 2000/XP auteur Popov Andrej Vladimirovitsj

De volgorde van uitvoering van de operatoren in de tabel. A1.10 JScript-taaloperatoren zijn gerangschikt in volgorde van prioriteit, d.w.z. bij samengestelde instructies worden de instructies hierboven in deze tabel als eerste uitgevoerd. Als operators zich in één rij van de tabel bevinden, worden ze vanaf de linkerkant uitgevoerd

Uit het boek UNIX: Procescommunicatie auteur Stefanus Willem Richard

9.6. Prioriteit voor lezen en schrijven Onze implementatie van lees-schrijfvergrendelingen in Paragraaf 8.4 gaf prioriteit aan processen die wachtten om te schrijven. Nu zullen we de details bestuderen mogelijke oplossing voert taken uit aan lezers en schrijvers met behulp van fcntl-recordblokkering. Ik zou graag willen weten hoe

Uit het boek TCP/IP Architecture, Protocols, Implementation (inclusief IP versie 6 en IP Security) door Faith Sydney M

6.13.4 Prioriteit en type dienst De oorspronkelijke sponsor van de TCP/IP-protocolsuite was het Amerikaanse ministerie van Defensie, waarvoor prioriteitstelling van datagrammen belangrijk was. Prioriteiten worden weinig gebruikt buiten militaire en overheidsorganisaties. Voor prioriteit

Uit het boek HTML 5, CSS 3 en Web 2.0. Ontwikkeling van moderne websites. auteur Dronov Vladimir

22.6.1 Prioriteit Het veld Prioriteit heeft twee doelen. Bij belastingcontrole voor TCP-verkeer komen hogere getallen overeen met controlepakketten en interactief verkeer, en lagere getallen met normaal verkeer. De volgende waarden zijn gedefinieerd: 0 Verkeer is niet gespecificeerd 1 Filler

Uit het boek HTML 5, CSS 3 en Web 2.0. Ontwikkeling van moderne websites auteur Dronov Vladimir

Uit het boek QNX/UNIX [Anatomie van gelijktijdigheid] auteur Tsilurik Oleg Ivanovitsj

Voorrang van operators Het laatste punt dat we hier bespreken is de prioriteit van operators. Zoals we ons herinneren, beïnvloedt prioriteit de volgorde waarin de operatoren in een expressie worden uitgevoerd. Stel dat er de volgende expressie is: a = b + c - 10. Open in dit geval eerst de waarde van de variabele b

Uit het boek Firebird DATABASE DEVELOPER'S GUIDE van Borri Helen

Prioriteit Misschien wel het meest gebruikelijke om opnieuw te definiëren is de prioriteit waarmee de gemaakte thread zal worden uitgevoerd. Wanneer een thread wordt gestart met standaardparameters, wordt de prioriteit ervan ingesteld op de prioriteit van de bovenliggende thread. Opmerking Bij het starten

Uit het boek The C Language - Een gids voor beginners van Prata Steven

Operatorprioriteit Prioriteit bepaalt de volgorde waarin operators en de waarden die ze produceren in een expressie worden geëvalueerd. Wanneer een expressie meerdere operators van hetzelfde type bevat, worden de operators van links naar rechts geëvalueerd, tenzij er een conflict is.

Uit het C++-boek voor beginners van Lippman Stanley

De volgorde van de bewerkingen Laten we eens kijken volgende regel: boter = 25,0 + 60,0 * n / SCHAAL; Deze operator bevat bewerkingen voor optellen, vermenigvuldigen en delen. Welke operatie wordt als eerste uitgevoerd? Zou 25,0 worden opgeteld bij 60,0, dan wordt het resultaat van 85,0 vermenigvuldigd met n, en het product

Uit het boek Ontwikkeling Linux-kernels van Liefde Robert

1.2.1. Uitvoeringsvolgorde van instructies Standaard worden programma-instructies na elkaar en opeenvolgend uitgevoerd. In het programma int main())(readIn();sort();compact();print();return 0;)wordt eerst de readIn() instructie uitgevoerd, gevolgd door sort(), compact() en ten slotte print(). Laten we ons echter een situatie voorstellen waarin

Uit het boek Beschrijving van de PascalABC.NET-taal auteur RuBoard-team

Procesprioriteit Het meest gebruikte type planningsalgoritme is op prioriteit gebaseerde planning. Het idee is om de processen te ordenen op basis van hun belang en gebruiksbehoefte

Uit het boek van de auteur

Barrières en uitvoeringsvolgorde In het geval dat het nodig is om met synchronisatie tussen verschillende verwerkers of verschillende hardwareapparaten, soms is het vereist dat het lezen (laden) of schrijven (opslaan) van het geheugen in dezelfde volgorde wordt uitgevoerd als deze

Uit het boek van de auteur

De volgorde van de bewerkingen die door de processor worden uitgevoerd. Denk aan Hoofdstuk 9, “Synchronisatiehulpmiddelen in de kernel”, dat voor verschillende hardwareplatforms processors in op verschillende niveaus de volgorde van uitvoering wijzigen programma instructies. Voor sommige verwerkers is dit de uitvoeringsvolgorde

Uit het boek van de auteur

Operatorprioriteit Prioriteit bepaalt de volgorde waarin de bewerkingen in een expressie worden uitgevoerd. Bewerkingen met de hoogste prioriteit worden als eerste uitgevoerd. Bewerkingen met dezelfde prioriteit worden van links naar rechts uitgevoerd. Operatieprioriteittabel @, not, ^, +, - (unair), nieuw 1