C# изборна дисциплина



страница2/5
Дата27.09.2016
Размер0.88 Mb.
#10986
1   2   3   4   5
4.Константи и променливи
В C# константите могат да бъдат от произволен тип, който е определен от тяхното представяне. За да няма трудността при определяне на типа на една константа, в C# съществуват специални правила. Типът на целите числа е най-малкият цял тип, започвайки от int, който може да съхрани нейната стойност. Следователно в зависимост от стойността, типът на цялата константа може да бъде int, uint, long, ulong. Константите с плаваща точка са от тип double. Типът на константите по подразбиране може да бъде променен явно чрез суфикс. За да се зададе тип long на константа се добавя към нея “l”/”L”. Например 20L или 20l. За да се зададе тип uint – “u”/”U” – 100U (100u), за да се зададе ulong – “ul”/”UL”- 9 415UL. За float се добавя “f”/”F” – 10.15F. За decimal – “m”/”M” – 9.95M.

Целите константи с тип по подразбиране могат да бъдат присвоени на променливи от тип byte/sbyte/short/ushort, ако тяхната стойност е в допустимите стойности на съответния тип. Цяла константа int, uint винаги може да бъде присвоена на long. Hexadecimal започват с 0x (oxFF = 255). В C# няма осмични константи (в C++ има), тъй като те се използват рядко. Символната константа е единичен символ заграден в апострофи. Може да е и буква от Кирилицата. За някой често се използват неграфични символи, а за служебните символи се ползват следните еднобуквени означения:

\a – system beep

\b – символа “backspace”

\f – за минаване на нова страница

\n – нов ред

\r – минаване в началото на същия ред

\t – хоризонтална табулация

\v – вертикална табулация

\0 – нулев байт

\’ – символа „’”

\” – символа „””

\{ и \} – съответно „”{ и „}”

\\ - символа „\”

Константа от тип низ от символи е последователност от символи заградена в кавички. Такива константи се използват често в метода WriteLine, т.е. могат да съдържат управляващи символи, които при извеждане се изпълняват. Допълнително в C# може да се започва с „@”, след което следва низ в кавички. Съдържимото на низовата константа се използва без модификация и може да включва два или повече реда, следователно в този случай могат да се използва управляващи символи за нов ред, табулация и т.н. без да се използват еднобуквените escape означения, но ако трябва да се изведат кавички се задават 2 кавички една до друга.

Console.WriteLine(@“Това е копираща низова константа

която включва

няколко реда”);

Ще се изведе на нов ред. Копиращите низови константи се извеждат в програмата така както са били въведени.

тип списък_от_имена_на_променливи;

„Тип” е произволен тип, включително тези типове, разгледани до сега. Типът определя колко бита се разпределят за стойността на променливата и как се представя тази стойност в C#. Всяка променлива трябва да се дефинира преди да се използва. Това е необходимо тъй като компилатора трябва да знае типа на променливата при компилация на израз, който я използва. Преди да се използва променлива на нея трябва да и се присвои стойност. Това става по два начина:



  • с отделна операция след дефинирането и;

  • при дефиницията и.

Тогава дефиницията има следния общ вид:

тип променлива = израз;

Стойността на израза която се присвоява на променливата трябва да е съвместима с типа и.

Пример:

Пресмятане на обема на цилиндър при зададени радиус и височина.



double radius=4, height=5;

double volume = 3.1416*radius*radius*height;

В израза за инициализация т.е. за присвояване на начална стойност, може да се използва всеки елемент, който преди това вече е бил обявен. Такъв елемент може да е метод, друга променлива или константа.

Както казахме, блокът е последователност от дефиниции и оператори затворени в {}. Той задава областта на видимост като определя възможността за достъп до променлива и нейния живот. Областта на видимост се задава с блока. Променливите могат да се дефинират на произволно място. В блока променливата се създава при дефинирането й и се унищожава в края на блока. Областта на видимост може да се влага – при всяко създаване на блок се създава вложена област като външната област е видима за вътрешната, но обекти от вътрешната не са видими за външната.

Най-важни области на видимост са определени от тези на класа и методите. Тялото на метода е блок. Параметрите на блока имат област на видимост блока – тя е защитена от достъп от извън блока – това е едно от правилата, осигуряващи инкапсулация.

Пример:


using System;

class ScopeDemo

{

public static void Main()



{

int x; //известна в метода Main()

x = 10;

if (x == 10)



{ //видима е в метода Main()

int y = 20;

x = y * 2; //y е видима само вътре

}

y = 100; //грешка



Console.WriteLine("x=" + x);

}

}



Ако променливата се инициализира при нейното дефиниране то тя ще се инициализира всеки път при влизане в блока в който е дефинирана

Пример:


using System;

class VarIniDemo

{

public static void Main()



{

int x;


for (x = 0; x < 3; x++)

{

int y = -1; //y се инициализира всеки път при влизане в блока



Console.WriteLine("y=" + y);

y = 100;


Console.WriteLine("y=" + y);

}

//y=100 се губи при всеки край на интерпретацията в цикъла



}

}

В C# името на променлива, дефинирана във вътрешна област на видимост, не може да съвпада с името на променлива, дефинирана във външната област на видимост. В C/ C++ няма такова ограничение.




5.Операции и изрази
В C# са определени следните операции:

+ - бинарно събиране и унарен +;

- бинарно изваждане и унарен –;



* - умножение;

/ - деление;

% - остатък от целочислено деление;

++ - увеличаване с единица;

–– - намаляване с единица.



+, –, *, / могат да се прилагат на всеки вграден тип данни.

Ако операндите при / са от цял тип, то делението е целочислено. В C# при операцията % операндите могат да са както от цял, така и от float тип.

Операциите ++ и – – могат да се записват както преди операнда, така и след него като постфикс.

++x и x++ са еквивалентни на x=x+1

– –x и x– – са еквивалентни на x=x – 1

Ако след тези операнди в израз се изпълняват и други операции тогава ++x и x++ се различават. Ако операцията е преди операнда то C# променя с единица променливата преди да се използва в останалата част от израза.

int x, y;

x = 10;


y = ++x; //x=x+1; y=x;

Но ако операцията е след операнда, то C# променя с единица стойността на операнда след като тази променлива е използвана в останалата част на израза.

y=x++; //y=x; x=X+1;

В C# се използват следни операции за сравнение:



==, !=, <, >==, >, <=;

& - and, логическо „и” (логическо умножение);

| - or, логическо „или” (логическо събиране);

^ - xor;

&& - бърза операция „и” (short-circuit and);

|| - бърза операция „или” (short-circuit or);

! – not.

Резултатът от изпълнението на операциите за сравнение и на логическите операции е стойност от тип bool.

В C# операциите == и != могат да се прилагат с всички обекти. Операциите за сравнение могат да се прилагат към типове, чиито стойности са наредени, следователно те могат да се прилагат към всички числови типове данни, но те не могат да се прилагат към стойности от булев тип false и true, тъй като те в C# не са наредени (в C/ C++ false

За логически операции операндите трябва да са от булев тип. Бързите операции пресмятат (оценяват) втория операнд само тогава, когато резултатът от изпълнението на операцията не може да се определи единствено с пресмятане на първия операнд.

Ако при изпълнение на операцията && първият операнд има стойност false, то резултатът ще е false независимо от стойността на втория операнд. При || ако първия операнд има стойност true, то резултатът ще е true независимо от втория операнд. Съществува разлика между & и | и && и ||. Тя се изразява в това, че при обикновените операции винаги се оценяват и първия и втория операнд. При бързите втория се оценява само при необходимост. В общия случай използването на && и || води до по-бързо изпълнение на програмата.

Ще разгледаме пример при който използването на && води до предотвратяване на деление на 0.

int n,d;

If(d!=0 && (n%d)==0)



{

Console.WriteLine(d+” е делител на ”+n);

}

//Понякога в операциите and и or винаги трябва да се оцени втория операнд”



int i=0; bool p;

If(p & ++i<100)



{

Console.WriteLine(“i=”+i);

}

Операцията за присвояване:



променлива = израз;

Типът на променливата трябва да е съвместим с типа на израза.

int x, y, z;

x = y = z = 34 + 66;

В C#, както и в C/C++, се използват съставни операции за присвояване с общ вид:

променлива операция=израз;

Те са съвместими с операциите +, –, *, /, %, &, |, ^.

Съставните операции имат две преимущества: те се записват по-кратко и се компилират по-бързо. Ако типовете на операндите при операция = са различни, то типа на израза от дясно се преобразува автоматично към типа на променливата отляво при условие че са изпълнение следните изисквания:



  1. двата типа са съвместими;

  2. допустимата стойност на типа от ляво обхваща допустимата стойност на типа от дясно (преобразуването е разширяващо).

Числените типове са съвместими помежду си. Числените типове bool, char и decimal не са съвместими помежду си.

long L;


double D;

D=L;//автоматично преобразуване от long в double

L=D;//не може автоматично (преобразуването не е разширяващо)

Когато не може да се извърши автоматичното преобразуването се използва явно преобразуване с помощта на операция, която има следния вид:

(тип)израз; – при изпълнение типа на израза се преобразува към „тип”

double x, y;

byte b;

int i;


char ch;

x=10.0;


y=3.0;

i=x/y; //грешка

i=(int)(x/y); //свиващо преобразуване към цяло число – реже се дробната част

b=(byte)i;

ch=(char)b; //между ch и b няма съвместимост

Израз в C# е синтактично и семантично допустима комбинация от константи, променливи, операции, обръщения към функции и методи и кръгли скоби. Съществува възможност в един израз да се използват две или повече различни типове данни, ако те са съвместими. Например в един израз могат да се използват данни от тип short и от тип long, тъй като са числени и съвместими. Различните типове се преобразуват към един и същи тип в съответствие с правилата за автоматично преобразуване на типовете в израз.

Ще разгледаме алгоритъма за преобразуване определен от аритметичните операции:


  1. Ако единия операнд е от тип decimal, то другия също се преобразува с изключение на long или double. Тогава възниква грешка.

  2. Ако единия операнд е double, то другия се преобразува към тип double.

  3. Ако единия операнд има тип float, то и другия се преобразува към float.

  4. Unsigned long – другия се преобразува към ulong, освен когато е short, long, signed byte или int. В такъв случай дава грешка.

  5. Long – другия се преобразува към long.

  6. Unsigned int, а другия signed byte, short, int – и двата стават long.

  7. Unsigned int – другия се преобразува към unsigned int.

  8. Ако от правилата от 1 до 7 не са приложими и двата стават int.

Ще обърнем внимание на някой моменти от алгоритъма. Не всички типове данни са съвместими, например: float или double в decimal или signed целочислена в unsigned long. За съвместяването трябва да се cast-ват. От последното правило следва, че всички стойности в един израз от тип char, sbyte, byte, short, ushort се преобразуват към int. Това означава, че за резултатът ще се разпределя памет, не по-малка от тази за int. Операндите при унарните операции, чиито диапазон е по-малък от този на int, стават на int. Освен това ако на операнд от тип unsigned int се присвои стойност по-малка от 0 , той се преобразува към long.

byte b; int i;

b=10;

i=b*b;


b=(byte)(b*b);

char ch1=’a’, ch2=’b’;

ch1=(char)(ch1+ch2);

int broi, suma;



double sr_uspeh;

….

sr_uspeh = (double)(suma/broi);


Таблица на приоритетите и асоциативността на операциите:

Операция

асоциативност

( ) [ ]

->

Постфиксно ++ и --

<-

! +(унарен) –(унарен)

(тип) префиксно ++ и --



<-

* / %

->

+ -

->

< <= > >=

->

== !=

->

&

->

^

->

|

->

&&

->

||

->

Операция =

<-

Програма за пресмятане на сумите за ежемесечно изплащане по взет кредит

using System;

class RegPay

{

public static void Main()



{

decimal Principal, IntRate, PayPerYear, NumYears, Payment;

decimal numer, denom;

double b, e; //b->oснова e->степенен показател в Pow()

Principal=10000.00m; //размер на кредита

IntRate=0.075m; //7.5% лихва

PayPerYear=12m; // изплащания на годинa

NumYears=5m; //срок за погасяване на кредита в години

numer=IntRate*(Principal/PayPerYear);

e=(double)-(PayPerYear*NumYears);

b=(double)(IntRate/PayPerYear) + 1;

denom=1-(decimal)Math.Pow(b, e);

Payment=numer/denom;

Console.WriteLine(“Сума за ежемесечно изплащане: {0:C}”, Payment);

}

}

В тази програма се извършват финансови пресмятания. Затова се използва тип decimal. Също така се демонстрира използването на операцията за явно преобразуване на типа и метода Pow от библиотеката на С#. Този метод реализира операцията повдигане в степен като и двата аргумента трябва да са от тип double и връщания резултат е от тип double.




6. Условни оператори if и switch
Ще разгледаме как в С# може да се работи в итеративен режим. За четене на символи от клавиатурата е необходимо да се извика метода

Console.Read();

който изчаква въвеждането на символ от клавиатурата и след това връща резултат. Резултатът е от цял тип, затова той трябва да се преобразува явно в тип char. По подразбиране, реда, въведен от клавиатурата, се записва в буфер след натискане на enter. Например:

char ch;

ch=(char)Console.Read();

Console.WriteLine(“Въведеният символ е:” + ch);

Символът enter също се въвежда в буфера.

Условният оператор if има следния общ вид:

if (израз) оператор1 [оператор2] //оператор2 може да го няма




Фиг.1

Изразът „израз” трябва да има булева стойност. Оператор 1 и оператор 2 могат да бъдат съставен оператор или блок. Те могат да бъдат и друг условен оператор, при което се получава влагане на условни оператори if. При това влагане е възможно не еднозначно тълкуване, което се отстранява от следното правило: текста на вложените оператори if се превежда отляво надясно като всяко срещнато else се съчетава в един оператор с най-близкото преди него несъчетано if след оператора или блока, на който if е разположен else. Пример:

if (i == 10)

{

if (j < 20)



a = b;

if (k > 100)

c = d;

else


a = c;

}

else



а = d;

Препоръчва се влагането на if да става след else. Пример:

if (e1)

S1;


else if (e2)

S2;


….

else if (en)

Sn;

else


Sn+1;

Изразите се оценяват от горе надолу. При намиране на първия израз със стойност true, се изпълнява асоциирания с него оператор, а останалата част се пропуска. Ако нито един от изразите не приема стойност true, то се изпълнява Sn+1. Ако той отсъства и всички изрази имат стойност „неистина”, то вложеният if не изпълнява никакви действия, т.е. той е еквивалентен на празния оператор. Пример:

int x;

double y;



if (x==1)

y=5*y+6;

else if (x==2)

y=y*y+2*y-1;

else if (x==3)

y=Math.Pow(y, 5);

else


y=0;

Принципите на работа на вложения if и на оператора за избор на вариант switch се различават, затова в много случаи, използването на switch е по-ефективно. switch съществено се различава от същия в С++. Общ вид на switch

switch (израз_селектор)

{

case израз1 : оператори



break;

case израз2 : оператори

break;

………………


case “изразn” : оператори

break;


default: оператори

break;


}

Изразът селектор трябва да е от цял тип – char, byte, short или int или от тип string, който ще разгледаме по-нататък. Изразът селектор не може да бъде с плаваща точка. Много често той е променлива. израз1, израз2, …, изразn са константни изрази и имат тип, съвместим с типа на израза селектор. Тези изрази в един блок трябва да имат различно стойности. При изпълнение на оператор switch, стойността на израза селектор последователно се сравнява със стойностите на константните изрази от списъка. При съвпадение се изпълняват операторите, асоциирани със съответния константен израз. Операторите след default се изпълняват тогава, когато няма съвпадения на израза селектор с нито един от константните изрази. Вариантът default не е задължителен. Ако той отсъства, тогава switch е еквивалентен на празния оператор. Операторът break е задължителен ( !!! ) и изпълнението му предава управлението на оператора след switch. В С# е забранено предаването на управлението между отделните варианти, т.е. алтернативи. Това позволява по-ефективна работа на компилатора и на съставената от него програма. В С/С++ и Java един вариант може да предава управлението на друг вариант.

В С#, както в С/С++ две и повече алтернативи могат да бъдат свързани с една и съща последователност от операции. Например:

switch(i)

{

case 1:


case 2:

case 3:


оператори

break;


case 4:

оператори

break;

}

Вложеният оператор if се използва вместо оператор switch, когато условията за избор на вариант е трудно или невъзможно да се запишат в switch. Например, когато в условията е удобно да се използват операции за сравнения, различни променливи и различни типове, стойности с плаваща точка или проверка на обекти от други типове. Например:



double x, y;

bool done;

if (x<10)



else if (y!=0)

else if (!done)



Операторът може да бъде част от външен оператор, вътрешният оператор се нарича вложен. Константните изрази на алтернативи на вътрешния и външния оператор switch могат да имат еднакви стойности и това няма да доведе до конфликтни ситуации при изпълнение на програмата.




7. Оператори за цикъл for, while и do while
Операторът за цикъл for има следния общ вид:

for (израз1; израз2; израз3)

Оператор

Обикновено израз1 инициализира управляващата променлива на цикъла, израз3 задава стъпката, с която се изменя управляващата променлива при всяко изпълнение на тялото на цикъла. Условието за продължаване на цикъла се проверява преди изпълнението на тялото на цикъла. Затова тялото на цикъла може да не се изпълни нито веднъж. Да съставим програма, която пресмята корен квадратен на числата от 1 до 99 и направената грешка при това пресмятане.

using System;
class SqrRoot

{

static void Main()



{

double num, sroot, rerr;

for (num = 0; num < 100; num++)

{

sroot = Math.Sqrt(num);



Console.WriteLine("Корен квардатен от{0} е {1}", num, sroot);

rerr = num - sroot * sroot;

Console.WriteLine("Грешката е равна на" + rerr);

Console.WriteLine();

}

}

}



Грешката е резултат от грешката на метода и грешката на закръгляне.

Операторът за цикъл for може да съдържа няколко управляващи променливи. Например:

for (int i=0, j=10; i

оператор


Всеки един от израз1, израз2 и израз3 могат да бъдат пропуснати, но „;” се запазва. Пропускането на израз2 означава, че условието е изълнено.

for (;;) //безкраен цикъл

оператор

Тялото на цикъла може да бъде празния оператор. Например – пресмятане сумата на числата от 1 до 5:

for (int i=0; i<=5; suma+=i++);

Много често управляващата променлива се използва само в рамките на оператора за цикъл. Тогава е удобно тя да бъде дефинирана при нейната инициализация в израз1. Например:

int fact=1, n;

for (int i=1; i

fact*i;

Видимостта на управляващата променлива, която е дефинирана в оператора for, е ограничена в рамките на този оператор. Извън границите на цикъла променливата е неизвестна.

Операторът за цикъл while има следния общ вид:

while (израз)



Оператори;

Условието за продължаване на цикъла се проверява преди изпълнението на тялото на цикъла.Следователно тялото на цикъла може да не се изпълни нито веднъж.

char ch;

while(ch<=’z’)

{

Console.Write(ch+ “ “);



ch++;

}

using System;



class Power

{

public static void Main()



{

int e;


int result;

for (int i = 0; i < 10; i++)

{

result = 1;



e = i;

while (e > 0)

{

result *= 2;



e--;

}

Console.WriteLine("2 на {0} степен = {1}", i, result);



}

}

}



Операторът за цикъл do while има следния общ вид:
do

Operator


while ( израз)

„Израз” е булев. Операторът се изпълнява по следния начин:



Тук условието се проверява след като е изпълнено тялото на цикъла. Следователно, то се изпълнява поне веднъж. Пример за продължаване на цикъла докато не бъде въведен символ ‘q’:

char ch;

do

{



Console.WriteLine("Въведете символ: ");

ch = (char)Console.Read();

}

while (ch != 'q');



При натискане на enter се въвеждат символите ‘\r’ и ‘\n’. Тези символи могат да бъдат игнорирани по следния начин:

char ch;


do

{

Console.WriteLine("Въведете символ: ");



ch = (char)Console.Read();

}

while (ch != '\n' || ch!=’\r’);



Вече разгледахме един пример, в който един цикъл е вложен в друг цикъл. Сега ще разгледаме друг пример на вложени цикли, в който се намират делителите на целите числа, които са в диапазона от 2 до 100.

using System;


class FindFac

{

public static void Main()



{

for (int i = 2; i <= 100; i++)

{

Console.Write("Делители на {0} са : ", i);



for (int j = 2; j < i; j++)

{

if (i % j == 0)



{

Console.Write("{0} ,", j);

}
}

Console.WriteLine();

}

}

}


Обикновено цикъл for се използва, когато предварително е известен броя на повторенията на тялото на цикъла. Цикълът do while – когато е необходимо поне едно изпълнение на тялото на цикъла, а while е най-ефективен в тези случаи, когато броят на повторенията на тялото на цикъла предварително не е известен.



Каталог: files -> lekcii
files -> Рецептура на лекарствените форми рецептурни бланки и тяхната валидност
files -> Прогностични възможности на тестовете, използвани за подбор на млади футболисти
files -> Правила за реда за ползване, стопаниване и управление на стадион "христо ботев" благоевград глава първа общи положения
lekcii -> Е п и с к о п к о н с т а н т и н п р е с л а в с к и
lekcii -> Лекции на IV курс, уктц правец Съдържание Подпрограми в паскал 3 Дефиниране на подпрограми 3
lekcii -> C# изборна дисциплина


Сподели с приятели:
1   2   3   4   5




©obuch.info 2024
отнасят до администрацията

    Начална страница