Priorita aritmetických operácií. Aritmetické výrazy

Na správne vyhodnotenie výrazov (napríklad 4 + 2 * 3) potrebujeme vedieť, ktoré operátory čo robia a v akom poradí sa vykonávajú. Postupnosť, v ktorej sa vykonávajú, sa nazýva prioritou operácií. Podľa obvyklých pravidiel matematiky (v ktorých násobenie prichádza pred sčítaním) sa vyššie uvedený výraz spracuje takto: 4 + (2 * 3) = 10.

V C++ majú všetky operátory (operácie) svoju vlastnú úroveň priority. Tie, v ktorých je vyššia, sú popravené ako prvé. V tabuľke nižšie vidíte, že priorita operácií násobenia a delenia (5) je vyššia ako priorita operácií sčítania a odčítania (6). Kompilátor používa prioritu operátorov na určenie poradia, v ktorom sa výrazy spracúvajú.

Čo ak však dva operátory vo výraze majú rovnakú úroveň priority a sú umiestnené vedľa seba? Ktorú operáciu vykoná kompilátor ako prvú? A tu kompilátor použije pravidlá asociatívnosti, ktoré označujú smer operácií: zľava doprava alebo sprava doľava. Napríklad v 3 * 4 / 2 majú operácie násobenia a delenia rovnakú úroveň priority (5). A asociativita úrovne 5 = zľava doprava: (3 * 4) / 2 = 6.

Tabuľka priority a asociatívnosti operácií

Pár poznámok:

1 je najvyššia úroveň priority a 17 je najnižšia. Operácie s vyššou prioritou sa vykonajú ako prvé.

L -> R znamená zľava doprava.

R -> L znamená sprava doľava.

Asociativita Operátor Popis Príklad
1. Nie :: Globálny rozsah (unárny) ::názov
:: Rozsah triedy (binárny) class_name::meno_člena
2. L -> R () Okrúhle zátvorky (výraz)
() Volanie funkcie názov_funkcie (parametre)
() Inicializácia typ meno (výraz)
{} jednotná inicializácia (C++11) typ meno (výraz)
typ() Konverzia typu nový_typ (výraz)
typ() Konverzia typu (C++11) nový_typ (výraz)
Index poľa ukazovateľ
. Prístup k objektovému členovi objekt.meno_člena
-> Prístup k členovi objektu cez ukazovateľ object_pointer->member_name
++ Po prírastku lvalue++
–– Po znížení lvalue––
typid Informácie o type spustenia typid(typ) alebo typid(výraz)
const_cast Odhodiť konšt const_cast(výraz)
dynamic_cast Typovo skontrolované odovzdanie za behu dynamic_cast(výraz)
reinterpret_cast Konverzia jedného typu na druhý reinterpret_cast(výraz)
static_cast Typovo skontrolované pretypovanie v čase kompilácie static_cast(výraz)
3. R -> L + Unárne plus +výraz
Unárne mínus -výraz
++ Predprírastok ++lhodnota
–– Predbežné zníženie ––hodnota
! Logické NIE (NIE) !výraz
~ Bitové NIE (NIE) ~výraz
(typ) Obsadenie v štýle C (nový_typ)výraz
veľkosť Veľkosť v bajtoch sizeof(type) alebo sizeof(expression)
& Adresa &lhodnota
* Dereference *výraz
Nový Dynamická alokácia pamäte nový typ
Nový Dynamická alokácia poľa nový typ
vymazať Dynamické odstránenie pamäte vymazať ukazovateľ
vymazať Dynamické vymazanie poľa vymazať ukazovateľ
4. L -> R ->* Selektor ukazovateľa člena object_pointer->*pointer_to_member
.* Selektor objektu člena objekt.*ukazovateľ_členovi
5. L -> R * Násobenie výraz * výraz
/ divízie výraz / výraz
% Zvyšok výraz % výraz
6. L -> R + Doplnenie výraz + výraz
Odčítanie výraz — výraz
7. L -> R << Bitový posun doľava výraz<< expression
>> Bitový posun doprava výraz >> výraz
8. L -> R < Porovnanie: menej ako výraz< expression
<= Porovnanie: menšie alebo rovnaké výraz<= expression
> Porovnanie: viac ako výraz > výraz
>= Porovnanie: väčšie alebo rovné výraz >= výraz
9. L -> R == Rovná sa výraz == výraz
!= Nerovná sa výraz != výraz
10. L -> R & Bitové AND výraz & výraz
11. L -> R ^ Bitové exkluzívne OR (XOR) výraz ^ výraz
12. L -> R | Bitové ALEBO výraz | výraz
13. L -> R && Logické AND (AND) výraz && výraz
14. L -> R || Logické ALEBO výraz || výraz
15. R -> L ?: Ternárny podmienený operátor výraz? výraz: výraz
= Pridelenie lvalue = výraz
*= Násobenie s priradením lvalue *= výraz
/= Rozdelenie s pridelením lvalue /= výraz
%= Delenie so zvyškom a pridelenie lvalue %= výraz
+= Doplnenie s priradením lvalue += výraz
-= Odčítanie s priradením lvalue -= výraz
<<= Bitové priradenie posunu doľava lvalue<<= expression
>>= Bitové priradenie posunu doprava lvalue >>= výraz
&= Priradenie pomocou bitovej operácie AND lvalue &= výraz
|= Priradenie s bitovou operáciou OR lvalue |= výraz
^= Priradenie s bitovou exkluzívnou operáciou OR (XOR). lvalue ^= výraz
16. R -> L hodiť Vyhodenie výnimky hodiť výraz
17. L -> R , Čiarka operátora výraz, výraz

Niektoré operátory už poznáte z predchádzajúcich lekcií: +, -, *, /, (), =,< и >. Ich význam je rovnaký v matematike aj v C++.

Ak však nemáte skúsenosti s inými programovacími jazykmi, potom vám väčšina týchto operátorov nemusí byť jasná. Toto je fajn. Väčšinu z nich preberieme v tejto kapitole a zvyšok prikryjeme podľa potreby.

Táto tabuľka je určená predovšetkým na to, aby ste sa na ňu mohli kedykoľvek odvolať pri riešení prípadných problémov s prioritou alebo asociatívnosťou.

Ako zvýšiť číslo na mocninu v C++?

Už ste si mali všimnúť, že operátor ^, ktorý sa bežne používa na vyjadrenie umocňovania v bežnej matematike, nie je v C++. V C++ ide o bitovú operáciu XOR. A na zvýšenie čísla na mocninu v C++ použite funkciu pow(), ktorá sa nachádza v cmath:

#include double x = pow(3,0; 4,0); // 3 na 4

#include

double x = pow (3,0, 4,0); // 3 na 4

Upozorňujeme, že parametre a návratové hodnoty funkcie pow() sú typu double. A keďže sú známe chyby zaokrúhľovania, výsledky pow() môžu byť mierne nepresné (o niečo menej alebo o niečo viac).

Ak potrebujete zvýšiť celé číslo na mocninu, je lepšie použiť vlastnú funkciu, napríklad:

// Poznámka: exponent nesmie byť záporný int pow(int základ, int exp) ( int výsledok = 1; while (exp) ( if (exp & 1) výsledok *= základ; exp >>= 1; základ *= základ;) vrátiť výsledok;)

// Poznámka: exponent nesmie byť záporný

int pow (int základ, int exp)

int vysledok = 1 ;

zatiaľ čo (exp)

ak (exp & 1)

vysledok * = zaklad ;

exp >> = 1 ;

základ * = základ ;

vrátiť výsledok;

Nerobte si starosti, ak tu niečo nie je jasné. Len si uvedomte problém s pretečením, ktorý môže nastať, ak je jeden z argumentov príliš veľký.

V príkaze priraďovania aj v príkaze writeln sme použili aritmetické výrazy, za ktoré Pascal dosadil výsledky ich výpočtov. Aritmetický výraz pozostáva z konštánt, premenných a funkcií spojených znamienkami aritmetických operácií.

Aritmetické operácie majú rôzne priority (prednosť). Ak výraz obsahuje operácie s rôznymi prioritami, najskôr sa vykonajú operácie s vyššou prioritou. Operácie s rovnakou prioritou sa vykonávajú v rade zľava doprava.

Obvyklý deliaci znak ( / ) v Pascale sa používa ako zlomkové delenie, to znamená, že delí reálne čísla a výsledkom delenia je reálne číslo. Aj keď 6 vydelíte 3, výsledok nebude 2, ale 2,0, teda reálne číslo. Okrem zlomkového delenia existuje aj delenie bezo zvyšku. div. Pracuje len s celými číslami a výsledkom delenia je celé číslo. Zvyšok sa ignoruje. Ak je naopak potrebný zvyšok delenia, použije sa operácia mod. Napríklad výraz 20 div 6 dáva 3 a výsledok výrazu 20 mod 6 rovná sa 2 . V týchto výrazoch nemožno vynechať medzery. Operátor mod je užitočný pri určovaní, či je jedna veličina deliteľná druhou. Ak je zvyšok delenia nula, potom sa delí bezo zvyšku.

výraz a pravidlá pre výpočet výrazu. Pravidlá sú:
  • prioritou operácie,
  • pre operácie s rovnakou prioritou postup podávania žiadostí- zľava doprava alebo sprava doľava;
  • konvertovanie typov operandov a výber implementácií pre preťažené operátory;
  • typ a hodnota výsledku vykonania operácie na daných hodnotách operandov určitého typu.

Priorita a poradie operácií

Väčšina operácií v jazyku C#, ich priorita a poradie, sú prevzaté z jazyka C++. Existujú však aj rozdiely: napríklad neexistuje žiadna operácia „ ,“, ktorá by vám umožnila vyhodnotiť zoznam výrazov; pridané kontrolované a nekontrolované operácie použiteľné pre výrazy.

Ako sa zvyčajne robí, uvádzame prioritná tabuľka operácie, v každom riadku ktorých sa zhromažďujú operácie s rovnakou prioritou, a riadky nasledujú v poradí priority, od najvyššej po najnižšiu.

Tabuľka 3.1. Priority operácií v jazyku C#
Priorita Kategória Operácie objednať
0 Primárny (výraz), x.y, x->y, f(x), a[x], x++, x--, nový, typ(t), začiarknutý (výraz), nezačiarknutý (výraz) Zľava doprava
1 Unary +, -, !, ~, ++x, --x, (T)x, sizeof(t) Zľava doprava
2 Násobenie (násobenie) *, /, % Zľava doprava
3 Aditívum (prídavok) +, - Zľava doprava
4 Shift << ,>> Zľava doprava
5 Vzťahy, typová kontrola <, >, <=, >=, je, ako Zľava doprava
6 Ekvivalencia ==, != Zľava doprava
7 Logické AND (AND) & Zľava doprava
8 Logické exkluzívne OR (XOR) ^ Zľava doprava
9 Logické ALEBO | Zľava doprava
10 Podmienené logické AND && Zľava doprava
11 Podmienené logické ALEBO || Zľava doprava
12 Podmienený výraz ? : Sprava doľava
13 Pridelenie

Lepenie s null

=, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |= Sprava doľava
14 Operátor lambda => Sprava doľava

Operácie a metódy preťaženia

Pod preťaženie prevádzky rozumie sa existencia niekoľkých implementácií tej istej operácie. Napríklad operácia „+“ sa vykonáva odlišne v závislosti od toho, či sú jej operandy celé čísla, dlhé celé čísla, celé čísla s pevnou alebo pohyblivou rádovou čiarkou alebo textové reťazce.

Musíte pochopiť, že operácie sú špeciálnym prípadom metód zaznamenávania tried. Metódy tried, podobne ako operácie, môžu byť preťažené. Zavolá sa metóda triedy preťažený, ak existuje viacero implementácií tejto metódy. Preťažené metódy majú rovnaký názov, ale musia sa líšiť podpis. Podpis metódy je zoznam typov formálnych argumentov metódy. Takže dve metódy triedy s rovnakým názvom, ale líšiace sa napríklad počtom parametrov, majú odlišný podpis a spĺňajú požiadavky na preťažené metódy.

Väčšina operátorov C# je preťažená – rovnaký operátor možno použiť na operandy rôznych typov. Preto sa pred vykonaním operácie hľadá implementácia, ktorá je vhodná pre dané typy operandov. Všimnite si, že operácie sa zvyčajne vykonávajú na operandoch rovnakého typu. Ak sú operandy rôznych typov, potom najprv implicitná konverzia typu jeden z operandov. Oba operandy môžu byť rovnakého typu, ale aj tak môže dôjsť k typovej konverzii, pretože pre dané typy neexistuje zodpovedajúci preťažený operátor. Táto situácia nastáva v praxi pomerne často, pretože napríklad operácia sčítania nie je definovaná pre nižšie podtypy aritmetického typu. Ak neexistuje vhodná implementácia operácie pre dané typy operandov a nie je možné implicitné pretypovanie typov operandov, potom sa táto chyba spravidla zistí vo fáze kompilácie.

Typ Konverzie

Každý objekt (premenná), každý operand pri vyhodnocovaní výrazu, samotný výraz je charakterizovaný dvojicou, ktorá špecifikuje hodnotu výrazu a jeho typ. V procese výpočtov často vzniká potreba konverzie typu – potreba previesť pár na pár . Pôvodný pár sa nazýva zdroj transformácie, konečný pár sa nazýva cieľ transformácie.

Potreba takýchto transformácií vzniká, ako už bolo uvedené, počas vyhodnocovania výrazu pri konverzii operandov na typ konzistentný s typom operácie. Konverzia typu je potrebná v operátoroch priraďovania, keď je typ výrazu na pravej strane operátora pretypovaný na typ určený ľavou stranou tohto operátora. Sémantika priradenia sa vyskytuje aj pri volaní metód v procese nahrádzania formálnych argumentov metódy skutočnými parametrami. A tu je potrebná konverzia typu.

Typové konverzie možno rozdeliť na bezpečné a nebezpečné. Bezpečná konverzia je konverzia, pri ktorej je zaručené, že:

Transformácia, pri ktorej nie je splnená aspoň jedna z týchto podmienok, sa nazýva nebezpečná. Postačujúcou podmienkou pre existenciu bezpečnej konverzie je napríklad podmienka, že typ je podtypom typu . V tomto prípade je akákoľvek zdrojová hodnota tiež platnou cieľovou hodnotou. Prevod z typu int na typ double je teda bezpečný. Opačná konverzia bude prirodzene nebezpečná.

Niektoré typy konverzií sa vykonávajú automaticky. Tieto konverzie sa nazývajú implicitné konverzie a sú bežné pri vyhodnocovaní výrazov. Je zrejmé, že implicitné môžu byť iba bezpečné konverzie. Akákoľvek nebezpečná transformácia musí byť výslovne špecifikovaná samotným programátorom, ktorý preberá plnú zodpovednosť za vykonanie nebezpečnej transformácie.

Existujú rôzne spôsoby vykonávania explicitných konverzií - operácia pretypovania (pretypovanie na typ), metódy špeciálnej triedy Convert, špeciálne metódy ToString, Parse. Všetky tieto metódy budú diskutované v tejto prednáške.

Vysvetlime si, ako sa pri vyhodnocovaní výrazu vykonávajú implicitné konverzie. Predpokladajme, že pri výpočte nejakého výrazu je potrebné vykonať sčítanie, kde typ je double a typ je int. Medzi mnohými implementáciami sčítania sú operácie, ktoré vykonávajú sčítanie na vnútorných operandoch a sčítanie na dvojitých operandoch, takže výber jednej z týchto implementácií sčítania bude vyžadovať konverziu typu jedného z operandov. Keďže prevod z int na double je bezpečný, ale opačný spôsob je nebezpečný, zvolí sa bezpečný prevod, ktorý sa vykoná automaticky, druhý operand sa implicitne prevedie na typ double, vykoná sa sčítanie operandov tohto typu a výsledok sčítania bude typu double.

Organizovanie softvérového projektu ConsoleExpressions

Ako vždy, všetky príklady kódu v texte sú súčasťou softvérového projektu. V tejto prednáške popíšem štruktúru konzolového projektu s názvom ConsoleExpressions. Okrem vytvorenej predvolenej triedy programu boli do projektu pridané dve triedy s názvom TestingExpressions a Scales. Každá z metód v triede TestingExpressions predstavuje test, ktorý vám umožňuje analyzovať vlastnosti operácií použitých na zostavenie výrazov, takže táto trieda je zbierkou testov. Trieda Scale je informatívna, ukazuje, ako pracovať so stupnicami, o ktorých bude reč v tejto prednáške. Aby bolo možné volať metódy týchto tried, objekty týchto tried sú deklarované a vytvorené v hlavnej procedúre triedy Program. Tieto objekty sa potom použijú ako cieľ volania príslušných metód. Všeobecná schéma hlavnej procedúry a volania metód triedy je nasledovná:

static void Main(string args) ( string answer = "Yes"; do ( try ( TestingExpressions test = new TestingExpressions(); test.Casting(); //Zavolajte iné metódy... ) catch (Exception e) ( Console. WriteLine( "Nie je možné pokračovať v normálnej práci!"); Console.WriteLine(e.Message); ) Console.WriteLine("Budeme pokračovať v práci? (Áno/Nie)"); odpoveď = Console.ReadLine(); ) while (odpoveď == "Áno" || odpoveď == "áno" || odpoveď == "áno"); )

Vždy, keď je potrebné v texte prednášky uviesť príklad kódu, uvedie sa buď úplný text volanej metódy, napríklad metóda Casting, alebo samostatný fragment metódy.

Poradie, v ktorom sa aritmetické operácie vykonávajú v aritmetickom výraze, závisí od priority týchto operácií, ktorú možno zmeniť pomocou zátvoriek.

Priority aritmetických operácií systému MATLAB v zostupnom poradí sú uvedené v tabuľke 1.5. Upozorňujeme, že priorita pri vykonávaní aritmetických operácií je normálna. Operácie s rovnakou prioritou sa vykonávajú v poradí zľava doprava. Zátvorky môžu toto poradie zmeniť) a stupeň vnorenia zátvoriek nie je obmedzený.

Tabuľka 1.5. Priorita aritmetických operácií v MATLABE.

Aritmetické výrazy.

Ústredným konceptom všetkých matematických systémov a zodpovedajúcich programovacích jazykov je aritmetický výraz (matematický výraz).

Aritmetický výraz určuje, čo sa musí vypočítať v číselnej (menej často symbolickej) forme. V tabuľke 1.6. Nižšie sú uvedené príklady najjednoduchších aritmetických výrazov napísaných podľa pravidiel systému MATLAB a podľa všeobecných matematických pravidiel.

Tabuľka 1.6. Niekoľko príkladov najjednoduchších aritmetických výrazov napísaných podľa pravidiel systému MATLAB a všeobecných matematických pravidiel.

Rozdiel je v záznamoch uvedených v tabuľke 1.6. celkom zrejmé. V systéme MATLAB sa aritmetické výrazy píšu ako jeden riadok a namiesto čiarky sa ako oddeľovač celých a zlomkových častí čísla používa bodka (a nie čiarka!). Aritmetické výrazy sú postavené na základe čísel, konštánt, premenných, operátorov a rôznych špeciálnych znakov. Špecifikom systému MATLAB je, že aritmetické výrazy sú špecifikované ako jeden riadok. Napríklad je to napísané ako 2^5. Podpíšte ";" (bodkočiarka) na konci riadku blokuje výstup výsledku výpočtu, ale systémová premenná ans umožňuje výstup výsledku výpočtu (v režime príkazového riadka):

>>2^5; >> ans =

Príklad. Musíte vypočítať nasledujúce aritmetické výrazy:

1) pri

2) pri

3) pri

4) pri

Text súboru M.



k = 2; r = 2; x = 2; y = 1; r1=abs(r)^(5*x*y)+tan(3*k) x=0,5; r2=sqrt(log(x)^2+1)+3*x^(1/3) x=1; y=2; z = 3; r3=(x+3*y)/(2*z)-3*abs(x)*exp(x+y)/(x+y)+1/(1+1/(1+1/x) ) x = 0,3; r4=sin(x/2)^3+cos(x^2)-2*cos(3*x)^(1/5)

Výsledky výpočtu v príkazovom okne:

Upozorňujeme, že ak chcete zobraziť výsledky práce operátora, použite znak „;“ nie je nainštalovaný.

Pozastavte AdBlock na tejto stránke.

V matematických výpočtoch hrá dôležitú úlohu poradie, v ktorom sa akcie vykonávajú. Akú hodnotu má napríklad výraz 2+2*2? Samozrejme, šesť, pretože... najprv sa vykoná násobenie.

C používa poradie operácií známe nám zo školy. Ale pretože Aj keď má programovanie svoje vlastné charakteristiky, stále existujú určité rozdiely. Zapíšme si prioritu pre tie operácie, ktoré už poznáme.

  • funkcie sa počítajú (napríklad sqrt() , cos() atď.)
  • násobenie, delenie, zvyšok delenia (zľava doprava)
  • sčítanie, odčítanie
  • zadanie prebieha

Aká je hodnota premennej x po vykonaní nasledujúceho kódu int x = 8 / 4 / 2;

Správna odpoveď 1. Pretože v prípade rovnakej priority operácií sa príkazy vykonávajú zľava doprava. Inými slovami, tento kód je ekvivalentný kódu int x = (8 / 4) / 2;

Ak potrebujeme zmeniť poradie vykonávania akcií, môžeme na to použiť zátvorky.

Výpis 1.

2+2*2 = 6 (2+2)*2 = 8 // akcia v zátvorke sa vykoná pred násobením

Na nasledujúcom obrázku je nad každou akciou uvedené, ako sa vykoná.

1 Priorita operácií v jazyku C. Príklad.

Ak ste vo svojom programe napísali pomerne zložitý výraz, v ktorom poradie operácií nie je okamžite jasné, potom je lepšie pridať ďalšie zátvorky, aby ste explicitne určili postupnosť operácií. Pomôže to vyhnúť sa chybám vo výpočtoch, ktoré bude neskôr ťažké zachytiť.

Zložité matematické výrazy

Niekedy môžu mať vzorce, ktoré je potrebné použiť na výpočet niečoho v programe, dosť hroznú podobu.

Navyše, keď píšeme program, akýkoľvek vzorec musí byť napísaný na jeden riadok. V počiatočnom štádiu vám to môže spôsobiť určité ťažkosti. Aby ste sa zbavili týchto ťažkostí, musíte zvládnuť zručnosť prekladu vzorca zo štandardnej matematickej notácie do tej, ktorá sa používa pri programovaní a naopak.

A krátky fragment videa, v ktorom som sa pokúsil na jednoduchom príklade ukázať, čo môžete robiť pri písaní zložitých matematických výrazov.



Zdieľajte s priateľmi alebo si uložte:

Načítava...