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


Масиви. Оператор за цикъл foreach



страница4/5
Дата27.09.2016
Размер0.88 Mb.
#10986
1   2   3   4   5
12. Масиви. Оператор за цикъл foreach
Масивът е n-мерна наредена съвкупност от елементи от един и същи тип. Масивите могат да бъдат едномерни, двумерни, тримерни и т.н. макар че най-често се използват едномерните. С указване името на масива и индекси може да се използва съответния елемент на масива. Данните в масива са организирани така, че те лесно и удобно да бъдат обработвани. Масивите в С# имат една особеност, която се състои в това, че те са реализирани като обекти. Това дава допълнителни възможности, например отстраняване от паметта на неизползваните масиви при събиране на боклука. Дефинирането на едномерен масив има следния общ вид:

тип[] име_на_масива = new тип[размер];

Тук „тип” задава типа на данните на всеки елемент на масива. [] указват, че се дефинира едномерен масив. „Размер” определя броя на елементите на масива. Тъй като масива е реализиран като обект, то процесът на създаване на масива включва два етапа. На първия етап се обявява името на масива като променлива от указателен тип. На втория етап – за масива се разпределя памет и на името на масива се присвоява адреса на тази област от паметта, т.е. в С# с помощта на new се разпределя динамична памет за масива. При дефиниране на масива в С# [] са след „тип”, а не след името на масива, както е в С/С++. Например:

int[] sample = new int[10];

Се дефинира масива sample, който се състои от 10 елемента от тип int. Това може да стане и така:

int[] sample;

sample = new int[10];

В този случай, след дефинирането на променливата на масива sample, тя няма да сочи към физически обект. Само след изпълнението на втория оператор, на sample ще се присвои адреса на масива. Достъпът до отделен елемент на масива се осъществява с използване на индекс. Първият елемент на всички масиви в С# има нулев индекс. Например:

int[] sample;

sample = new int[10];

int i;


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

sample[i] = i;

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

Console.WriteLine("На елемента sample[{0}] е била присвоена стойност = {1}", i, sample[i]);

Да съставим програма за намиране на минималната и максимална стойност на елементите на масив.

using System;


class MinMax

{

public static void Main()



{

int[] nums = new int[10];

int min, max;

nums[0] = 99;

nums[1] = -10;

nums[2] = 100123;

nums[3] = 18;

nums[4] = -978;

nums[5] = 5623;

nums[6] = 463;

nums[7] = -9;

nums[8] = 287;

nums[9] = 49;

min = max = nums[0];

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

{

if (min > nums[i])



min = nums[i];

if (max < nums[i])

max = nums[i];

}

Console.WriteLine("Най-големият елемент в масива е {0}, а най-малкият е {1}", max, min);



}

};

В този пример стойностите на елемента на масива nums бяха зададени ръчно с използване на 10 отделни оператора за присвояване. Съществува по-ефективен начин за изпълнение на тези действия. Масива може да се инициализира веднага при неговото създаване. Инициализирането на едномерен масив има следния общ вид:



тип[]име_на_масива={стойност1, стойност2, … , стойностN};

На елементите на масива, започвайки от първия, т.е. с индекс 0, се присвояват зададените стойности от ляво на дясно. В С# за масива автоматично се разпределя памет, достатъчна за съхраняване на зададените стойности, без да е необходимо явно да се използва операцията new. Да съставим по-ефективно предната програма:

using System;
class MinMax

{

public static void Main()



{

int min, max;

int[] nums = { 99, -10, 100123, 18, -978, 5623, 463, -9, 287, 49 };

min = max = nums[0];

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

{

if (min > nums[i])



min = nums[i];

if (max < nums[i])

max = nums[i];

}

Console.WriteLine("Най-големият елемент в масива е {0}, а най-малкият е {1}", max, min);



}

};

Зададените стойности се присвояват на елементите на масива при неговото създаване. Инициализирането на масива nums може да стане и с използване на операцията new, но това не е необходимо. Това става така:



int[] nums = new int[]{ 99, -10, 100123, 18, -978, 5623, 463, -9, 287, 49 };

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

int[] nums;

nums=new int[]{ 99, -10, 100123, 18, -978, 5623, 463, -9, 287, 49 };

В този случай променливата на масива nums се дефинира в първия оператор, а се инициализира във втория.

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

int[] sample = new int[10];

int i;


for (i = 0; i < 100; i++) //генерира се обект изключение IndexOutOfRangeException()

sample[i] = i; //и завършва изпълнението на програмата

Ще непишем програма за сортировка, реализираща метода на мехурчето. Този метод може да се използва за не големи масиви, но става неефективен при сортиране елементите на големи масиви.

using System;


class Bubble

{

public static void Main()



{

int[] nums = { 99, -10, 100123, 18, -978, 5623, 463, -9, 287, 49 };

int i, pos, temp;

int size;

bool change;

size = 10;

pos = 1;

do

{



change = false;

for (i = 0; i < size - pos; i++)

{

if (nums[i] > nums[i + 1])



{

temp = nums[i];

nums[i] = nums[i + 1];

nums[i + 1] = temp;

change = true;

}

}



pos++;

} while (change);

Console.WriteLine("\nМасивът след сортирането:");

for (i = 0; i < size; i++)

Console.Write(" " + nums[i]);

Console.WriteLine();

}

}

Многомерните масиви имат две или повече размерности, а достъпът до техните елементи се осъществява с два или повече индекса. Двумерният масив може да се разглежда като информационна таблица или матрица, като единият индекс дава номер на ред, а другият – номер на стълб. Например, двумерният цял масив table с размерност 10х20 се дефинира така:



int[,]table = new int[10, 20];

Броят на елементите на масива е равен на произведението от горните граници на размерностите, т.е. 10х20=200. В първата част на дефиницията, с помощта на запетая в квадратните скоби, се указва, че се създава променлива от указателен тип за двумерен масив. Разпределяне на памет за масива с new става при изпълнение на втората част от дефиницията на масива, като горните граници на размерностите са разделени със запетаи. За получаване на достъп до елемент на двумерен масив е необходимо да се зададат два индекса, разделени със запетаи. Например:



table[3, 5]=10;

В С# дефинирането и достъпът до елементите на неедномерните масиви се различава от това в С/С++ и Java. При тях всяка размерност на масива и индексите се задават в отделни квадратни скоби. Да разгледаме програма, в която на елементите на двумерен масив се присвояват стойности от 1 до 12 и след това тези стойности се извеждат на екрана.

using System;

class TwoD

{

public static void Main()



{

int t, i;

int[,] table = new int[3, 4];

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

{

for (i = 0; i < 4; i++)



{

table[t, i] = t * 4 + i + 1;

Console.Write(table[t, i] + " ");

}

Console.WriteLine();



}

}

};



Дефинирането на многомерен или n-мерен масив има следния общ вид:

тип[, …, ] име =new тип[размер1, …, размерN];

Например, при:

int[, ,] MD = new int[4, 10, 4];

Ще бъде създаден тримерен масив с размерност 4х10х3, или 120 елемента. Примерно присвояване:

MD[2, 4, 1] = 100;

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



тип[,]име={ {стойност, стойност, …, стойност}, {стойност, стойност, …, стойност}, …, {стойност, стойност, …, стойност} };

Блоковете, съдържащи стойности са разделени със запетаи, а най-накрая има ;. Всеки вътрешен блок присвоява стойности на елементите от съответния ред. В рамките на реда, първата стойност ще се присвои на елемента от ред с индекс 0, втората – с индекс 1 и т.н. Пример:

int[,]ex={{1, 1}, {2, 4}, {4, 5}, {5, 6}, {1, 1}, {8, 64}};

Разгледаните двумерни масиви мога да бъдат наречени правоъгълни или изравнени масиви, тъй като те имат редове с еднаква дължина. В С# могат да бъдат създавани и двумерни, неизравнени масиви. Те представляват външен масив, който се състои от вътрешни масиви с различна дължина. Следователно, неизравненият масив може да се използва за създаване на таблица, съдържаща редове с различна дължина. При дефиниране на неизравнен масив, за задаване на всяка размерност, се използва отделна двойка квадратни скоби. Например, двумерен, неизравнен масив се дефинира по следния начин:



тип[][]име_на_масива=new тип[брой_редове][];

Размерът на редовете не се задава и памет за тях не се разпределя. /*:D:D:D:D */ За всеки ред е необходимо изпълнение на отделна операция new. Тази технология позволява да се определят редове с различна дължина. Например:

int[][] array = new int[3][];

При дефиниране на масива array памет се разпределя само за външния масив.

array[0] = new int[2];

array[1] = new int[3];

array[2]=new int[4];

При изпълнение на тези три оператора, памет се разпределя отделно за всеки вътрешен масив. Когато неизравнения масив е създаден, достъпът до неговите елементи се получава като се зададе всеки индекс в двойка квадратни скоби. Например:

array[2][1]=10;

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

Когато стойността на една променлива от указателен тип, която сочи към масив, се присвоява на друга променлива от този тип, то на втората променлива се присвоява адреса на същия масив, към който сочи първата. При това не се създава копие на масива и не се копира съдържанието на единия масив в другия. Да разгледаме един пример:

int i;


int[] nums1 = new int[10];

int[] nums2 = new int[10;

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

nums1[i]=i;

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

nums2[i]=-i;

nums2=nums1; //сега nums2 сочи към същия масив, какъвто е nums1

nums2[3]=99; //фактически се прави промяна на nums1[3]

В С# масивите са реализирани като обекти и това два определени преимущества при работа с тях. Едно такова преимущество е възможността да се използва свойството Length, което съдържа информация за максималния брой елементи на масива. Ще разгледаме пример за копиране на един масив във друг с използване на свойството Length:

using System;

class ACopy

{

public static void Main()



{

int[] nums1 = new int[10];

int[] nums2 = new int[10];

for (int i = 0; i < nums1.Length; i++)

{

nums1[i] = i;



}

if (nums2.Length >= nums1.Length) //проверява се дали позволява размера

//на масива nums2 да се прекопират

{ //всички елементи на масива nums1

for (int i = 0; i < nums1.Length; i++)

{

nums2[i] = nums1[i];



}

}

for (int i = 0; i < nums1.Length; i++)



Console.WriteLine(nums2[i]+" ");

}

};



Свойството Length позволява да се създава код, който може да работи с масиви с различна дължина. Това опростява алгоритмите и ги прави по-ефективни.

Особено внимание трябва да се обърне на използване на свойството Length в двумерни, неизравнени масиви. Например:

int[][] table = new int[3][];

table[0] = new int[] { 1, 2, 3 };

table[1] = new int[] { 4, 5 };

table[2] = new int[] { 6, 7, 8, 9 };

table.Length; //дава броя на масивите, които се съдържат в масива table, т.е.3

//за да се получи дължината на всеки вътрешен масив,

//във външния масив е необходимо да се използва следния израз:

table[0].Length; //3

table[1].Length; //2

table[2].Length; //4

Пример за последователно опашка реализирана чрез масив:

using System;

class Queue

{

public char[] q;



public int putloc, getloc;

public Queue(int size)

{

q = new char[size+1];



putloc=getloc=0;

}

public void put(char ch)



{

if(putloc==q.Length-1)

{

Console.WriteLine(“Opa6kata e zapalnena”);



return;

}

putloc++;



q[putloc]=ch;

}

Public char get()



{

if(getloc==putloc)

{

Console.WriteLine(“Opa6kata e prazna”);



return (char)0;

}

getloc++;



return q[getloc];

}

}


class QDemo

{

public static void Main()



{

Queue Q = new Queue(26);

char ch;

int i;


for(i=0; i<26; i++)

Q.put((char)(‘A’+i));

Q.put(‘Z’);

for(i=0; i<26; i++)

{

ch==Q.get();



if(ch!=(char)0)

Console.Write(ch);

}

Conslole.WriteLine();



Ch=Q.get();

}

}



Оператора foreach се използва за обработка на елементи от колекции. Колекцията е набор от обекти. Масива е една от пиковите колекции в C#. Оператора за цикъл foreach има следния прототип:

foreach (тип име_на_итерационна_променлива in колекция)

оператор;

При изпълнение на цикъла итерационната променлива ще приема за стойности елементите на колекцията. Типа на итерационната променлива трябва да е съвместим с типа на колекцията, например масива. При работа с масиви итерационната променлива е достъпна само за четене. Следователно оператора за цикъл foreach не може да се използва за присвояване на нови стойности на елементите на масива. Също така, не може да се осъществява достъп до елементите на масива в обратен ред. Пример:

using System;

class ForeachDemo

{

public static void Main()



{

int suma = 0;

int[] nums = new int[10];

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

nums[i] = i;

foreach(int x in nums)

{

Console.WriteLine(“Stoinosta na elementa na masiva=” + x);



suma+=x;

}

Console.WriteLine(“Sumata ot stoinostite na vsi4ki elementi na masiva=” + suma);



}

}

От резултата на изпълнението на програмата се вижда, че при достъпа на елементите на масива, индекса нараства. С помощта на foreach могат да се обработват многомерни масиви. Достъпът на елементите е по редове. От първия до последния елемент в реда.



using System;

class ForeachDemo

{

public static void Main()



{

int suma = 0;

int[,] nums = new int[3,5];

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

for(int j=0; j<5; j++)

nums[i,j]=(i+1)*(j+1);

foreach(int x in nums)

{

Console.WriteLine(“Stoinosta na elementa na masiva=” + x);



suma+=x;

}

Console.WriteLine(“Sumata ot stoinostite na vsi4ki elementi na masiva=” + suma);



}

}

Да използваме foreach за намиране на минималната и максималната стойност в масив:



using System;

class MinMax

{

public static void Main()



{

int[] nums = {99, -10, 100123, 18, -978, 5623, 463, 287, 49}

int min,max;

min=max=nums[0];

foreach(int value in nums)

{

if(value

min=value;

if(value>max)

max=value;

}

Console.WriteLine(“Min=” + min + “Max=” + max);



}

}

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




13. Низове
В C# низовете са обекти, т.е. типът от данни string в C# е указателен тип. В много други езици за програмиране, например C и C++, низът е символен масив. При създаване на константа от тип низ от символи, фактически се създава обект от тип string. Тъй като класът string е достатъчно голям, ние ще разгледаме само основните му характеристики. Най-простия начин за създаване на обект от тип string е използване на константа от тип низ от символи. Например:

string str = "tova e konstanta ot tip niz ot simvoli";

Тук променливата str е от указателен тип string, на който се присвоява адреса на константата от тип низ от символи. Може също да се зададе обект от тип string, като се използва масив от тип char. Например:

char[] str1={'t', 'e', 's', 't'};

string str2 = new string(str1);

След създаване на обект от тип string той може да се използва в програмата навсякъде, където може да се използва константа от тип низ от символи. Например, като аргумент в метода WriteLine:

Console.WriteLine(str2);

Сега ще разгледаме някои от методите на класа string:



- static string Copy (strig str) – Връща копие на променливата str.

- int CompateTo(string str) – Връща число < 0 , ако стойността на извикания низ е по-малка от стойността на променливата str. Връща число > 0, ако стойността на извикания низ е по-голяма от стойността на променливата str и връща 0, ако низовете са равни.

- int IndexOf(string str) – Този метод извършва търсене в извикващия низ на подниза, зададен като параметър str. Връща индекса на позицията в извиквания низ, където за първи път е открит подниза или стойност – 1, ако поднизът не е открит.

- int LastIndexOf(string str) – Този метод извършва търсене в извикващия низ на подниза, зададен като параметър str. Връща индекса на позицията в извиквания низ, където за последен път е открит подниза или стойност – 1, ако поднизът не е открит.

Обектите от тип string също имат свойството Length, съдържащо информацията за дължината на низа. За получаване на стойностa на отделен символ на низа е необходимо да се използва неговия индекс. Например:

string str = "test";

Console.WriteLine(str[0]); // - 6te se izvede patviq simvol 't';

Както и масивите, първия елемент на низа има индекс 0, но използването на индекс за присвояване на нова стойност на символ от низа е забранено. Индекса може да се използва само за получаване на символа. За сравняване на два низа може да се използва операцията ==. Обикновено, когато тази операция се използва за променлива от указателен тип, тя определя дали те соча към един и същи обект. Когато операцията == се прилага към две променливи от указателен тип string, то се проверява съдържанието на самите низове. Същото е вярно и за оператора !=, когато той се използва са сравняване на обекти от тип string, обаче другите операции за сравнение, сравняват стойностите на променливите от указателен тип string, както работят с обекти от други типове. Ще разгледаме програма , която демонстрира използването на някои от операциите с низове:

using System;

class StringOperations

{

static void Main()



{

string str1 = "използване на операции с низове ";

string str2 = string.Copy(str1); // pravi se kopie

string str3 = " това е константа от тип низ от символи ";

int result, idx;

Console.WriteLine("Дължината на низа str1 = " + str1.Length + " символ ");

for (int i = 0; i < str1.Length; i++)

Console.WriteLine(str1[i]);

Console.WriteLine();

if (str1 == str2)

Console.WriteLine("str1 == str2");

else


Console.WriteLine("str1 != str2");

result = str1.CompareTo(str3);

str2 = "ЕдноДвеТриЕдно";

idx = str2.IndexOf("Едно");

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

idx = str2.LastIndexOf("Едно");

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

}

}



С помощта на оператора + може да се конкатенират низове. Например:

string str1 = "Конка";

string str2 = "тен";

string str3 = "ация";

string str4 = str1 + str2 + str3;

Елементите на масив могат да бъдат низове. Да разгледаме пример на масив с елементи низове:

using System;

class StringArrays

{

public static void Main()



{

string[] str = {"това е ", " пример", "за", "низов", "масив." };

Console.WriteLine("Първоначален масив: ");

for (int i = 0; i < str.Length; i++)

Console.WriteLine(str[i]);

Console.WriteLine();

str[1] = "също";

str[2] = "масив от";

str[3] = "низове";

Console.WriteLine("Променен масив: ");

for (int i = 0; i < str.Length; i++)

Console.WriteLine(str[i]);

Console.WriteLine();

}

}



При работа с низове трябва да се обърне внимание на една много важна характеристика на обектите от тип string. Веднъж създадена последователността от символи в низа, тя не може да бъде променяна. Въпреки, че такова ограничение на пръв поглед изглежда като сериозен недостатък, но в действителност не е така. Когато ни потрябва низ, различен от съществуващия, то просто се създава нов низ, съдържащ необходимите изменения. Тъй като неизползваните низови обекти автоматично се отстраняват от паметта по време на „събиране на боклука”, то старите низове ще бъдат, незабелязано за потребителя отстранени. Стойността на променливата от указателен тип, която сочи към обект от тип string, безусловно може да бъде променена, но след създаване на нов обект от тип string неговото съдържание не може да се променя.

За изменение на низ се използва метода Substring(), връщащ нов низ, който съдържа копие на указана част от извикващия низ. Тъй като се създава нов обект от тип string, съдържащ подниз, то първоначалният низ остава непроменен. Методът Substring() има следния общ вид:

string Substring(int начален_индекс, int дължина)

Пример:


using System;
class Substring

{

public static void Main()



{

string orgstr = "registraciq";

string substr1 = orgstr.Substring(0, 7);

Console.WriteLine(substr1);

string substr2 = orgstr.Substring(6, 5);

Console.WriteLine(substr2);

}

}

В С# е включен клас StringBuilder, който се намира в пространството от имена System.Text, освен този клас се създават низови обекти, които могат да бъдат изменяни.




14. Побитови операции. Операция ?
Побитовите операции се извършват непосредствено с битовете на своите операнди. Операндите на побитовите операции могат да бъдат само целочислени стойности. Тези операции не могат да се използват за стойности от тип bool, float или double и за обекти от класове. Побитовите операции се използват за проверка за установяване или изместване на битовите, които съставят целочислените стойности. Побитовите операции са важни за решаване на много задачи при системното програмиране. Например, когато е необходимо да се получи информация за състоянието на устройство. Побитовите операции са:

& - AND - логическо умножение / и

| - OR – логическо събиране / или

^ - XOR – събиране по модул 2 / изключващо или

>> - побитова операция за изместване надясно

<< - побитова операция за изместване наляво

~ - побитова унарна операция NOT

С помощта на побитовата операция AND могат да се анулират битове, т.е. ако някой бит в единия от операндите има стойност 0, то и съответния му бит в резултата винаги има стойност 0. Да разгледаме един пример (преобразуване на малки в главни латински букви):

using System;

class UpperCase

{

public static void Main()



{

char ch;


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

{

ch = (char)('a' + i);



Console.WriteLine(ch);

ch = (char)(ch & 65503);

Console.WriteLine(ch);

}

}



}

Побитовата операция & също се използва, когато е необходимо да се получи стойността на определен бит. Например, ако искаме да получим стойността на 4ти бит, трябва да имаме 00001000, пр.:

Console.WriteLine(status & 8);

Този подход се използва в следващата програма за извеждане на екрана на двоичното представяне на стойности от тип byte.

using System;
class showBits

{

public static void Main()



{

int t;


byte val = 123 ;

for (t = 128; t > 0; t /= 2)

{

if ((val & t)!=0)



Console.Write("1");

else


Console.Write("0");

}

}



}

Обратно на операцията &, побитовата операция | може да се използва за задаване на стойност 1 на отделен бит. Ако поне в единия от операндите е даден бит 1, то съответния бит в резултата е също 1.

Ще разгледаме програма, която преобразува главна в малка латински букви:

using System;


class LowerCase

{

public static void Main()



{

char ch;


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

{

ch = (char)('A' + i);



Console.WriteLine(ch);

ch = (char)(ch | 32);

Console.WriteLine(ch);

}

}



}

При изпълнение на ^, даден бит в резултата получава стойност 1, само когато съответните битове в операндите са различни. Операцията ^ има едно много интересно свойство, което позволява да се използва кодиране на съобщения.

R1=X^Y;

R2=R1^Y;


Сега R2 има същата стойност като Х, т.е. резултатът от последователното изпълнение на две операции ^ с използването на една и съща стойност, ще бъде първия операнд. Тази стойност се използва като ключ, или шифър, при кодирането и разкодирането на дадено съобщение.

using System;


class Encode

{

public static void Main()



{

string msg = "Съвършено секретно! Агент Тенев";

string encmsg = "";

string decmsg = "";

int key=123;

Console.WriteLine("Първоначално съобщение: {0}", msg);

for (int i = 0; i < msg.Length; i++)

encmsg+=(char)(msg[i]^key);

Console.WriteLine("Кодирано съобщение: {0}", encmsg);

for (int i = 0; i < msg.Length; i++)

decmsg += (char)(encmsg[i] ^ key);

Console.WriteLine("Декодирано съобщение: {0}", decmsg);

}

}

Унарната побитова операция ~ променя всички битове в операнда.



В С# съществува възможност битовите на целочислена стойност да се изместват наляво или надясно на зададен брой позиции. Определени са две операции: >> и <<. Те имат следния общ вид:

Операнд<<бр_битове;

Операнд>>бр_битове;

Изместване наляво води до изместване на всички битове на операнда наляво с указания бтой позиции, като освободилите се младши битове се запълват с 0, а съответния брой старши се губят. Аналогично и за изместването надясно. Ако надясно се изместват битовете на стойност без знак, то старшите се запълват с 0, а съответния брой младши се губят. Ако надясно се изместват битовете с знак, то старшите се запълват със знаковия бит. Ще разгледаме програма, която демонстрира >> и <<:

using System;
class ShiftThem

{

public static void Main()



{

int val = 1;

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

{

for (int t = 128; t > 0; t /= 2)



{

if ((val & t) != 0)

Console.Write("1");

else


Console.Write("0");

}

Console.WriteLine();



val = val << 1;

}

val = 128;



Console.WriteLine();

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

{

for (int t = 128; t > 0; t /= 2)



{

if ((val & t) != 0)

Console.Write("1");

else


Console.Write("0");

}

Console.WriteLine();



val = val >> 1;

}

Console.WriteLine();



}

}

Побитовите операции могат да се използват за изпълнение на бързо умножение или деление на 2. Изместване наляво умножава по 2, а надясно – дели на 2. Резултатът ще бъде верен, ако при изместването, битовете 1 не излизат от границите на числото. Всички двуместни побитови операции могат да се използват едновременно с операцията =.



Ще разгледаме клас, който представя двоичното представяне на целочислена стойност:

using System;

class ShowBits

{

public int numbits;



public ShowBits(int n)

{

numbits = n;



}

public void show(ulong val)

{

ulong mask = 1;



mask <<= numbits - 1;

int spacer = 0;

for (; mask != 0; mask >>= 1)

{

if ((val & mask) != 0)



Console.Write("1");

else


Console.Write("0");

spacer++;

if (spacer % 8 == 0)

{

Console.Write(" ");



spacer = 0;

}

}



Console.WriteLine();

}

}


class ShowBitsDemo

{

public static void Main()



{

ShowBits b = new ShowBits(8);

ShowBits i = new ShowBits(32);

ShowBits l = new ShowBits(64);

b.show(123);

i.show(123456789);

l.show(12345678987654321);

b.show(1232456); //taka 6te bydat pokazani samo mlad6ite 8 bita

}

}

Операцията ? има следния общ вид:



Израз1?израз2:израз3

Тук израз1 трябва да е от булев тип, а израз2 и израз3 трябва да имат еднакви типове. При изпълнение на операцията ? първо се пресмята израз1. Ако стойността на израз1 е true, то се пресмята израз2 и неговата стойност става резултат от изпълнението на операцията. Ако стойността на израз1 е false, то се пресмята израз3 и неговата стойност става резултат от изпълнението на операцията. Да разгледаме пример за пресмятане на абсолютна стойност:

аbsval=val<0?-val:val;

Същия резултат се получава с използване на оператор if:

if(val<0)

аbsval=-val;

else

аbsval=val;



Следващият пример се демонстрира използването на операция ?, за да се предотврати деление на 0:

using System;


class NoZeroDev

{

public static void Main()



{

int result;

for(int i=-5; i<6; i++)

{

result=i!=0?100/i:0;



if(i!=0)

Console.WriteLine("100/{0}={1}", i, result);

}
}

}



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


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




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

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