Si të konfiguroni telefonat inteligjentë dhe PC. Portali informativ

Veprimet matematikore c#. Shprehjet e kushtëzuara

Operatorë relacionalë dhe logjikë

Në shënim operator relacional Dhe operator logjik afati marrëdhënie nënkupton një marrëdhënie që mund të ekzistojë midis dy kuptimeve dhe termit logjike- marrëdhënia midis vlerave logjike "e vërtetë" dhe "e rreme". Dhe meqenëse operatorët relacionalë prodhojnë rezultate të vërteta ose të rreme, ata shpesh përdoren së bashku me operatorët logjikë. Është për këtë arsye që ato konsiderohen së bashku.

Më poshtë janë operatorët relacionalë:

Operatorët logjikë përfshijnë si më poshtë:

Rezultati i ekzekutimit të një operatori relacional ose logjik është një vlerë Boolean e tipit bool.

Në përgjithësi, objektet mund të krahasohen për barazi ose pabarazi duke përdorur operatorët relacionalë == dhe !=. Dhe operatorët e krahasimit, = mund të aplikohen vetëm për llojet e të dhënave që mbështesin relacionin e rendit. Prandaj, operatorët relacionalë mund të aplikohen për të gjitha llojet e të dhënave numerike. Por vlerat bool mund të krahasohen vetëm për barazi ose pabarazi, pasi vlerat e vërteta dhe të rreme nuk renditen. Për shembull, krahasimi true > false në C# nuk ka kuptim.

Le të shohim një shembull programi që demonstron përdorimin e operatorëve relacionalë dhe logjikë:

Përdorimi i Sistemit; duke përdorur System.Collections.Generic; duke përdorur System.Linq; duke përdorur System.Text; hapësira e emrave ConsoleApplication1 ( Programi i klasës ( zbrazëti statike Main (string args) ( i shkurtër d = 10, f = 12; bool var1 = i vërtetë, var2 = false; nëse (d f) Console.WriteLine ("d > f"); // Krahasimi variablat var1 dhe var2 if (var1 & var2) Console.WriteLine ("Ky tekst nuk do të printohet"); nëse (!(var1 & var2)) Console.WriteLine ("!(var1 & var2) = i vërtetë"); nëse (var1 | var2) Console.WriteLine("var1 | var2 = true"); if (var1 ^ var2) Console.WriteLine("var1 ^ var2 = true"); Console.ReadLine(); ) )

Operatorët logjikë në C# kryejnë operacionet logjike më të zakonshme. Sidoqoftë, ka një sërë operacionesh të kryera sipas rregullave të logjikës formale. Këto operacione logjike mund të ndërtohen duke përdorur operatorët logjikë të mbështetur në C#. Rrjedhimisht, C# ofron një grup operatorësh logjikë që janë të mjaftueshëm për të ndërtuar pothuajse çdo operacion logjik, duke përfshirë implikimin. Implikimiështë një operacion binar, rezultati i të cilit është fals vetëm nëse operandi i tij i majtë ka kuptimin e vërtetë, dhe e drejta është e rreme. (Operacioni i nënkuptimit pasqyron parimin e mëposhtëm: e vërteta nuk mund të nënkuptojë gënjeshtrën.)

Operacioni i nënkuptimit mund të ndërtohet bazuar në një kombinim të operatorëve logjikë! dhe |:

Operatorë logjikë të shkurtuar

C# gjithashtu ofron speciale i shkurtuar, variante të operatorëve logjikë AND dhe OR, të dizajnuara për të prodhuar kode më efikase. Le ta shpjegojmë këtë në shembujt e mëposhtëm operacionet logjike. Nëse operandi i parë i një operacioni logjik AND është false, atëherë rezultati i tij do të jetë fals pavarësisht nga vlera e operandit të dytë. Nëse operandi i parë i një operacioni logjik OR është i vërtetë, atëherë rezultati i tij do të jetë i vërtetë pavarësisht nga vlera e operandit të dytë. Për shkak të faktit se vlera e operandit të dytë në këto operacione nuk ka nevojë të llogaritet, kursen kohë dhe rrit efikasitetin e kodit.

Operacioni i shkurtuar logjik DHE kryhet duke përdorur operator &&, dhe operacioni i shkurtuar logjik OSE kryhet duke përdorur operatori ||. Këta operatorë logjikë të shkurtuar korrespondojnë me operatorët e rregullt logjik & dhe |. I vetmi ndryshim midis një operatori logjik të shkurtuar dhe atij të rregullt është se operandi i tij i dytë vlerësohet vetëm sipas nevojës.

Përditësimi i fundit: 19.06.2017

C# përdor shumicën e operacioneve që përdoren në gjuhë të tjera programimi. Operacionet paraqesin veprime specifike mbi operandët - pjesëmarrës në operacion. Operandi mund të jetë një ndryshore ose ndonjë vlerë (për shembull, një numër). Operacionet mund të jenë unare (të kryera në një operand), binar - në dy operandë dhe tresh - të kryera në tre operandë. Le të shqyrtojmë të gjitha llojet e operacioneve.

Veprimet aritmetike binare:

    Operacioni i mbledhjes së dy numrave:

    Int x = 10; int z = x + 12; // 22

    Operacioni i zbritjes së dy numrave:

    Int x = 10; int z = x - 6; // 4

    Operacioni i shumëzimit të dy numrave:

    Int x = 10; int z = x * 5; // 50

    Operacioni i pjesëtimit të dy numrave:

    Int x = 10; int z = x / 5; // 2 dyfishtë a = 10; dyfishtë b = 3; dyfishtë c = a / b; // 3.33333333

    Gjatë ndarjes, vlen të merret parasysh që nëse të dy operandët përfaqësojnë numra të plotë, atëherë rezultati gjithashtu do të rrumbullakoset në një numër të plotë:

    Dyfishtë z = 10 / 4; //rezultati është 2

    Edhe pse rezultati i operacionit vendoset përfundimisht në një variabël shkruani dyfish, e cila ju lejon të ruani pjesën e pjesshme, por vetë operacioni përfshin dy fjalë për fjalë, të cilat si parazgjedhje trajtohen si objekte int, domethënë numra të plotë, dhe rezultati do të jetë gjithashtu një numër i plotë.

    Për të dalë nga kjo situatë, është e nevojshme të përcaktohen literalet ose variablat e përfshirë në operacion si lloje të dyfishta ose float:

    Z dyfishtë = 10.0 / 4.0; //rezultati është 2.5

    Operacioni që merr bilancin nga ndarja e numrave të plotë dy numra:

    Dyfishtë x = 10.0; dyfishi z = x % 4,0; //rezultati është 2

Ka edhe një numër operacionet unare, në të cilin një operand merr pjesë:

    Operacioni në rritje

    Rritja mund të parashtesohet: ++x - fillimisht vlera e ndryshores x rritet me 1, dhe më pas vlera e saj kthehet si rezultat i operacionit.

    Dhe ka gjithashtu një rritje postfiks: x++ - së pari vlera e ndryshores x kthehet si rezultat i operacionit, dhe më pas i shtohet 1.

int x1 = 5; int z1 = ++x1; // z1=6; x1=6 Console.WriteLine($"(x1) - (z1)"); int x2 = 5; int z2 = x2++; // z2=5; x2=6 Console.WriteLine($"(x2) - (z2)");

Operacioni i zvogëlimit ose zvogëlimit të një vlere me një. Ekziston gjithashtu një formë parashtese e zvogëlimit (--x) dhe një formë pasfiksore (x--).

Int x1 = 5; int z1 = --x1; // z1=4; x1=4 Console.WriteLine($"(x1) - (z1)"); int x2 = 5; int z2 = x2--; // z2=5; x2=4 Console.WriteLine($"(x2) - (z2)");

Gjatë kryerjes së disa veprimeve aritmetike në të njëjtën kohë, duhet të merret parasysh radha në të cilën ato kryhen. Prioriteti i funksionimit nga më i larti tek më i ulëti:

    Rritje, pakësim

    Shumëzim, pjesëtim, mbetje

    Mbledhja, zbritja

Për të ndryshuar rendin e veprimeve, përdoren kllapa.

Konsideroni një grup operacionesh:

Int a = 3; int b = 5; int c = 40; int d = c---b*a; // a=3 b=5 c=39 d=25 Konsola.WriteLine($"a=(a) b=(b) c=(c) d=(d)");

Këtu kemi të bëjmë me tre veprime: zvogëlim, zbritje dhe shumëzim. Së pari, ndryshorja c zvogëlohet, pastaj b*a shumëzohet dhe në fund zbritet. Kjo është, në fakt, grupi i operacioneve dukej kështu:

Int d = (c--)-(b*a);

Por me ndihmën e kllapave mund të ndryshojmë rendin e veprimeve, për shembull si kjo:

Int a = 3; int b = 5; int c = 40; int d = (c-(--b))*a; // a=3 b=4 c=40 d=108 Konsola.WriteLine($"a=(a) b=(b) c=(c) d=(d)");

Asociacioni i operatorëve

Siç u përmend më lart, operacionet e shumëzimit dhe pjesëtimit kanë të njëjtin përparësi, por cili do të jetë rezultati në shprehjen:

Int x = 10 / 5 * 2;

A duhet ta interpretojmë këtë shprehje si (10 / 5) * 2 apo si 10 / (5 * 2)? Në fund të fundit, në varësi të interpretimit, do të marrim rezultate të ndryshme.

Kur operacionet kanë të njëjtin prioritet, radha e vlerësimit përcaktohet nga shoqata e operatorëve. Në varësi të asociativitetit, ekzistojnë dy lloje operatorësh:

    Operatorët asociativë të majtë, të cilët ekzekutohen nga e majta në të djathtë

    Operatorët shoqërues të djathtë, të cilët ekzekutohen nga e djathta në të majtë

Të gjitha operatorët aritmetikë(me përjashtim të rritjes dhe zvogëlimit të parashtesave) janë asociative majtas, domethënë ekzekutohen nga e majta në të djathtë. Prandaj, shprehja 10 / 5 * 2 duhet të interpretohet si (10 / 5) * 2, domethënë, rezultati do të jetë 4.

Në gjuhën C#, nuk ka konvertime të nënkuptuara në llojin Boolean, madje edhe për llojet aritmetike me numra të plotë. Prandaj, një hyrje plotësisht e saktë në C++ është:

ndërk1 = 7;
nëse (k1) Konsol. WriteLine(" Ne rregull!");

Ilegale në programet C#. Një gabim do të ndodhë gjatë fazës së përkthimit sepse kushti i vlerësuar është i llojit ndër, dhe shndërrimi i nënkuptuar i këtij lloji në tip bool mungon.

Në C#, rregulla më të rrepta zbatohen edhe për operatorët logjikë. Po, regjistro nëse(k1 && (x> y)), korrekt në C++, çon në një gabim në

programet në C#, pasi operatori && është përcaktuar vetëm për operandët e tipit bool, dhe në këtë shprehje njëri nga operandët është i tipit ndër. Në C#, në këto situata duhet të përdorni hyrjet e mëposhtme:

nëse(k1>0)
nëse((k1>0) && (x> y))

Operacionet logjike ndahen në dy kategori: disa kryhen në vlerat logjike të operandëve, ndërsa të tjerët kryejnë një operacion logjik në bitet e operandëve. Për këtë arsye, ekzistojnë dy operatorë unarë të mohimit në C# - mohimi logjik, i specifikuar nga operatori "!", dhe mohimi bit, i specifikuar nga operatori "~". E para prej tyre përcaktohet mbi një operand të tipit bool, e dyta - mbi operandin e një tipi numër të plotë, duke filluar me llojin ndër dhe më lart (ndër, unint, gjatë, gjatë). Rezultati i operacionit në rastin e dytë është një operand në të cilin çdo bit zëvendësohet nga plotësuesi i tij. Ja një shembull:

/// < përmbledhje>
/// Shprehje logjike
/// përmbledhje>
publikei pavlefshëmLogjika() {
//operacionet mohuese ~, !
bool b1, b2;
b1= 2*2 == 4;
b2= !b1;
//b2= ~b1;
uint j1= 7, j2;
j2= ~j1;
//j2= !j1;
int j4= 7, j5;
j5= ~ j4;
Console.WriteLine("uint j2= " + j2+ " int j5= " + j5);
} // Logjika

Ky fragment komenton deklaratat që shkaktojnë gabime. Në rastin e parë, u bë një përpjekje për të aplikuar operacionin e mohimit bit në një shprehje si bool, në të dytën, mohimi logjik u aplikua për të dhënat e numrave të plotë. Të dyja janë të paligjshme në C#. Vini re interpretimin e ndryshëm të mohimit bit për llojet e numrave të plotë të panënshkruar dhe të nënshkruar. Për variablat j5 Dhe j2 vargu i biteve që specifikon vlerën është i njëjtë, por interpretohet ndryshe. Prodhimi përkatës është:

unintj2 = 4294967288
ndërj5 = -8.

Operacionet logjike binare " && - të kushtëzuara AND" dhe " || - OR me kusht" përcaktohen vetëm mbi llojin e të dhënave bool. Veprimet quhen të kushtëzuara ose stenografi sepse vlerësimi i operandit të dytë varet nga vlera tashmë e vlerësuar e operandit të parë. Vlera e operacioneve logjike të kushtëzuara qëndron në efikasitetin e tyre në kohën e ekzekutimit. Shpesh ata ju lejojnë të llogaritni shprehje logjike, e cila ka kuptim, por në të cilën operandi i dytë është i papërcaktuar. Le të marrim si shembull problemin klasik të kërkimit sipas modelit në një grup, kur kërkohet një element me një vlerë (model) të caktuar. Mund të ketë ose jo një element të tillë në grup. Këtu është një zgjidhje tipike për këtë problem në një formë të thjeshtuar, por duke përcjellë thelbin e çështjes:

// E kushtëzuarDhe- &&
ndër[] ar= { 1, 2, 3 };
int search= 7;
int i= 0;
nderkohe une< ar.Gjatësia)&& (ar[i]!= kërko)){
i++;
}
nese une< ar.Gjatësia)Console.WriteLine("Mostragjetur");
tjetërConsole.WriteLine("MostraJogjetur");

Nëse vlera e ndryshores kërkimi(kampion) nuk përputhet me asnjë nga vlerat e elementit të grupit ar, pastaj kontrolli i fundit i gjendjes së ciklit derisa do të ekzekutohet kur vlera i, të barabartë ar. Gjatësia. Në këtë rast, operandi i parë do të marrë vlerën i rremë, dhe, megjithëse operandi i dytë është i papërcaktuar, cikli do të përfundojë normalisht. Operandi i dytë nuk është përcaktuar në kontrolli i fundit, sepse indeksi i elementit të grupit është jashtë rrezes (në C#, indeksimi i elementeve fillon nga zero).

Tre binare operacionet bitwise- "& - DHE" , " | -OR", "^-XOR" përdoren në dy mënyra. Ato përcaktohen si më sipër llojet e numrave të plotë më sipër ndër, dhe mbi tipat Boolean. Në rastin e parë ato përdoren si operacione bitwise, në të dytin - si operacione të zakonshme logjike. Ndonjëherë është e nevojshme që të dy operandët të vlerësohen në çdo rast, atëherë këto operacione nuk mund të shmangen. Këtu është një shembull i përdorimit të tyre të parë:

//Operacionet logjike bitwiseDhe, Ose, XOR(&,|,^)
int k2= 7, k3= 5, k4, k5, k6;
k4= k2& k3;
k5= k2 | k3;
k6= k2^k3;
Console.WriteLine("k4= " + k4+ " k5= " + k5+ " k6= " + k6);

Rezultatet e daljes:

k4 = 5 k5 = 7 k6 =2

Këtu është një shembull i kërkimit sipas modelit duke përdorur logjikën DHE: i= 0;

kërkimi= ar;
nderkohe une< ar.Gjatësia)& (ar[i]!= kërko)) i++;
nese une< ar.Gjatësia)Console.WriteLine("Mostragjetur");
tjetër cConsole.WriteLine("MostraJogjetur");

Ky fragment siguron që modeli i kërkimit të jetë i pranishëm në grup dhe fragmenti do të ekzekutohet me sukses. Në të njëjtat raste kur grupi nuk përmban një element kërkimi, do të bëhet një përjashtim. Kuptimi thelbësor i një procedure të tillë - ndodhja e një përjashtimi - mund të jetë një shenjë e një gabimi në të dhëna, i cili kërkon trajtim të veçantë të situatës.

Ky seksion përshkruan shkurtimisht sintaksën dhe përdorimin e të gjithë operatorëve C#, me përjashtim të disa atyre bazë, të cilët trajtohen më vonë në materialin përkatës.

Rritje dhe zvogëlim

Operatorët e rritjes (++) dhe zvogëlimit (--) rritin dhe zvogëlojnë operandin me një. Ata kanë dy forma shënimi - parashtesë, kur shenja e veprimit shkruhet para operandit, dhe postfiks. Në formën e parashtesës, fillimisht operandi modifikohet dhe më pas vlera e tij bëhet vlera rezultuese e shprehjes, ndërsa në formën pasfiksore, vlera e shprehjes është vlera origjinale e operandit dhe më pas modifikohet.

Operacionet standarde ekzistojnë rritje për sasitë e plota, simbolike, reale dhe financiare.

Operacioni i ri

Operacioni i ri përdoret për të krijuar një objekt të ri. Formati i funksionimit:

lloji i ri ([args])

Duke përdorur këtë operacion, ju mund të krijoni objekte të dy llojeve të referencës dhe vlerave, për shembull:

objekti z = objekt i ri(); int i = new int(); // njëjtë si int i = 0;

Duke bërë operacione të reja së pari, ndahet sasia e kërkuar e memories (për llojet e referencës në grumbull, për llojet e vlerave në pirg), dhe më pas i ashtuquajturi konstruktor i paracaktuar, pra metoda me të cilën inicializohet objekti. E ndryshueshme lloji i vlerës caktuar vlera e paracaktuar, e cila është e barabartë me zero të llojit përkatës.

Operacionet mohuese

Negacion aritmetik(unary minus – ) përmbys shenjën e operandit. Operatori standard i mohimit është përcaktuar për llojet int, long, float, double dhe decimal. Mund të aplikohet në sasi të llojeve të tjera nëse është e mundur për ta konvertim i nënkuptuar ndaj këtyre llojeve.

Boolean mohim(!) është përcaktuar për llojin bool . Rezultati i operacionit është false nëse operandi është i vërtetë dhe i vërtetë nëse operandi është i rremë.

Negacion bitwise(~), i quajtur shpesh bitwise, përmbys çdo bit në paraqitjen binare të një operand të tipit int, uint, long ose ulong.

Konvertimi i tipit eksplicit

Një operacion përdoret për të kthyer në mënyrë eksplicite një vlerë nga një lloj në tjetrin. Kjo kërkohet kur nuk ka konvertim të nënkuptuar. Kur konvertohet nga një lloj më i gjatë në një lloj më të shkurtër, informacioni mund të humbasë. Formati i funksionimit:

(lloji) shprehje

Këtu lloji është emri i llojit në të cilin po bëhet konvertimi, dhe shprehja është më shpesh emri i një ndryshoreje, për shembull:

e gjatë b = 300; int a = (int) b; // asnjë e dhënë nuk humbet int d = (byte) a; // të dhënat humbasin

Shumëzimi, pjesëtimi dhe mbetja

Operacioni i shumëzimit(*) kthen rezultatin e shumëzimit të dy operandëve. Operacioni standard i shumëzimit është përcaktuar për llojet int, uint, long, ulong, float, double dhe decimal. Mund të zbatohet për vlerat e llojeve të tjera nëse ato mund të konvertohen në mënyrë implicite në këto lloje. Lloji i rezultatit të operacionit është i barabartë me "më të madhin" nga llojet e operandit, por jo më pak se int.

tabela 3.2. Simbolet x dhe y tregojnë vlera të fundme pozitive, dhe simboli z tregon rezultatin e veprimit real të shumëzimit. Nëse rezultati është shumë i madh për t'u përfaqësuar duke përdorur lloji i dhënë, merret si e barabartë me vlerën "pafundësi", nëse është shumë e vogël, merret si 0. NaN (jo numër) do të thotë se rezultati nuk është numër.

Tabela 3.2. Rezultatet reale të shumëzimit
* +y -y +0 -0 + - NaN
+x +z -z +0 -0 + - NaN
-x -z +z -0 +0 - + NaN
+0 +0 -0 +0 -0 NaN NaN NaN
-0 -0 +0 -0 +0 NaN NaN NaN
+ + - NaN NaN + - NaN
- - + NaN NaN - + NaN
NaN NaN NaN NaN NaN NaN NaN NaN

Operacioni i divizionit(/) njehson herësin e operandit të parë pjesëtuar me të dytin. Operacioni standard i ndarjes është përcaktuar për llojet int, uint, long, ulong, float, double dhe decimal. Mund të zbatohet për vlerat e llojeve të tjera nëse ka një konvertim të nënkuptuar për to në këto lloje. Lloji i rezultatit përcaktohet nga rregullat e konvertimit, por nuk është më pak se int.

Nëse të dy operandët janë numra të plotë, rezultati i operacionit rrumbullakoset në numrin më të afërt të plotë. Nëse pjesëtuesi e barabartë me zero, hidhet një System.DivideByZeroException.

Nëse të paktën një nga operandët është real, fraksioni rezultati i ndarjes nuk hidhet poshtë, por të gjitha vlerat e mundshme janë dhënë në tabelën 3.3.

Tabela 3.3. Rezultatet reale të ndarjes
/ +y -y +0 -0 + - NaN
+x +z -z + - +0 -0 NaN
-x -z +z - + -0 +0 NaN
+0 +0 -0 NaN NaN +0 -0 NaN
-0 -0 +0 NaN NaN -0 +0 NaN
+ + - + - NaN NaN NaN
- - + - + NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN

Për vlerat financiare (lloji dhjetor), ndarja me 0 dhe tejmbushja gjenerojnë përjashtime të përshtatshme; zhdukja e rendit rezultati është 0.

Operacioni i mbetjes së ndarjes(%) gjithashtu interpretohet ndryshe për sasitë e plota, reale dhe financiare. Nëse të dy operandët janë numra të plotë, rezultati i operacionit llogaritet duke përdorur formulën x - (x / y) * y. Nëse pjesëtuesi është zero, hidhet një System.DivideByZeroException.

Nëse të paktën një nga operandët është real, rezultati i operacionit llogaritet duke përdorur formulën x – n * y, ku n është numri i plotë më i madh më i vogël ose i barabartë me rezultatin e pjesëtimit të x me y. Të gjitha kombinimet e mundshme të vlerave të operandit janë paraqitur në tabelën 3.4.

Tabela 3.4. Rezultate reale të mbetura
% +y -y +0 -0 + - NaN
+x +z z NaN NaN x x NaN
-x -z -z NaN NaN -x -x NaN
+0 +0 +0 NaN NaN +0 +0 NaN
-0 -0 -0 NaN NaN -0 -0 NaN
+ NaN NaN NaN NaN NaN NaN NaN
- NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN

Për vlerat financiare (lloji dhjetor), kur merret pjesa e mbetur e pjesëtimit me 0 dhe kur tejmbushet, krijohen përjashtimet përkatëse, kur zhdukja e rendit rezultati është 0. Shenja e rezultatit është e barabartë me shenjën e operandit të parë.

Mbledhja dhe zbritja

Operacioni i shtimit(+) kthen shumën e dy operandëve. Operacioni standard i mbledhjes është përcaktuar për llojet int, uint, long, ulong, float, double dhe decimal. Mund të zbatohet për vlerat e llojeve të tjera nëse ka një konvertim të nënkuptuar për to në këto lloje. Lloji i rezultatit të operacionit është i barabartë me "më të madhin" nga llojet e operandit, por jo më pak se int.

Të gjitha vlerat e mundshme për operandët real janë dhënë në tabelën 3.5.

Tabela 3.5. Rezultate reale të shtimit
+ y +0 -0 + - NaN
x z x x + - NaN
+0 y +0 +0 + - NaN
-0 y +0 -0 + - NaN
+ + + + + NaN NaN
- - - - NaN - NaN
NaN NaN NaN NaN NaN NaN NaN

Operacioni i zbritjes(-) kthen diferencën e dy operandëve. Operacioni standard i zbritjes është përcaktuar për llojet int, uint, long, ulong, float, double dhe decimal. Mund të zbatohet për vlerat e llojeve të tjera nëse ka një konvertim të nënkuptuar për to në këto lloje. Lloji i rezultatit të operacionit është i barabartë me "më të madhin" nga llojet e operandit, por jo më pak se int.

Nëse të dy operandët janë numër i plotë ose dhjetor dhe rezultati i operacionit është shumë i madh për t'u përfaqësuar nga lloji i specifikuar, hidhet një System.OverflowException.

Të gjitha vlerat e mundshme të rezultatit të zbritjes për operandët realë janë dhënë në tabelën 3.6. Simbolet x dhe y tregojnë vlera të fundme pozitive, dhe simboli z tregon rezultatin e një veprimi real të zbritjes. Nëse x dhe y janë të barabartë, rezultati është zero pozitiv. Nëse rezultati është shumë i madh për t'u përfaqësuar nga lloji i dhënë, merret si vlera "pafundësi" me të njëjtën shenjë si x - y, nëse është shumë i vogël, merret si 0 me të njëjtën shenjë si x - y .

Tabela 3.6. Rezultatet reale të zbritjes
- y +0 -0 + - NaN
x z x x - + NaN
+0 -y +0 +0 - + NaN
-0 -y -0 +0 - + NaN
+ + + + NaN + NaN
- - - - - NaN NaN
NaN NaN NaN NaN NaN NaN NaN

Operacionet e ndërrimit

Operacionet e ndërrimit (<< и >> ) zbatohet për operandët me numër të plotë. Ata zhvendosin paraqitjen binar të operandit të parë majtas ose djathtas me numrin e shifrave binare të specifikuara nga operandi i dytë.

zhvendosja majtas (<< ) освободившиеся разряды обнуляются. При zhvendosja djathtas(>> ) bitet e liruara mbushen me zero nëse operandi i parë është i panënshkruar dhe me një bit të nënshkruar ndryshe. Operacionet standarde të ndërrimit janë përcaktuar për llojet int, uint, long dhe ulong.

Operacionet relacionale dhe testet e barazisë

Operacionet e marrëdhënieve (< , <= , >, >= , == , != ) krahasoni operandin e parë me të dytin. Operatorët duhet të jenë lloji aritmetik. Rezultati i operacionit është tip boolean, është e vërtetë apo e rreme. Rregullat për llogaritjen e rezultateve janë dhënë në > y

e vërtetë nëse x është më e madhe se y, e gabuar përndryshe x<= y e vërtetë nëse x është më e vogël ose e barabartë me y, e gabuar ndryshe x >= y e vërtetë nëse x është më e madhe ose e barabartë me y, e gabuar ndryshe

Operacione logjike bitwise

Operacione logjike bitwise(& , | , ^ ) zbatohen dhe veprojnë në operandë me numër të plotë paraqitjet binare. Gjatë kryerjes së veprimeve, operandët hartohen pak nga pak (biti i parë i operandit të parë me bitin e parë të të dytit, biti i dytë i operandit të parë me bitin e dytë të të dytit, etj.). Operacionet standarde janë përcaktuar për llojet int, uint, long dhe ulong.

lidhja bitwise(& ), biti i rezultatit është 1 vetëm kur bitet përkatëse të të dy operandëve janë 1.

ndarje bitwise(| ), biti i rezultatit është 1 kur biti përkatës i të paktën njërit prej operandëve është 1.

Me OR ekskluzive bitwise() një bit i rezultatit është 1 vetëm nëse biti përkatës i vetëm njërit prej operandëve është 1.

Operacionet Boolean të kushtëzuara

Operacionet Boolean të kushtëzuara AND (&& ) dhe OR (|| ) përdoren më shpesh me operandët boolean. Rezultati i një operacioni logjik është true, atëherë rezultati i një operacioni të kushtëzuar është vlera e operandit të dytë, përndryshe vlera e operandit të tretë. Ose operandi i dytë ose i treti vlerësohet gjithmonë. Lloji i tyre mund të ndryshojë.

Lloji i rezultatit të operacionit varet nga lloji i operandit të dytë dhe të tretë. Nëse operandët janë të të njëjtit lloj, ai bëhet lloji i rezultatit të operacionit.

Operatorët e caktimit

Operatorët e caktimit(= , += , -= , *= , etj.) vendosni një vlerë të re për ndryshoren. Këto operacione mund të përdoren në një program si deklarata të plota.

Formati i Operacionit detyrë e thjeshtë (= ):

variabël = shprehje

Mekanizmi për kryerjen e operacionit të caktimit është si më poshtë: një shprehje llogaritet dhe rezultati i saj ruhet në memorie në adresën e përcaktuar nga emri i ndryshores që ndodhet në të majtë të shenjës së operacionit. Ajo që ishte ruajtur më parë në këtë zonë memorie humbet. Shembuj të operatorëve të caktimit:

Përveç caktimit, operandi i parë i shtohet të dytit dhe rezultati shkruhet në operandin e parë, domethënë shprehja a += b është një paraqitje më kompakte e shprehjes a = a + b.

Rezultati i një operacioni të caktimit kompleks është vlera e shkruar në operandin e majtë.

Operatorët e caktimit djathtas-shoqërues, domethënë ato kryhen nga e djathta në të majtë, ndryshe nga shumica e operacioneve të tjera (a = b = c do të thotë a = (b = c)).

Pyetje dhe detyra për punën e pavarur të nxënësve

  1. Ku mund të deklarohen variablat? Çfarë përfshihet në përshkrimin e ndryshores?
  2. Çfarë ndodh kur përdorni operandë në një shprehje lloje të ndryshme? Jep shembuj.
  3. Rendisni veprimet e gjuhës C#, duke i grupuar ato sipas përparësisë.
  4. Çfarë është NaN? Në cilat operacione rezulton NaN?
  5. Për çfarë lloj operandësh mund të zbatohen operacionet e zhvendosjes?
  6. Cilat janë situatat e jashtëzakonshme?
  7. Përshkruani parimet e trajtimit të përjashtimeve.

KAPITULLI 10. Shprehjet dhe operatorët

Në këtë kapitull, ne do të shohim thelbin e çdo gjuhe programimi - aftësinë e saj për të kryer detyra dhe krahasime duke përdorur operatorë. Do të shohim se cilët janë operatorët në C# dhe cila është përparësia e tyre, dhe më pas do të zhytemi në kategori të veçanta shprehjesh për kryerjen e veprimeve aritmetike, caktimin e vlerave dhe krahasimin e operandëve.

Operatorët

Një operator është një simbol që specifikon një operacion që do të kryhet në një ose më shumë argumente. Kur ekzekutohet operatori, merret një rezultat. Sintaksa për përdorimin e operatorëve është disi e ndryshme nga metodat e thirrjes, dhe ju duhet të dini formatin e shprehjeve që përmbajnë operatorë në C# si pjesa e pasme e dorës. Si në shumicën e gjuhëve të tjera, semantika e operatorëve në C# korrespondon me rregullat dhe shënimet e njohura për ne nga shkolla. Operatorët Bazë në C# përfshijnë shumëzimin (*), pjesëtimin (/), mbledhjen dhe plus unar (+), zbritjen dhe minus unar (-), modulin (%) dhe caktimin (=).

Operatorët përdoren për të marrë një vlerë të re nga vlerat mbi të cilat kryhet operacioni. Këto vlera fillestare quhen operandët. Rezultati i operacionit duhet të ruhet në memorie. Ndonjëherë ai ruhet në një variabël që përmban një nga operandët origjinalë. Përpiluesi C# gjeneron një mesazh gabimi kur përdorimi i një operatori nuk përcakton ose ruan një vlerë të re. Kodi më poshtë nuk i ndryshon vlerat. Përpiluesi do të gjenerojë një mesazh gabimi sepse një shprehje aritmetike që nuk ndryshon të paktën një vlerë zakonisht konsiderohet të jetë në gabim.

klasa NoResultApp

{

zbrazëti publike statike kryesore ()

{

int i; int j;

i+j; // Gabim sepse rezultati nuk është caktuar për asgjë. ) >

Shumica e operatorëve punojnë vetëm me lloje të të dhënave numerike, si p.sh Byte, Short, Long, Integer, Single, Double Dhe dhjetore. Përjashtim bëjnë operatorët e krahasimit (== dhe !=). Për më tepër, në C# mund të përdorni operatorët + dhe - në një klasë Vargu dhe madje përdorni operatorët e rritjes (++) dhe (-) për konstruksione të tilla të pazakonta gjuhësore si delegatë. Për këtë të fundit do të flas në kapitullin 14.

Vjetërsia e operatorit

Kur ka shumë deklarata në një shprehje të vetme, përpiluesi duhet të përcaktojë rendin në të cilin ato duhet të ekzekutohen. Në këtë rast, përpiluesi udhëhiqet nga rregullat e quajtura vjetërsia e operatorëve. Kuptimi i përparësisë së operatorit është i nevojshëm për të drejtshkrimi i saktë shprehje - ndonjëherë rezultati mund të mos jetë siç pritej.

Merrni parasysh shprehjen 42 + 6 * 10. Nëse shtoni 42 dhe 6, dhe më pas shumëzoni shumën me 10, merrni 480. Nëse shumëzoni 6 me 10 dhe shtoni 42 në rezultat, merrni 102. Kur përpiloni kodin, një komponent i veçantë i kompajlerit është analizues leksikor -është përgjegjës për rendin e leximit të këtij kodi. Është analizuesi leksikor ai që përcakton përparësinë relative të operatorëve heterogjenë në një shprehje. Për ta bërë këtë, ai përdor një vlerë - prioritetin - të secilit operator të mbështetur. Operatorët me prioritet më të lartë zgjidhen së pari. Në shembullin tonë, operatori * ka përparësi ndaj operatorit +, pasi * thith(Unë do ta shpjegoj këtë term tani) operandët e tij përpara + ta bëjë atë. Shpjegimi qëndron në rregullat e përgjithshme aritmetike: shumëzimi dhe pjesëtimi Gjithmonë kanë përparësi më të madhe se mbledhja dhe zbritja. Le të kthehemi te shembulli: ata thonë se numri është 6 absorbohet operatori * në të dy 42 + 6 * 10 dhe 42 * 6 + 10, kështu që këto shprehje janë ekuivalente me 42 + (6 * 10) dhe (42 * 6) + 10.

Si përcaktohet përparësia në C#

Tani le të shohim se si përcaktohet përparësia e operatorit në C#. Operatorët janë renditur më poshtë në rend zbritës të prioritetit (Tabela 10-1). Më pas, do të hyj në më shumë detaje rreth kategorive të ndryshme të operatorëve të mbështetur në C#.

Tabela 10-1. Përparësia e operatorit në C#.

Kategoria e operatorit Operatorët
E thjeshtë (x), x.y, f(x), a[x], x++, x - , e re, lloji, madhësia, e kontrolluar, e pakontrolluar
Unar + , -, !, ++x, - x, (T)x
Shumëzues *,/, %
Shtues +, -
Ndërrimi «, »
Qëndrimi <, >, <=, >=, është
Barazia ==
Logjike DHE (DHE) &
Ekskluzive logjike OR (XOR) ^
OSE logjike 1
E kushtëzuar DHE (DHE) &&
IL e kushtëzuar DHE (OR) II
gjendja 9-
Detyrë = *= /= % = , + = , -= « = , » = , &=, ^ = , =

Asociacioni majtas dhe djathtas

Asociativiteti përcakton se cila pjesë e shprehjes duhet të vlerësohet së pari. Për shembull, rezultati i shprehjes së mësipërme mund të jetë 21 ose 33, në varësi të faktit nëse asociativiteti përdoret për operatorin "-": majtas ose djathtas.

Operatori - ka asociativitetin e majtë, d.m.th., së pari vlerësohet 42-15 dhe më pas rezultatit i zbritet 6. Nëse do të ishte asociativ i djathtë, së pari do të vlerësohej ana e djathtë e shprehjes (15-6). dhe pastaj rezultati do të zbritet nga 42.

Të gjithë operatorët binarë (operatorët me dy operandë), përveç operatorëve të caktimit, janë majtas-shoqëruese, dmth përpunojnë shprehjet nga e majta në të djathtë. Kështu, a + b+ Me - e njejta si (a + b) + c, ku llogaritet fillimisht a + b, dhe më pas i shtohet shumës Me. Operatorët e caktimit dhe deklarata të kushtëzuara - asociative e djathte, dmth përpunojnë shprehjet nga e djathta në të majtë. Me fjale te tjera, a=b=c ekuivalente a = (b= Me). Shumë njerëz pengohen në këtë kur duan të vendosin operatorë të shumëfishtë të caktimit në një linjë, kështu që le të shohim këtë kod:

duke përdorur Sistemin;

klasa RightAssocApp(

boshllëk publik statik Main() (

int a = 1; int b = 2; int c = 3;

Console.WriteLine("a=(0) b=(1) c=(2>", a, b, c); a = b = c;

Console.WriteLine("Pas "a=b=c - : a=(0) b=(1) c=(2)", a, b, c); > >

Rezultati i këtij shembulli është:

a=1 b=2 c=3

Pas "a=b=c": a=3 b=3 o=3

Vlerësimi i shprehjeve nga e djathta në të majtë mund të jetë konfuze në fillim, por le t'i qasemi në këtë mënyrë: nëse operatori i detyrës do të ishte shoqërues majtas, përpiluesi fillimisht do të duhej të vlerësonte a = b, pastaj A do të ishte e barabartë me 2 dhe më pas b= me dhe si rezultat b do të ishte e barabartë me 3. Rezultati përfundimtar do të ishte a=2 b=3 c=3. Natyrisht, kjo nuk është ajo që ne presim kur shkruajmë A= b= me, dhe për këtë arsye operatorët e caktimit dhe operatorët e kushtëzuar janë të drejtë-shoqërues.

Përdorimi praktik

Asgjë nuk është aq e mundimshme sa gjetja e një gabimi që është bërë thjesht sepse zhvilluesi nuk i dinte rregullat e përparësisë dhe të shoqërimit. Kam hasur në mesazhe në konferencat me postë, në të cilat njerëz në dukje të arsyeshëm propozonin një lloj mekanizmi vetë-dokumentues - duke përdorur hapësira për t'u treguar operatorëve se, sipas mendimit të tyre, kanë vjetërsi pune. Për shembull, meqenëse e dimë se operatori i shumëzimit ka përparësi ndaj operatorit të mbledhjes, duhet të shkruajmë kodin diçka të tillë, në të cilën hapësirat tregojnë të nënkuptuara vjetërsia:

a = b*c + d;

Kjo qasje është thelbësisht e gabuar: përpiluesi nuk mund të analizojë saktë kodin nëse nuk përcaktohet një sintaksë specifike. Përpiluesi analizon kodin sipas rregullave të përcaktuara nga zhvilluesit e përpiluesit. Nga ana tjetër, ka kllapa të rrumbullakëta, përdoret për të treguar në mënyrë eksplicite përparësinë dhe asociativitetin. Për shembull, shprehja A= b*c+d mund të rishkruhet si a =(b * c) + d ose si A= b*(c+d) dhe kompajleri fillimisht do të vlerësojë shprehjen në kllapa. Nëse ka çifte të shumta kllapash, përpiluesi së pari do të vlerësojë shprehjet në kllapa dhe më pas të gjithë shprehjen, bazuar në rregullat e përparësisë dhe asociativitetit të përshkruara.

Unë besoj fuqimisht se duhet të përdorni gjithmonë kllapa kur ka shumë operatorë në një shprehje. Unë rekomandoj ta bëni këtë edhe nëse e kuptoni rendin e llogaritjeve, sepse njerëzit që do të mbajnë kodin tuaj mund të mos jenë aq të shkolluar.

Operatorët C#

Është më mirë të merren parasysh operatorët sipas përparësisë. Më poshtë do të përshkruaj operatorët më të zakonshëm.

Operatorë të thjeshtë

  • (x) Ky është një variacion i operatorit "bracket" për të kontrolluar rendin e llogaritjeve si në operacionet matematikore ashtu edhe në thirrjet e metodave.
  • x.y Operatori i pikës përdoret për të specifikuar një anëtar të një klase ose strukture. Këtu X përfaqëson një ent që përmban një anëtar u.
  • f(x) Ky lloj operatori i kllapave përdoret për të renditur argumentet e metodës.
  • Oh] Kllapa katrore përdoren për të indeksuar një grup. Këto kllapa përdoren gjithashtu në lidhje me indeksuesit kur objektet mund të trajtohen si një grup. Për indeksuesit, shihni Kapitullin 7.
  • x++ Për operatorin e rritjes do të flasim veçmas në seksionin “Operatorët e rritjes dhe zvogëlimit”.
  • x - Ne do të shqyrtojmë gjithashtu operatorin e zvogëlimit më vonë.
  • i ri Ky operator përdoret për të instancuar objektet bazuar në një përkufizim të klasës.

lloji i

Reflektimi reflektimi është aftësia për të marrë informacionin e tipit në kohën e ekzekutimit. Ky informacion përfshin emrat e llojeve, klasave dhe anëtarëve të strukturës. NË. NET Framework ky funksionalitet lidhet me një klasë Sistemi. Lloji. Kjo klasë është rrënja e të gjithë operatorëve të reflektimit dhe mund të merret duke përdorur operatorin lloji i. Ne nuk do të hyjmë në detajet e reflektimit tani (ne do ta bëjmë këtë në Kapitullin 16), por këtu është një shembull i thjeshtë për të ilustruar se sa e lehtë është përdorimi i operatorit lloji i"për të marrë pothuajse çdo informacion rreth një lloji ose objekti gjatë ekzekutimit të programit:

duke përdorur Sistemin;

duke përdorur System.Reflection;

klasë publike Apple (

publike int nSeeds;

boshllëk publik Ripen()

{

> >

klasa publike TypeOfApp (

boshllëk publik statik Main() (

Lloji t = lloji (Mollë);

emri i klasës së vargut = t.ToStringO;

Console.IgShipe("\nInformacion 0 class (About)", className);

Console.WriteLine("\nMeroflH (0)", Emri i klasës); Konsol. WriteLine ("--------"); Metodat Metodlnfo = t.GetMethodsO;

foreach (metoda MethodInfo në metoda)

Console.WriteLine(metoda.ToSt ring());

}

Console.WriteLine("\nAnëtarët Bce (O)", Emri i klasës); Konsol. Writel_ine ("--------"); Anëtari nfo të gjithëAnëtarët = t.Merr AnëtarëO; foreach (Anëtar i Anëtarit të të gjithë Anëtarëve)

{

Konsol. WriteLine (anëtar.ToStringO);

} > }

Ky program përmban një klasë Apple i cili ka vetëm dy anëtarë: fushë nFarat dhe metodë Pjekur. Së pari, duke përdorur operatorin lloji i dhe emrin e klasës, marr objektin Sistemi. Lloji, e cila më pas ruhet në një variabël t. ME në këtë pikë unë mund të përdor objektin Sistemi. Lloji për të marrë të gjitha metodat dhe anëtarët e një klase Apple. Kjo bëhet duke përdorur metoda GetMethods Dhe GetAnëtarë përkatësisht. Rezultatet e këtyre metodave shfaqen në pajisje standarde dalje si më poshtë:

Informacion rreth Klasa e mollës Metodat e mollës

Int32 GetHashCodeQ

Sistemi.String ToStringQ

E zbrazët RipenO

Sistemi.Type GetTypeO

Të gjithë anëtarët e Apple

Int32 nFarat

Int32 GetHashCodeO

Boolean Equals (System.Object)

Sistemi.String ToStringO

E zbrazët RipenO

Sistemi.Type GetTypeO

Para se të vazhdoj më tej, dua të them dy pika. Së pari, vini re se anëtarët e trashëguar të klasës janë gjithashtu të shtypura. Meqenëse një klasë nuk rrjedh në mënyrë eksplicite nga një klasë tjetër, ne e dimë se të gjithë anëtarët nuk janë përcaktuar në klasë Apple trashëgojnë nga një klasë bazë e nënkuptuar Sistemi.Objekti. Së dyti, objekti Sistemi.Lloji mund të merret duke përdorur metodën GetType. Ky është i trashëguar nga Sistemi.Objekti Metoda ju lejon të punoni me objekte, jo me klasa. Secili nga dy fragmentet më poshtë mund të përdoret për të marrë një objekt Sistemi. Lloji.

II Marrja e një objekti System.Type bazuar në një përkufizim të klasës. Lloji t1 = lloji (Mollë);

// Merrni objektin System.Type nga objekti. Mollë mollë= AppleQ i ri; Lloji t2 = mollë.GetTypeO;

madhësia e

Operatori madhësia e përdoret për të marrë madhësinë e llojit të specifikuar në bajt. Në të njëjtën kohë, mbani mend vetëm dy faktorë të rëndësishëm. Së pari, madhësia e mund të aplikohet vetëm për llojet e dimensioneve. Prandaj, edhe pse mund të përdoret për anëtarët e klasave, nuk mund të përdoret për vetë klasat. Së dyti, madhësia e mund të përdoret vetëm në metoda ose blloqe kodesh të shënuara si e pasigurt. ME Ne do ta shikojmë këtë lloj kodi në Kapitullin 17. Këtu është një shembull i përdorimit të operatorit madhësia e në një metodë klase të shënuar si i pasigurt:

duke përdorur Sistemin;

Klasa BasicTypes(

// Shënim: Kodi që përdor operatorin sizeof duhet // të shënohet si i pasigurt, statik i pasigurt publik i pavlefshëm ShowSizesQ (

Console.WriteLine("\nllojet bazë Pa3Mephi"); Console.WriteLine("Pa3Mep short = (0)", sizeof(short)); Console.WriteLine("Pa3Mep int = (0)", sizeof(int)); Console.Writel_ine ("Pa3Mep i gjatë = (0)", sizeof(i gjatë)); Console.WriteLine("Pa3Mep bool = (0)", sizeof(bool)); ) )

klasa UnsafeUpp

{

boshllëk statik publik i pasigurt MainQ

{

BasicTypes.ShowSizes();

} }

Këtu është rezultati i ekzekutimit të këtij aplikacioni:

Madhësitë e llojeve kryesore Madhësia e shkurtër = 2 Madhësia int = 4 Madhësia e gjatë = 8 Madhësia bool = 1

Operatori madhësia e mund të përdoret për të përcaktuar dimensionet jo vetëm të llojeve të thjeshta të integruara, por edhe të llojeve të dimensioneve të personalizuara siç janë strukturat. Megjithatë, rezultatet madhësia e mund të mos jetë e qartë:

// Duke përdorur operatorin sizeof. duke përdorur Sistemin;

Struktura StructWithNoMembers

struct StructWithMembers

{

Pantallona të shkurtra;

int i;

e gjatë 1;

bool b; )

struct CompositeStruct

{

StrukturaMeNoAnëtarë a; StrukturaMeAnëtarë b;

StrukturaMeNoAnëtarë c; )

Klasa UnSafe2App (

e pasigurt publike statike void Main() ( Console.WriteLine("\nStruktura Pa3Mep StructWithNoMembers = (0)",

sizeof(StructWithNoMembers)); Console.WriteLine("\nStruktura Pa3Mep StructWithMembers = (0)",

sizeof(StructWithMembers)); Console.WriteLine("\nStruktura e Pa3Mep CompositeStruct = (0)",

sizeof(CompositeStruct)); ) )

Edhe pse mund të pritet që ky aplikacion të nxjerrë 0 për një strukturë pa anëtarë (StructWithNoAnëtarë), 15 për një strukturë me katër anëtarë të llojeve bazë (StructWithAnëtarë) dhe 15 për një strukturë që bashkon dy të mëparshmet (CompositeStruct), në realitet rezultati do të jetë si ky:

Size StructWithNoMembers Struktura = 1 Size StructWithMembers Struktura = 16

Madhësia e strukturës CompositeStruct = 24

Shpjegimi për këtë është mënyra se si ruhet struktura struktura nga përpiluesi në skedarin dalës, në të cilin përpiluesi aplikon shtrirjen dhe mbushjen. Për shembull, nëse një strukturë është 3 bajt në madhësi dhe është vendosur të jetë e rreshtuar në kufijtë 4 bajt, përpiluesi do të shtojë automatikisht 1 bajt në strukturë dhe deklaratën madhësia e do të tregojë se madhësia e strukturës është 4 bajt. Mos harroni ta merrni parasysh këtë kur përcaktoni madhësinë e strukturave në C#.

kontrolluar Dhe i pakontrolluar

Këta dy operatorë kontrollojnë kontrollin e tejmbushjes kur kryejnë veprime matematikore.

Operatorët matematikë

C#, si shumica e gjuhëve të tjera, mbështet operatorët bazë matematikorë: shumëzimin (*), pjesëtimin (/), mbledhjen (+), zbritjen (-) dhe modulin (%). Qëllimi i katër operatorëve të parë është i qartë nga emrat e tyre; Operatori i modulit formon pjesën e mbetur të ndarjes së numrit të plotë. Këtu është kodi që ilustron përdorimin e operatorëve matematikorë:

duke përdorur Sistemin;

klasa MathOpsApp

{

zbrazëti publike statike MainQ

{

// Klasa System.Random është pjesë e bibliotekës së klasës .NET Framework //. Në konstruktorin e saj të paracaktuar // metoda Next përdor datën/kohën aktuale si // vlera fillestare. Random random = i ri RandomO; int a, b, c;

a = rand.Next() % 100; // Vlera kufitare 99. b = rand.NextO % 100; // Vlera kufitare 99.

Console.WriteLine("a=(0) b=(1)", a, b);

c = a * b;

Console.WriteLineC"a * b = (0)", c);

// Vini re se ne po përdorim numra të plotë këtu. // Prandaj, nëse a është më pak se b, rezultati // do të jetë gjithmonë 0. Për të marrë një rezultat më të saktë // duhet të përdorni variablat e tipit dyfishtë ose noton, c = a / b; Console.WriteLineC"a / b = (0)", c);

Console.WriteLineC"a + b = (0)", c);

Console.WriteLineC"a - b = (0)", c);

Console.WriteLineC"a X b = (0)", c); > >

Operatorët unarë

Ekzistojnë dy operatorë unarë: plus dhe minus. Operatori unar minus i tregon kompajlerit se numri është negativ. Pra në kodin e mëposhtëm A do të jetë e barabartë me -42:

duke përdorur Sistemin; duke përdorur Sistemin;

klasa UnarylApp(

zbrazëti publike statike kryesore ()

{

int a = 0;

a = -42;

Console.WriteLine("(0)", a); ) )

Megjithatë, ky kod paraqet paqartësi: duke përdorur Sistemin;

Klasa Unary2App<

boshllëk publik statik Main() (

int a; int b = 2; int c = 42;

a = b * -c;

Console.WriteLine("(0)", a); > >

Shprehje a= b*-c jo mjaft e qartë. Përsëri, përdorimi i kllapave do ta bëjë këtë shprehje më të qartë:

// Kur përdorim kllapa, është e qartë se po // shumëzojmë b me një numër negativ c. a = b * (-c);

Nëse kthehet një minus unar kuptim negativ operand, ju mund të mendoni se unary plus kthehet pozitiv. Megjithatë, plus unary vetëm e kthen operandin në formën e tij origjinale dhe nuk bën asgjë tjetër, d.m.th., nuk ndikon në operand. Për shembull, ekzekutimi i këtij kodi do të nxjerrë vlerën -84:

duke përdorur Sistemin;

klasa UnarySApp(

zbrazëti publike statike MainQ (

a = b * (+c);

Console.WriteLine("(0)", a); ) )

Për të marrë një vlerë pozitive, përdorni funksionin Math.Abs. Ky kod do të nxjerrë vlerën 84:

duke përdorur Sistemin;

Klasa Unary4App

{

zbrazëti publike statike kryesore ()

int a; int b = 2; int c = -42;

a = b * Math.Abs(c); Console.Writel_ine("(0)", a); ) )

Operatori i fundit unar që përmenda është T(x). Ky është një variant i operatorit "bracket" që ju lejon të transmetoni një lloj në tjetrin. Meqenëse mund të mbingarkohet duke krijuar një transformim të personalizuar, ne do ta diskutojmë atë në Kapitullin 13.

Operatorët e caktimit të kompleksit

Operatori i caktimit të kompleksit -është një kombinim i operatorit binar dhe operatorit të caktimit (=). Sintaksa e këtyre operatorëve është:

kor=y

Ku op - ky është operatori. Vini re se në këtë rast vlera e majtë (lvlera) nuk zëvendësohet me atë të duhurin (rvlera), operatori i kompleksit ka të njëjtin efekt si:

x = x op

Dhe lvlera përdoret si bazë për rezultatin e operacionit.

Vini re që thashë "ka të njëjtin efekt". Përpiluesi nuk përkthen një shprehje si x += 5v X= x + 5, ai vepron logjikisht. ME vëmendje të veçantë duhet të merren parasysh rastet kur lvleraështë një metodë. Le të shohim kodin:

duke përdorur Sistemin;

klasa CompoundAssignmentlApp(

elemente të mbrojtura;

në publik GetArrayElementO

{

elementet e kthimit;

}

CompoundAssignment1App() (

elemente = int e re;

elemente = 42;

}

boshllëk publik statik Main() (

Aplikacioni CompoundAssignmentlApp = i ri CompoundAssignment1App();

Console.WrlteLine("(0>", app.GetArrayElement());

app.GetArrayElement() = app.GetArrayElement() + 5; Console.WriteLine("(0)", app.GetArrayElement()); ). )

Kushtojini vëmendje thirrjes së theksuar të linjës - metodës Compound-AssignmentlApp.GetArrayElement dhe pastaj duke ndryshuar elementin e parë - këtu kam përdorur sintaksën:

x = x op

Ky është kodi MSIL që do të gjenerohet: // Teknika joefikase: x = x ose y.

Metoda publike hldebyslg static void Main() 11 e menaxhuar

Entrypolnt

// Madhësia e kodit 79 (Ox4f).maxstack 4

Locals (klasa CompoundAssignmentlApp V_0)

IL_0000: instancë e re e pavlefshme CompoundAssignmentlApp::.ctor() IL_0005: stloc.O IL_0006: Idstr "(OG IL_OOOb: ldloc.0 ILJJOOc: instancë e thirrjes int32

CompoundAssignmentlApp::GetArrayElementO

IL_0011: ldc.14.0

IL_0012: Idelema ["mscorlib"]System.Int32

IL_0017: kutia [ 1 mscorlib"]System.Int32

IL_001c: thirrja e pavlefshme ["mscorlib 1 ]System.Console::WriteLine (klasa System.String, klasa System.Object)

IL_0021: ldloc.0

IL_0022: shembulli i thirrjes int32 CompoundAssignmentlApp::GetArrayElementO

IL_0027: Idc.i4.0

IL_0028: ldloc.0

IL_0029: shembulli i thirrjes int32 CompoundAssignmentlApp: :GetArrayElementO

IL_002e: Idc.i4.0

IL_002f: ldelem.14

IL_0030: ldc.14.5

IL_0031: shtoni

IL_0032: vjedhur.14

IL_0033: Idstr "(0)"

IL_0038: ldloc.0

IL_0039: telefononi

shembull int32 CompoundAssignmentlApp::GetArrayElement() IL_003e: ldc.14.0

IL_003f: Idelema ["mscorlib"]Systera.Int32 IL_0044: kutia ["msoorlib"]System.Int32 IL_0049: telefononi void ["mscorlib"]System.Console::WriteLine

(klasa System.String, klasa System.Object) IL_004e: ret

) // fundi i metodës "CompoundAssignmentlApp::Main" !

Shikoni rreshtat e shkruar: metoda CompoundAssignmentlApp.Get-ArrayElement në fakt quhet dy herë! Kjo është e paefektshme për të thënë të paktën, dhe mundësisht e dëmshme në varësi të asaj që bën metoda tjetër.

Tani le të shohim një kod tjetër që përdor sintaksën e operatorit të caktimit të përbërë:

duke përdorur Sistemin;

Klasa CompoundAssignment2App (

elemente int të mbrojtura;

në publik GetArrayElementO

elementet e kthimit;

}

CompoundAssignment2App() (

elemente = int e re;

elemente = 42;

}

boshllëk publik statik Main() (

Aplikacioni CompoundAssignment2App = i ri CompoundAssignment2App();

Console.WriteLine("(0)", app.GetArrayElement());

app.GetArrayElement() += 5; Console.WriteLine("(0)", app.GetArrayElement()); ) )

Përdorimi i një operatori të caktimit të përbërë do të prodhojë kod MSIL shumë më efikas:

// Teknika më efikase: x op = y.

Metoda publike hidebysig static void Main() u menaxhua

\ {

\.pika hyrëse

I // Madhësia e kodit 76 (Ox4c) \ .maxstack 4

Locals (klasa CompoundAssignmentlApp V_0, int32 V_1) \ IL_0000: shembulli i ri i pavlefshëm CompoundAssignmentlApp::.ctor() \ IL_0005: stloc.O 1 IL_0006: Idstr "(0)" 1 IL_OOOb: ldloc.0 IL_OOOc: shembulli i thirrjes int32

CompoundAssignmentlApp::GetArrayElementO IL_0011:Idc.i4.0

IL_0012: Idelema [ mscorlib"]System.Int32 IL_0017: box [ > mscorlib - ]System.Int32 lL_001c: telefononi void ["mscorlib"]System.Console::WriteLine

(klasa System.String, klasa System.Object) IL_0021: ldloc.0 IL_0022: shembulli i thirrjes int32

CompoundAssignmentlApp::GetArrayElement()

IL_0027: dup

IL_0028: stloc.1

IL_0029: Idc.i4.0

IL_002a: ldloc.1

IL_002b: Idc.i4.0

IL_002c:ldelem.14

IL_002d: ldc.14.5

IL_002e: shtoni

IL_002f:stelem.14

IL_0030: Idstr "(0)"

IL_0035: ldloc.0

IL_0036: shembulli i thirrjes int32

CompoundAssignmentlApp::GetArrayElementO IL_003b:Idc.i4.0

IL_003c: Idelema ["mscorlib"]System.Int32

IL_0041: box [mscorlib"]System.Int32

IL_0046: thirrja e pavlefshme ["mscorlib"]System.Console::WriteLine

(klasa System.String, klasa System.Object)

IL_004b: ret ) // fundi i metodës "CompoundAssignmentlApp::Main"

Ju mund të shihni se komanda MSIL është përdorur dup. Ai kopjon elementin e sipërm në pirg, duke krijuar kështu një kopje të vlerës së kthyer nga metoda CompoundAssignmentlApp.Get Element Array. I

Nga kjo është e qartë se edhe pse në thelb x +=y ekuivalente x = x + y, Kodi MSIL është i ndryshëm në të dyja rastet. Ky ndryshim duhet t'ju bëjë të pyesni se cila sintaksë të përdorni në secilin rast. Rregulli i përgjithshëm dhe rekomandimi im është përdorimi i operatorëve të caktimit të përbërë kurdo dhe kudo që të jetë e mundur.

Operatorët e rritjes dhe zvogëlimit

U shfaq në gjuhën C dhe u transferua në C++ dhe Operatorët Java inc 1 -ment dhe zvogëlimi ju lejojnë të shprehni në mënyrë të përmbledhur se dëshironi të rritni ose ulni një vlerë numerike me 1. Kjo do të thotë, /++ është e barabartë me shtimin e 1 në vlerën aktuale të /".

Të kesh dy forma të operatorëve të rritjes dhe zvogëlimit ndonjëherë çon në konfuzion. Parashtesa Dhe postfiks Llojet e këtyre operatorëve ndryshojnë në momentin në të cilin ndryshohet vlera. Në versionin prefiks të operatorëve të rritjes dhe zvogëlimit (++ai - a përkatësisht) fillimisht kryhet operacioni dhe më pas krijohet vlera. Në versionin postfix (a++ Dhe A-) fillimisht krijohet vlera dhe më pas kryhet operacioni. Le të shohim një shembull:

duke përdorur Sistemin;

klasa IncDecApp (

boshllëk publik statik Foo(int j)

{

Console.WriteLine("IncDecApp.Foo j = (0)", j);

>

boshllëk publik statik Main() (

int i = 1;

Console.WriteLineC"flo thërret në Foo(i++) = (0)", i);

Console.WriteLine("Pas thirrjes së Foo(i++) = (0)", i);

Console.WriteLine("\n");

\ Console.WriteLineC"flo thërret në Foo(++i) = (0)", i);

\Foo(++l);

\ Console.WrlteLine ("Pas thirrjes së Foo(++i) = (0)", i);

l Rezultati i ekzekutimit do të jetë si ky:

Përpara se të telefononi Foo(i++) = 1

IncDecApp.Foo j = 1

Pasi të telefononi Foo(i++) = 2

Përpara se të telefononi Foo(-n-i) = 2

IncDecApp.Foo j = 3

Pasi të telefononi Foo(++i) = 3

Dallimi është Kur krijohet vlera dhe modifikohet operandi. Kur telefononi Foo (i++) vlera /" i kalohet (e pandryshuar) metodës Foo Dhe pas kthimet nga metoda / rritet me 1. Shikoni kodin MSIL më poshtë: komandën shtoni ekzekutohet pasi vlera të shtyhet në pirg.

IL.0013: ldloc.0

IL.0014: dup

IL_0015: Idc.i4.1

IL_0016: shtoni

IL_0017: stloc.O

IL_0018: thirrje e pavlefshme IncDecApp::Foo(int32)

Tani le të shohim formën e prefiksit të operatorit të përdorur në thirrje Foo (++a). Në këtë rast, kodi MSIL do të jetë i ndryshëm. Në të njëjtën kohë, ekipi shtoni kryer para si shtyhet vlera në pirg për thirrjet e mëvonshme të metodës Foo.

IL.0049: ldloc.0

IL_004a: Idc.i4.1

IL_004b: shtoni

IL_004c: dup

IL_004d: stloc.O

IL_004e: thirrje e pavlefshme IncDecApp::Foo(int32)

Operatorët relacionalë

Shumica e operatorëve kthejnë vlera numerike. Sa për operatorët relacionalë, ata gjenerojnë një rezultat Boolean. Në vend të / në vend të kryerjes së operacioneve matematikore në një grup operandësh, / operatorët relacionalë analizojnë marrëdhënien midis operandëve dhe kthimi kuptimi e vertete, nëse lidhja është e vërtetë, i rremë - nëse/ e rreme.

Operatorët e Krahasimit

Operatorët relacionalë të thirrur operatorët e krahasimit, lidh)-xia "më pak" (<), «меньше или равно» (<=), «больше» (>), “më e madhe se ose e barabartë me” (>=), “e barabartë me” (==) dhe “jo e barabartë me” (!=). Aplikimi i këtyre operatorëve në numra është i qartë, por kur përdoren me objekte, zbatimi i tyre nuk është aq i dukshëm. Ja një shembull:

duke përdorur Sistemin;

klasa Numeric Test (

NumericTest publik (int 1)

{

kjo.i = i;

>

i mbrojtur int 1; )

klasa RelationalOpslApp (

boshllëk publik statik Main() (

NumericTest testl = NumericTest i ri(42); NumericTest test2 = new NumericTest(42);

Console.WriteLine("(0)", testl == test2); > )

Nëse programoni në Java, e dini se çfarë do të ndodhë këtu. Sidoqoftë, programuesit e C++ me shumë mundësi do të befasohen kur shohin rezultatin i rremë. Më lejoni t'ju kujtoj: kur krijoni një shembull të një objekti, ju merrni një referencë për të. Kjo do të thotë që kur ndeshet me një operator relacional që krahason dy objekte, përpiluesi C# nuk krahason përmbajtjen e objekteve, por adresat e tyre. Për ta kuptuar më mirë këtë, le të shohim kodin MSIL:

\ .metoda publike hldebysig zbrazëti statike MainQ il menaxhuar

\ .pikë hyrëse

\ // Madhësia e kodit 39 (0x27)

1 .maxstack 3

Vendasit (klasa NumericTest V_0, \ klasa NumericTest V_1, 1 bool V_2)

ILJJOOO: Idc.i4.s 42

1L_0002: instancë e re e pavlefshme NumericTest::.ctor(int32)

IL_0007: stloc.O

IL_0008: Idc.i4.s 42

IL_OOOa: shembulli i ri i pavlefshëm NumericTest::.ctor(int32)

IL_OOO nga: stloc.1

IL_0010: Idstr "(0)"

IL_0015: ldloc.0

IL_0016: ldloc.1

IL_0017: eeq

IL_0019: stloc.2

IL_001a: Idloca.s V_2

IL_001c: kutia ["mscorlib"]Sistemi.Boolean

IL_0021: thirrje e pavlefshme ["mscorlib"]System.Console::WriteLine

(klasa System.String,klasa System.Object)

IL_0026: ret ) // fundi i metodës "RelationalOpslApp::Main"

Shikoni vijën .vendasit. Përpiluesi tregon se metoda Kryesor tre variabla lokale. Dy të parat janë objekte Testi numerik dhe e treta është një variabël Boolean. Tani le të kalojmë te linjat IL_0002 Dhe IL_0007. Kjo është ajo ku objekti është instancuar testl, dhe lidheni me të duke përdorur stloc ruhet në variablin e parë lokal. Është e rëndësishme që MSIL të ruajë adresën e objektit të krijuar rishtazi. Pastaj në rreshta IL_OOOa Dhe IL_OOO e ju shihni kodet MSIL për të krijuar një objekt testi 2 dhe ruajtja e referencës së kthyer në një variabël të dytë lokale. Më në fund, në rreshta 1LJ)015 Dhe IL_0016 variablat lokale shtyhen në rafte nga komanda Idloc, dhe në linjë IL_0017 ekipi floke gri krahason dy vlera në krye të pirgut (d.m.th. referencat e objekteve testl Dhe testl). Vlera e kthyer ruhet në një variabël të tretë lokale dhe më pas del nga metoda Sistemi.Konsol. WriteLine.

Por si i krahasoni anëtarët e dy objekteve? Përgjigja është përdorimi i një klase bazë të nënkuptuar për të gjitha objektet .NET Framework. Pikërisht, për këto qëllime, klasa Sistemi.Objekti ka një metodë Të barabartë. Për shembull, kodi i mëposhtëm krahason përmbajtjen e objekteve dhe daljeve, siç pritej / e vërtetë: Unë

duke përdorur Sistemin; /

Klasa RelationalOps2App

( / zbrazëti publike statike kryesore () (

Console.WriteLine("(0)", testl.Equals(test2));

Shembulli RelationalOpslApp përdor një klasë "homemade". (Nu-mericTest), dhe në shembullin e dytë - klasa .NET (dhjetore).Çështja është se metoda Sistemi.Objekti.E barabartë duhet të anashkalohet për të bërë një krahasim të vërtetë të anëtarëve. Prandaj, metoda Të barabartë me klasën Testi numerik nuk do të funksionojë pasi nuk e kemi anuluar metodën. Dhe këtu është klasa dhjetore anashkalon metodën që trashëgon e barabartë, dhe në këtë rast gjithçka do të funksionojë.

Një mënyrë tjetër për të krahasuar objektet është përdorimi mbingarkesa e operatorit(mbingarkimi i operatorit). Mbingarkimi i operatorit përcakton operacionet e kryera në objekte të një lloji të caktuar. Për shembull, për objektet varg Operatori + nuk kryen mbledhje, por bashkon vargjet. Ne do të shikojmë mbingarkimin e operatorit në Kapitullin 13.

Operatorët e thjeshtë të caktimit

Vlera në anën e majtë të operatorit të caktimit thirret lvlera, dhe në anën e djathtë - rvlera. Si rvlera mund të jetë çdo konstante, ndryshore, numër ose shprehje, rezultati i së cilës është i pajtueshëm lvlera. ndërkohë lvlera duhet të jetë një variabël i një lloji të caktuar. Çështja është se vlera kopjohet nga ana e djathtë në të majtë. Prandaj, hapësira e adresës fizike duhet të ndahet për vlerën e re. Për shembull, mund të shkruani /" = 4, sepse / ka një vend në memorie - në pirg ose në grumbull - në varësi të llojit të ndryshores /. Dhe këtu është operatori 4 = 1 nuk mund të ekzekutohet sepse 4 është një vlerë dhe jo një variabël përmbajtja e së cilës në memorie mund të ndryshohet. Nga rruga, unë vërej se në C # si lvlera mund të jetë një ndryshore, veti ose indeksues. Për më shumë informacion mbi vetitë dhe indeksuesit, shihni Kapitullin 7. Në këtë kapitull, unë përdor variabla për thjeshtësi. Nëse me detyrë vlerat numerike gjithçka është mjaft e qartë, me objektet është më e ndërlikuar. Më lejoni t'ju kujtoj se kur merreni me objekte, nuk po manipuloni elementë të stivës, të cilët janë të lehtë për t'u kopjuar dhe lëvizur. Me objekte, ju me të vërtetë keni vetëm referenca për disa entitete për të cilat memorja është ndarë në mënyrë dinamike. Prandaj, kur përpiqeni t'i caktoni një objekt (ose ndonjë lloj referimi) një ndryshoreje, nuk janë të dhënat që kopjohen, siç është rasti me llojet e vlerave, por referencat.

Le të themi se keni dy objekte: testl Dhe testi 2. Nëse specifikoni testl= test2, testl nuk do të jetë një kopje testi 2. Ata do të përputhen! Nje objekt testl tregon të njëjtën kujtesë si testi 2, dhe çdo ndryshim në objekt testl do të çojë në ndryshime testi 2. Këtu është një program që ilustron këtë:

duke përdorur Sistemin;

klasa Foo (

publike int i; )

klasa RefTestlApp (

boshllëk publik statik MainO (

Foo testl = i ri Foo(); testl.i = 1;

Foo test2 = i ri Foo(); test2.i = 2;

Console.WriteLine ("Para caktimit të objekteve"); Console.WriteLine("test1.i=(0>", testl.i); Console.WriteLine("test2.i=(0)", test2.i); Console.WriteLine("\n");

testl = test2;

Console.Writel_ine("Pas caktimit të objekteve");

Console.WriteLine("test1.i=(0)", testl.i); Console.WriteLine("test2.i=(0)", test2.i); Console.WriteLine("\n");

testl.i = 42; ;"

Console.WriteLine ("Pas ndryshimit të vetëm anëtarit TEST1"); Console.WriteLine("test1.i=(0)", testl.i); Console.WriteLine("test2.i=(0)", test2.i); Console.WriteLine("\n"); ) )

Kur të ekzekutoni këtë kod, do të shihni:

Para caktimit të një objekti

testi1.i=1

test2.i=2

Pas caktimit të një objekti

testt.i=2

test2.i=2

Pas ndryshimit të vetëm anëtarit TEST1

testi1.i=42

test2.i=42

Le të shohim se çfarë ndodh në secilën fazë të këtij shembulli. Foo- Kjo është një klasë e thjeshtë k me një anëtar të vetëm, /. Metoda Main krijon dy instanca të kësaj klase: testl Dhe testi 2- dhe anëtarët e tyre i janë vendosur respektivisht në 1 dhe 2. Këto vlera më pas nxirren dhe, siç pritej, testl.iështë e barabartë me 1, a test2.i- 2. Dhe këtu fillon argëtimi! NË rreshti tjetër Objekt testl caktuar testi 2. Lexuesit që programojnë në Java e dinë se çfarë vjen më pas. Megjithatë, shumica e programuesve të C++ do të presin që anëtari /object testl tani është e barabartë me anëtarin e objektit testi 2(duke supozuar se kur një aplikacion i tillë kompilohet, do të ekzekutohet një lloj operatori i kopjes së anëtarit të objektit). Prodhimi duket se e konfirmon këtë. Megjithatë, në fakt, lidhja midis objekteve tani është shumë më e thellë. Le t'i caktojmë termit vlerën 42 testl.i dhe printoni sërish rezultatin. DHE?! Kur një objekt ndryshon testl ndryshuar dhe testZ Kjo ndodhi për shkak se objekti testl jo më. Pas caktimit të tij testi 2 nje objekt testl humbet sepse aplikacioni nuk e referon më dhe si rrjedhojë “pastrohet” nga mbledhësi i plehrave (GC). Tani testl Dhe testi 2 tregoni të njëjtën kujtesë në grumbull. Prandaj, kur ndryshon një variabël, përdoruesi do të shohë një ndryshim në tjetrin.

Vini re dy rreshtat e fundit të daljes: megjithëse në kod vetëm vlera u ndryshua testl.i, kuptimi test2.i gjithashtu ka ndryshuar. Edhe një herë, të dy variablat tregojnë tani në të njëjtin vend në memorie - kjo është sjellja që programuesit Java prisnin. Sidoqoftë, kjo nuk i plotëson aspak pritshmëritë e zhvilluesve të C++, pasi në këtë gjuhë kryhet pikërisht kopjimi i objekteve: çdo variabël ka kopjen e vet unike të anëtarëve dhe ndryshimet në një objekt nuk ndikojnë në tjetrin. . Meqenëse ky është çelësi për të kuptuar se si funksionojnë objektet në C#, le të bëjmë një devijim të shpejtë dhe të shohim se çfarë ndodh kur ia kaloni një objekt një metode:

duke përdorur Sistemin;

klasa Foo (

publike int i; )

Klasa RefTest2App (

publik void ChangeValue (Foo f)

{

f.i = 42;

}

boshllëk publik statik Main() (

Aplikacioni RefTest2App = i ri RefTest2App();

Foo test = i ri Foo(); test.i = 6;

Console.WriteLine ("Para thirrjes së metodës"); Console.WriteLine("test.i=(0)", test.i); Console.WriteLine("\n");

app.ChangeValue(test);

Console.WriteLine ("Pas thirrjes së metodës"); Console.WriteLine("test.i=(0)", test.i); Console.WriteLine("\n"); > )

Në shumicën e gjuhëve përveç Java, ky kod do të kopjojë objektin e krijuar test në steka e metodave lokale RefTest2App.ChangeValue. Në këtë rast, objekti provë krijuar në metodë Kryesor, nuk do të shohë kurrë ndryshime në objekt/të bëra në metodë Ndryshimi Vlera. Megjithatë, e përsëris edhe një herë se metoda Kryesor kalon një referencë për një objekt të caktuar në grumbull provë. Metoda kur Ndryshimi Vlera manipulon variablin e saj lokal // gjithashtu manipulon drejtpërdrejt objektin provë metodë Kryesor.

Le ta përmbledhim

Gjëja kryesore në çdo gjuhë programimi është mënyra se si kryen detyrat, operacionet matematikore, logjike dhe relacionale - gjithçka që kërkohet për të punuar. aplikacione reale. Në kod, këto operacione përfaqësohen nga operatorët. Faktorët që ndikojnë në ekzekutimin e deklaratave përfshijnë përparësinë dhe asociativitetin (djathtas dhe majtas) të deklaratave. Grupi i fuqishëm i operatorëve të paracaktuar të C# mund të zgjerohet me implementime të përcaktuara nga përdoruesi, siç do të diskutojmë në Kapitullin 13.

Artikujt më të mirë mbi këtë temë