Целочислени типове данни за 32-битов процесор. Типове данни и променливи

Последна актуализация: 13.11.2017г

Както при много езици за програмиране, C # има своя собствена система от типове данни, която се използва за създаване на променливи. Типът данни определя вътрешното представяне на данните, набора от стойности, които обектът може да приеме, и валидните действия, които могат да бъдат приложени към обекта.

Езикът C # има следните примитивни типове данни:

    bool: има вярно или невярно (булеви литерали). Представен от системния тип System.Boolean

    Bool жив = истина; bool isDead = false;

    байт: съхранява цяло число от 0 до 255 и заема 1 байт. Представен от системния тип System.Byte

    Байт бит1 = 1; байт бит2 = 102;

    sbyte: съхранява цяло число от -128 до 127 и отнема 1 байт. Представен от системния тип System.SByte

    Sbyte bit1 = -101; sbyte bit2 = 102;

    кратко: съхранява цяло число от -32768 до 32767 и заема 2 байта. Представен от системния тип System.Int16

    Кратко n1 = 1; късо n2 = 102;

    ushort: съхранява цяло число от 0 до 65535 и отнема 2 байта. Представен от системния тип System.UInt16

    Ushort n1 = 1; късо n2 = 102;

    int: съхранява цяло число от -2147483648 до 2147483647 и отнема 4 байта. Представен от системния тип System.Int32. Всички целочислени литерали представляват int стойности по подразбиране:

    Int a = 10; int b = 0b101; // двоична форма b = 5 int c = 0xFF; // шестнадесетична форма c = 255

    uint: съхранява цяло число от 0 до 4294967295 и отнема 4 байта. Представен от системния тип System.UInt32

    Uint a = 10; uint b = 0b101; uint c = 0xFF;

    long: съхранява цяло число от –9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 и заема 8 байта. Представено от системния тип System.Int64

    Дълъг a = -10; дълго b = 0b101; дълго c = 0xFF;

    ulong: съхранява цяло число от 0 до 18 446 744 073 709 551 615 и заема 8 байта. Представен от системния тип System.UInt64

    Ulong a = 10; ulong b = 0b101; ulong c = 0xFF;

    float: съхранява число с плаваща запетая от -3,4 * 10 38 до 3,4 * 10 38 и заема 4 байта. Представен от системния тип System.Single

    double: съхранява число с плаваща запетая от ± 5,0 * 10 -324 до ± 1,7 * 10 308 и заема 8 байта. Представен от системния тип System.Double

    decimal: съхранява десетично дробно число. Ако се използва без десетична запетая, той има стойност от ± 1,0 * 10 -28 до ± 7,9228 * 10 28, може да съхранява 28 знака след десетичната запетая и заема 16 байта. Представено от системния тип System.Decimal

    char: съхранява един Unicode символ и отнема 2 байта. Представен от системния тип System.Char. Символните литерали съответстват на този тип:

    Char a = "A"; char b = "\ x5A"; char c = "\ u0420";

    низ: съхранява набора от символи на Unicode. Представено от системния тип System.String. Символните литерали отговарят на този тип.

    String hello = "Здравей"; низова дума = "свят";

    обект: може да съхранява стойност от всеки тип данни и е 4 байта на 32-битова платформа и 8 байта на 64-битова платформа. Представен от системния тип System.Object, който е основният тип за всички други типове и класове .NET.

    Обект а = 22; обект b = 3,14; обект c = "здравейте код";

Например, нека дефинираме няколко променливи от различни типове и да отпечатаме техните стойности в конзолата:

Използване на системата; пространство на имена HelloApp (клас Program (статичен празен Main (низови аргументи) (име на низ = "Tom"; int възраст = 33; bool isEmployed = false; двойно тегло = 78,65; Console.WriteLine ($ "Име: (име))"); Console.WriteLine ($ "Възраст: (възраст)"); Console.WriteLine ($ "Тегло: (тегло)"); Console.WriteLine ($ "Works: (isEmployed)");)))

За извеждане на данни в конзолата тук се използва интерполация: знак $ се поставя пред низа и след това можем да въвеждаме стойностите на променливите в низа в къдрави скоби. Конзолен изход на програмата:

Име: Том Възраст: 33 Тегло: 78,65 Работено: False

Използване на суфикси

Когато задавате стойности, имайте предвид следната тънкост: всички реални литерали се третират като двойни стойности. И за да посочите, че дробно число представлява float или десетичен тип, трябва да добавите суфикс към литерала: F / f за float и M / m за десетичен.

По същия начин всички целочислени литерали се третират като int стойности. За да посочите изрично, че един целочислен литерал представлява стойност на uint, трябва да използвате суфикса U / u, long с L / l и ulong с UL / ul:

Uint a = 10U; дълъг b = 20L; ulong c = 30UL;

Използване на системни типове

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

Int a = 4; System.Int32 b = 4;

Неявно въвеждане

По-рано ние изрично посочихме типа на променливите, например int x; ... И компилаторът вече знаеше при стартиране, че x съхранява цяло число.

Можем обаче да използваме и модела за имплицитно въвеждане:

Var hello = "Адът на света"; var c = 20; Console.WriteLine (c.GetType (). ToString ()); Console.WriteLine (hello.GetType (). ToString ());

За имплицитно въвеждане се използва ключовата дума var вместо името на типа данни. След това, по време на компилацията, самият компилатор извежда типа данни въз основа на присвоената стойност. Горният пример използва израза Console.WriteLine (c.GetType (). ToString ()); което ни позволява да разберем изведения тип на променливата c. Тъй като по подразбиране всички целочислени стойности се считат за тип int, така че в крайна сметка променливата c ще бъде от тип int или System.Int32

Тези променливи са подобни на нормалните променливи, но имат някои ограничения.

Първо, не можем първо да декларираме имплицитно въведена променлива и след това да инициализираме:

// този код работи int a; а = 20; // този код не работи var c; с = 20;

Второ, не можем да посочим null като стойност на имплицитно въведена променлива:

// този код не работи var c = null;

Тъй като стойността е нула, компилаторът не може да изведе типа данни.

двоен или десетичен

От горния списък с типове данни е очевидно, че ако искаме да използваме числа до 256 в програмата, тогава можем да използваме променливи от типа байт, за да ги съхраняваме. Когато използваме големи стойности, можем да приемем типовете short, int, long. Същото е и за дробните числа - за обикновени дробни числа можете да вземете типа float, за много големи дробни числа - двойния тип. Десетичният тип се откроява тук в смисъл, че въпреки голямата битова дълбочина в сравнение с двойния тип, двойният тип може да съхранява по-голяма стойност. Въпреки това, десетичната стойност може да съдържа до 28 знака след десетичната запетая, докато двойна стойност може да бъде 15-16 знака след десетичната запетая.

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

Цело число (int)

Тип размер международенне е дефиниран от стандарта, но зависи от компютъра и компилатора.

За 16-битов процесор се разпределят 2 байта за стойности от този тип,

за 32-битови - 4 байта.

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

Спецификаторът дългоозначава, че една цяло число ще заема 4 байта.

И така, на 16-битов компютър еквивалентите са int и short int,

а на 32-битов е int и long int.

Вътрешно представителствоцелочислени стойности - двоично цяло число. При използване на спецификатора подписананай-значимият бит от числото се интерпретира като знак (0 е положително число, 1 е отрицателно). Спецификаторът неподписанпозволява само положителни числа да бъдат представени, тъй като най-значимият бит се третира като част от числовия код. По този начин диапазонът от стойности int зависи от спецификаторите. Диапазони от стойности на стойности от целочислен тип с различни спецификатори за IBM PC-съвместими компютри са показани в таблицата „Обхвати от стойности на прости типове данни“.

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

На константите, намиращи се в програмата, се присвоява един или друг тип в съответствие с техния тип. Ако по някаква причина не отговаря на програмиста, можете изрично да посочите необходимия тип, като използвате наставките L, l (дълго) и U, u (без знак). Например, константа 32L ще бъде от тип long и ще заема 4 байта. Можете да използвате суфиксите L и U едновременно, например 0x22UL или 05Lu.

Забележка.Типовете short int, long int, signed int и unsigned int могат да бъдат съкратени съответно на short, long, signed и unsigned.

Тип знак (знак)

Броят байтове се разпределя за стойността на тип символ, достатъчен да побере всеки знак от набора от знаци за даден компютър, което е причината за името на типа. Обикновено това е 1 байт. Типът char, подобно на други типове цели числа, може да бъде подписан или неподписан. Подписаните стойности могат да съхраняват стойности в диапазона от -128 до 127. Когато използвате спецификатора без знак, стойностите могат да варират от 0 до 255. Това е достатъчно за съхраняване на всеки знак в набора от 256 символа ASCII. Стойностите на символите също се използват за съхраняване на цели числа.



Разширен тип символ (wchar_t)

Тип wchar_tе проектиран да работи с набор от знаци, за които кодирането не е достатъчен 1 байт. Например Unicode. Размерът на този тип зависи от изпълнението; обикновено съответства на типа къс.Низовите константи от тип wchar_t се записват с префикс L, например L „Gates“.

Булев тип (bool)

Булевите стойности могат да приемат само стойности вярнои фалшивокоито са запазени думи. Вътрешната форма на фалшивата стойност е 0 (нула). Всяка друга стойност се тълкува като вярна. При преобразуване в целочислен тип вярноима стойност 1.

Типове с плаваща запетая (float, double и long double)

Стандартът C ++ дефинира три типа данни за съхраняване на реални стойности: float, double и long double.

Типовете данни с плаваща запетая се съхраняват в паметта по различен начин от целочислените типове данни. Вътрешното представяне на реално число се състои от две части - мантисаи поръчка.

В компютрите, съвместими с IBM PC, стойности като плувазаемат 4 байта, от които се разпределя една двоична цифра под знака на мантисата, 8 бита по поръчкаи 23 под мантисата. Мантисата е число, по-голямо от 1,0, но по-малко от 2,0.Тъй като най-значимата цифра на мантисата винаги е 1, тя не се съхранява.

За стойности като двойно,заемащи 8 байта, 11 и 52 бита се разпределят съответно за реда и мантисата. Дължината на мантисата определя точността на числото, а дължината на поръчката определя неговия обхват.Както можете да видите от таблицата в края на записа, при еднакъв брой байтове, разпределени за float и long int стойности, диапазоните на техните допустими стойности се различават значително. поради вътрешната форма на представяне.

Спецификаторът дългопреди името на типа двойнопоказва, че за неговата стойност са разпределени 10 байта.

Константите с плаваща запетая са от тип double по подразбиране. Можете изрично да посочите типа на константа, като използвате суфиксите F, f (float) и L, l (дълго).

Например, константа 2E + 6L ще бъде от тип long double, а константата 1.82f ще бъде от тип float.

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

Например за операционната система MS-DOS sizeof (int) ще доведе до 2, а за Windows 98 или OS / 2 резултатът ще бъде 4.

Стандартът ANSI не определя диапазони от стойности за основни типове, само се определят съотношенията между техните размери, например:

sizeof (float) ≤ slzeof (двойно) ≤ sizeof (дълго двойно)
sizeof (char) ≤ slzeof (кратко) ≤ sizeof (int) ≤ sizeof (дълго)

Забележка.Минималните и максималните разрешени стойности за целочислени типове зависят от реализацията и са изброени в заглавния файл (), характеристики на реалните типове - във файла (), както и в шаблона на класа numeric_limits

Тип празнота

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

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

Тип Диапазон от стойности Размер (байтове)
bool вярно и невярно
подписан char -128 … 127
неподписан char 0 … 255
подписан кратко вт -32 768 … 32 767
неподписан кратко вт 0 … 65 535
подписан long int -2 147 483 648 … 2 147 483 647
unsigned long int 0 … 4 294 967 295
плува 3.4e-38 ... 3.4e + 38
двойно 1.7e-308 ... 1.7C + 308
дълъг двоен 3.4e-4932 ... 3.4e + 4932

Структура на програмата

Програмата на C ++ се състои от функции, описанияи директиви за препроцесор... Една от функциите трябва да има име главен... Изпълнението на програмата започва с първия израз на тази функция. Най-простата дефиниция на функцията има следния формат:

По правило функцията се използва за изчисляване на стойност, поради което нейният тип се посочва преди името на функцията. По-долу са някои от най-важните функции, които трябва да знаете:

  • ако функцията не трябва да връща стойност, се посочва типа void:
  • тялото на функцията е блок и следователно е затворено в къдрави скоби;
  • функциите не могат да бъдат вложени;
  • всяко изявление завършва с точка и запетая (с изключение на съставен израз).

Пример за структурата на програма, съдържаща функциите main, fl и f2:

Програмата може да се състои от няколко модули(изходни файлове).

Бележки за I / O в C ++

C ++ няма вграден вход/изход - това се прави с помощта на функции, типове и обекти, съдържащи се в стандартните библиотеки.

Използват се два начина: функции, наследени от езика C и C ++ обекти.

Основни I/O функции в стил C:

int scanf (const char * формат, ...) // вход
int printf (const char * формат, ...) // изход

Те извършват форматирано въвеждане и извеждане на произволен брой стойности според низа за форматиране. Форматният низ съдържа знаци, които се копират в потока (към екрана) при изход или се изискват от потока (от клавиатурата) при въвеждане и спецификации за преобразуване, които започват със знак %, които се заменят със специфични стойности при вход и изход.

Примерна програма, използваща I/O функции в стил C:

#включи
int main () (
int i;
printf ("Моля, въведете цяло число \ n");
scanf ("% d", & i);
printf ("Въведете числото% d, благодаря!", i);
връщане на 0;
}

Първият ред на тази програма е директива за препроцесор, според която в текста на програмата се вмъква заглавен файл, съдържащ описание на входните/изходните функции, използвани в програмата (в този случай ъгловите скоби са езиков елемент). Всички директиви на препроцесора започват със знак #.

Третият ред е описанието на целочислена променлива с име i.

Функцията printf на четвъртия ред отпечатва подканата „Моля, въведете цяло число“ и продължава на нов ред според \ n escape последователността. Функцията scanf поставя цяло число, въведено от клавиатурата в променливата i (знакът & означава операцията за получаване на адрес), а следващият оператор показва посочения низ на екрана, заменяйки спецификацията за преобразуване със стойността на това число.

Програма, използваща библиотека с класове C ++:

#включи
int main () (
int i;
cout<< "Введите целое число\ н"; cin >> i;
cout<< "Вы ввели число " << i << ", спасибо!";
връщане на 0;
}

Заглавният файл съдържа описание на набор от класове за управление на I/O. Той дефинира стандартните обекти на потока cinза въвеждане от клавиатура и coutза показване, както и операцията по поставяне в поток< < и чтения из потока >>.

Можете да използвате и двата метода за организиране на I/O, но не се препоръчва да ги смесвате в една и съща програма.

Типове данни

Типовете данни имат специално значение в C #, защото това е силно въведен език. Това означава, че всички операции подлежат на строго съвпадение на типа от компилатора и невалидните операции не се компилират. Следователно, силната проверка на типа помага за премахване на грешки и подобряване на надеждността на програмите. За проверка на типа всички променливи, изрази и стойности трябва да са от определен тип. В този език за програмиране изобщо няма такова нещо като "безтипова" променлива. Освен това типът на стойността определя операциите, които са разрешени да се извършват върху нея. Операция, разрешена за един тип данни, може да не е валидна за друг.

Има две общи категории вградени типове данни в C #: типове стойностии референтни типове... Те се различават по съдържанието на променливата. Концептуално разликата между двете е, че типът стойност съхранява данни директно, докато референтният тип съхранява препратка към стойност.

Тези типове се съхраняват на различни места в паметта: типовете стойности се съхраняват в област, известна като стека, а референтните типове в област, наречена управлявана купчина.

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

Целочислени типове

C # дефинира девет типа целочислени: char, byte, sbyte, short, ushort, int, uint, long и ulong... Но типът char се използва главно за представяне на знаци и следователно се разглежда отделно. Останалите осем цели числа са за числови изчисления. Техният диапазон на представяне на числа и битова дълбочина са представени по-долу:

Целочислени типове C #
Тип CTS тип Дълбочина на битовете Обхват
байт System.Byte 8 0:255
sbyte System.SByte 8 -128:127
къс System.Int16 16 -32768: 32767
кратък System.UInt16 16 0: 65535
международен System.Int32 32 -2147483648: 2147483647
uint System.UInt32 32 0: 4294967295
дълго System.Int64 64 -9223372036854775808: 9223372036854775807
улонг System.UInt64 64 0: 18446744073709551615

Както можете да видите от таблицата по-горе, C # дефинира и двата варианта на различните типове цели числа, със знак и без знак. Типовете цели числа със знак се различават от двойниците без знак по начина, по който интерпретират най-значимия бит от цяло число. Например, ако в програма е посочена стойност на цяло число със знак, компилаторът на C # генерира код, който използва най-значимия бит от цялото число като знак за знак. Числото се счита за положително, ако знакът е 0, и отрицателен, ако е 1.

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

Вероятно най-често срещаният целочислен тип в програмирането е тип int... Променливите от тип int често се използват за контрол на цикъла, индексиране на масиви и общи математически изчисления. Когато се изисква целочислена стойност с по-голям диапазон на представяне на числа от този на типа int, има редица други целочислени типове, налични за тази цел.

Така че, ако стойността трябва да се съхранява без знак, тогава можете да изберете за нея тип uint, за големи стойности със знак - дълъг тип, а за големи стойности без знак, типа улонг... Като пример по-долу е дадена програма, която изчислява разстоянието от Земята до Слънцето в сантиметри. За да съхранява такава голяма стойност, той използва променлива с дълъг тип:

Използване на системата; използване на System.Collections.Generic; използване на System.Linq; използване на System.Text; пространство от имена ConsoleApplication1 (клас Program (static void Main (string args) (дълъг резултат; const long km = 149800000; // разстояние в km.result = km * 1000 * 100; Console.WriteLine (резултат); Console.ReadLine ();); )))

На всички целочислени променливи може да се присвои десетична или шестнадесетична нотация. В последния случай се изисква префиксът 0x:

Дълъг x = 0x12ab;

Ако има някаква несигурност дали една цяло число е от тип int, uint, long или ulong, тогава по подразбиране int се приема. За да посочите изрично кой друг целочислен тип трябва да има стойност, можете да добавите следните знаци към числото:

Uint ui = 1234U; дълъг l = 1234L; ulong ul = 1234UL;

U и L също могат да бъдат написани с малки букви, въпреки че малките букви L могат лесно да се объркат с 1 (едно).

Типове с плаваща запетая

Типовете с плаваща запетая ви позволяват да представяте числа с дробна част. Има два вида типове данни с плаваща запетая в C #: плуваи двойно... Те представляват цифрови стойности с единична и двойна прецизност, съответно. И така, капацитетът на типа float е 32 бита, което приблизително съответства на диапазона на представяне на числата от 5E-45 до 3.4E + 38. И битовата дълбочина на двойния тип е 64 бита, което приблизително съответства на диапазона на представяне на числата от 5E-324 до 1.7E + 308.

Типът данни float е за по-малки стойности с плаваща запетая, които изискват по-малко прецизност. Двойният тип данни е по-голям от float и предлага по-висока степен на прецизност (15 бита).

Ако стойност, която не е цяло число, е твърдо кодирана в изходния код (например 12.3), тогава компилаторът обикновено приема, че се подразбира двойна стойност. Ако стойността трябва да бъде посочена като float, трябва да добавите F (или f) към нея:

Float f = 12.3F;

Десетичен тип данни

Осигурен е и десетичен тип за представяне на числа с плаваща запетая с висока точност. десетичен, който е предназначен за използване при финансови изчисления. Този тип е широк 128 бита, за да представи числови стойности, вариращи от 1E-28 до 7.9E + 28. Вероятно сте наясно, че грешките при десетичното закръгляване са често срещани в обикновената аритметика с плаваща запетая. Тези грешки се елиминират чрез използване на десетичния тип, който може да представлява числа до 28 (а понякога и 29) знака след десетичната запетая. Тъй като този тип данни може да представлява десетични стойности без грешки при закръгляване, той е особено полезен за финансови изчисления:

Използване на системата; използване на System.Collections.Generic; използване на System.Linq; използване на System.Text; пространство от имена ConsoleApplication1 (клас Program (static void Main (string args)) (// *** Изчисляване на цената на капиталовата инвестиция с *** // *** фиксирана норма на възвръщаемост *** десетични пари, проценти; int i; постоянен байт години = 15 ; пари = 1000,0 милиона; процент = 0,045 милиона; за (i = 1; i

Резултатът от тази програма ще бъде:

символи

В C # знаците са представени не с 8-битов код, както в много други езици за програмиране, като C++, а с 16-битов код, наречен уникод... Наборът от символи на Unicode е толкова широк, че включва знаци от почти всеки естествен език в света. Докато много естествени езици, включително английски, френски и немски, се характеризират с относително малки азбуки, редица други езици, като китайския, използват доста обширни набори от знаци, които не могат да бъдат представени с 8-битов код. За да се преодолее това ограничение, C # дефинира тип charпредставляващи 16-битови стойности без знак, вариращи от 0 до 65535. Стандартният 8-битов ASCII символен набор е подмножество на Unicode от 0 до 127. Следователно ASCII знаците все още са валидни в C # ...

В този раздел ще разгледаме основните типове данни в C ++, тези типове данни се наричат ​​още вградени типове данни. Езикът за програмиране C ++ е разширяем език за програмиране. Разширяем означава, че в допълнение към вградените типове данни, можете да създавате свои собствени типове данни. Следователно има огромен брой типове данни в C ++. Ще проучим само основните.

Таблица 1 - Типове данни на C ++
Тип байт Обхват от приети стойности

целочислен (булев) тип данни

bool 1 0 / 255

целочислен (знаков) тип данни

char 1 0 / 255

целочислени типове данни

кратко вт 2 -32 768 / 32 767
неподписан кратко вт 2 0 / 65 535
международен 4
unsigned int 4 0 / 4 294 967 295
дълго междун 4 -2 147 483 648 / 2 147 483 647
unsigned long int 4 0 / 4 294 967 295

типове данни с плаваща запетая

плува 4 -2 147 483 648.0 / 2 147 483 647.0
дълга плувка 8
двойно 8 -9 223 372 036 854 775 808 .0 / 9 223 372 036 854 775 807.0

Таблица 1 показва основните типове данни в C ++. Цялата таблица е разделена на три колони. Първата колона показва запазена дума, която ще дефинира, всяка своя собствен, тип данни. Втората колона показва броя на байтовете, които са разпределени за променлива със съответния тип данни. Третата колона показва диапазона от валидни стойности. Имайте предвид, че в таблицата всички типове данни са сортирани от най-малкия до най-големия.

Тип данни Bool

Първият в таблицата е типът данни bool целочислен тип данни, тъй като обхватът на валидните стойности е цели числа от 0 до 255. Но както вече забелязахте, той е написан в скоби - булев тип данни и това също е вярно. Защото boolизползва се изключително за съхраняване на резултатите от булеви изрази. Булевият израз може да има един от двата резултата, true или false. true - ако булевият израз е вярно, false - ако булевият израз е false.

Но тъй като диапазонът от валидни стойности на типа данни bool е от 0 до 255, беше необходимо по някакъв начин този диапазон да се съпостави с булевите константи true и false, дефинирани в езика за програмиране. По този начин константата true е еквивалентна на всички числа от 1 до 255, включително, докато константата false е еквивалентна само на едно цяло число - 0. Помислете за програма, използваща типа данни bool.

// data_type.cpp: дефинира входната точка за конзолното приложение. #include "stdafx.h" #include използване на пространство от имена std; int main (int argc, char * argv) (bool boolean = 25; // променлива тип bool с име boolean if (boolean) // if условие на израза cout<< "true = " << boolean << endl; // выполнится в случае истинности условия else cout << "false = " << boolean << endl; // выполнится в случае, если условие ложно system("pause"); return 0; }

V ред 9е декларирана променлива от тип bool който се инициализира на 25. На теория следред 9, в булева променлива трябва да съдържа числото 25, но всъщност тази променлива съдържа числото 1. Както казах, числото 0 е фалшива стойност, числото 1 е истинска стойност. Изводът е, че в променлива като bool може да съдържа две стойности - 0 (невярно) или 1 (вярно). Докато под типа данни bool се разпределя цял байт, което означава, че променлива от тип bool може да съдържа числа от 0 до 255. За определяне на фалшиви и истински стойности са необходими само две стойности, 0 и 1. Възниква въпросът: "За какво са другите 253 стойности?"

Въз основа на тази ситуация се съгласихме да използваме числата от 2 до 255 като еквивалентни на числото 1, тоест вярно. Ето защо булевата променлива съдържа числото 25, а не 1. В редове 10 -13декларирано, което прехвърля контрола на оператора в ред 11, ако условието е вярно, и операторът в ред 13ако условието е невярно. Резултатът от програмата е показан на фигура 1.

Вярно = 1 Натиснете произволен клавиш, за да продължите. ... ...

Фигура 1 - Тип данни Bool

Тип данни Char

Типът данни char е целочислен тип данни, който се използва за представяне на знаци. Тоест всеки знак съответства на определено число от диапазона. Типът данни char се нарича още тип данни за символи, тъй като графичното представяне на знаци в C ++ е възможно благодарение на char. За представяне на знаци в C ++, типът данни char се разпределя един байт, в един байт - 8 бита, след което повишаваме два на степен 8 и получаваме стойността 256 - броят знаци, които могат да бъдат кодирани. По този начин, използвайки типа данни char, можете да покажете всеки от 256 знака. Всички кодирани знаци са представени в.

ASCII (от английския американски стандартен код за обмен на информация) е американският стандартен код за обмен на информация.

Помислете за програма, използваща типа данни char.

// symbols.cpp: дефинира входната точка за конзолното приложение. #include "stdafx.h" #include използване на пространство от имена std; int main (int argc, char * argv) (char символ = "a"; // деклариране на променлива от тип char и инициализирането й със символа "a" cout<< "symbol = " << symbol << endl; // печать символа, содержащегося в переменной symbol char string = "сайт"; // объявление символьного массива (строки) cout << "string = " << string << endl; // печать строки system("pause"); return 0; }

Така че в ред 9се декларира променлива с иметосимвол , му се приписва стойността на символа"а" ( ASCII код). V ред 10 cout оператор отпечатва символа, съдържащ се в променливатасимвол. V ред 11декларира низов масив с имениз , а размерът на масива е зададен имплицитно. Низът се съхранява в низовия масив"сайт" ... Имайте предвид, че когато съхранявахме символа в променлива като char , след което след знака за равенство поставяме единични кавички, в които сме изписали символа. При инициализиране на низов масив с определен низ се поставят двойни кавички след знака за равенство, в който се записва определен низ. Подобно на нормален символ, низовете се извеждат с помощта на оператораизмама, ред 12... Резултатът от програмата е показан на фигура 2.

Символ = низ = сайт Натиснете произволен клавиш, за да продължите. ... ...

Фигура 2 - Тип данни char

Целочислени типове данни

Целочислените типове данни се използват за представяне на числа. Таблица 1 съдържа шест от тях: short int, unsigned short int, int, unsigned int, long int, unsigned long int . Всички те имат свой собствен размер на заета памет и диапазон от приети стойности. В зависимост от компилатора, размерът на заетата памет и диапазонът от приети стойности може да варира. В таблица 1 са взети всички диапазони от приети стойности и размери на заета памет за компилатора MVS2010. Освен това всички типове данни в Таблица 1 са подредени във възходящ ред на размера на заетата памет и диапазона от приети стойности. Обхватът на приетите стойности, по един или друг начин, зависи от размера на заета памет. Съответно, колкото по-голям е размерът на заетата памет, толкова по-голям е диапазонът на приетите стойности. Също така, диапазонът от приети стойности се променя, ако типът данни е деклариран с префикса unsigned - unsigned. Неподписаният префикс означава, че типът данни не може да съхранява подписани стойности, тогава диапазонът от положителни стойности се удвоява, например типовете данни short int и unsigned short int.

Префикси за целочислен тип данни:

къс префиксът съкращава типа данни, към който се прилага, като намалява размера на заетата памет;

дълго префиксът удължава типа данни, към който се прилага, като увеличава размера на заетата памет;

unsigned - префиксът удвоява диапазона от положителни стойности, докато диапазонът от отрицателни стойности не може да бъде съхранен в този тип данни.

Така че по същество имаме един целочислен тип за представяне на цели числа - това е типът данни int. Благодарение на късите, дълги, неподписани префикси се появява известно разнообразие от типове данни тип int, които се различават по размера на заета памет и (или) диапазона от приети стойности.

Типове данни с плаваща запетая

В C ++ има два типа данни с плаваща запетая: float и double. Типовете данни с плаваща запетая са предназначени да съхраняват числа с плаваща запетая. Типовете данни float и double могат да съхраняват както положителни, така и отрицателни числа с плаваща запетая. Типът данни float има два пъти по-малък размер на паметта от двойния тип данни, което означава, че диапазонът от приети стойности също е по-малък. Ако типът данни float е деклариран с дългия префикс, тогава диапазонът на приетите стойности ще стане равен на диапазона на приетите стойности на двойния тип данни. По принцип типовете данни с плаваща запетая са необходими за решаване на проблеми с висока изчислителна точност, например парични транзакции.

И така, ние разгледахме основните моменти относно основните типове данни в C ++. Остава само да се покаже откъде идват всички тези диапазони от приети стойности и размера на заетата памет. И за това ще разработим програма, която ще изчисли основните характеристики на всички типове данни, обсъдени по-горе.

// data_types.cpp: дефинира входната точка за конзолното приложение. #include "stdafx.h" #include // I/O библиотека за манипулации #include // заглавен файл за математически функции #include използване на пространство от имена std; int main (int argc, char * argv) (cout<< " data type " << "byte" << " " << " max value "<< endl // заглавки на колони <<"bool = " << sizeof(bool) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных bool*/ << (pow(2,sizeof(bool) * 8.0) - 1) << endl << "char = " << sizeof(char) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных char*/ << (pow(2,sizeof(char) * 8.0) - 1) << endl << "short int = " << sizeof(short int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных short int*/ << (pow(2,sizeof(short int) * 8.0 - 1) - 1) << endl << "unsigned short int = " << sizeof(unsigned short int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных unsigned short int*/ << (pow(2,sizeof(unsigned short int) * 8.0) - 1) << endl << "int = " << sizeof(int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных int*/ << (pow(2,sizeof(int) * 8.0 - 1) - 1) << endl << "unsigned int = " << sizeof(unsigned int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных unsigned int*/ << (pow(2,sizeof(unsigned int) * 8.0) - 1) << endl << "long int = " << sizeof(long int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных long int*/ << (pow(2,sizeof(long int) * 8.0 - 1) - 1) << endl << "unsigned long int = " << sizeof(unsigned long int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных undigned long int*/ << (pow(2,sizeof(unsigned long int) * 8.0) - 1) << endl << "float = " << sizeof(float) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных float*/ << (pow(2,sizeof(float) * 8.0 - 1) - 1) << endl << "double = " << sizeof(double) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных double*/ << (pow(2,sizeof(double) * 8.0 - 1) - 1) << endl; system("pause"); return 0; }

Тази програма е изложена така, че да можете да видите характеристиките на типовете данни във вашата система. Не си струва да разбирате кода, тъй като програмата използва оператори за управление, които най-вероятно все още не познавате. За повърхностно запознаване с програмния код ще обясня някои точки по-долу. Операторразмер на () изчислява броя на байтовете, разпределени за тип данни или променлива. Функциямощност (x, y) повдига смисъла x на степен на y , тази функция е достъпна от заглавния файл ... Манипулаторите с фиксирана и зададена точност (). достъпно от заглавния файл ... Първият е фиксиран , изпраща стойности във фиксирана форма към изходния поток. Манипулатор setprecision (n) показва n десетични знаци. Максималната стойност на даден тип данни се изчислява по следната формула:

Max_val_type = 2 ^ (b * 8 - 1) - 1; // за типове данни с отрицателни и положителни числа // където b е броят на байтовете, разпределени в паметта за променлива с този тип данни // умножете по 8, тъй като в един байт има 8 бита // извадете 1 в скоби , тъй като числата на диапазона трябва да бъдат намалени наполовина за положителни и отрицателни стойности // извадете 1 в края, тъй като диапазонът от числа започва от нула // типове данни с префикс unsigned max_val_type = 2 ^ (b * 8) - 1 ; // за типове данни само с положителни числа

Пример за това как работи програмата може да се види на фигура 3. Първата колона показва основните типове данни в C ++, втората колона показва размера на паметта, разпределена за всеки тип данни, а третата колона показва максималната стойност, която съответният тип данни може да съдържа. Минималната стойност се намира по същия начин като максималната. За типове данни с префикс без знак минималната стойност е 0.

Тип данни BYTE MAX стойност BOOL = 1 255.00 char = 1 255.00 къси int = 2 32767.00 неподписан къс int = 4 4294967295.00 long int = 4 2147483647.00 бездушен дълъг int = 4 4294967295.00 float = 4 2147483647.00 Двойна = 8 9223372036854775808.00 Натиснете произволен клавиш, за да продължите. ... ...

Фигура 3 - Типове данни на C ++

Ако например на променлива от тип short int е присвоена стойност 33000, тогава битовата мрежа ще препълни, тъй като максималната стойност в променлива от тип short int е 32767. Тоест, някаква друга стойност ще бъде съхранена в променлива от тип short int, най-вероятно ще бъде отрицателен. Тъй като засегнахме типа данни int, заслужава да се отбележи, че можете да пропуснете ключовата дума int и да напишете, например, само кратко. Компилаторът ще интерпретира тази нотация като кратко int. Същото важи и за дългите и неподписани префикси. Например:

// съкращения за тип данни int short a1; // същото като short int long a1; // същото като long int unsigned a1; // същото като unsigned int unsigned short a1; // същото като unsigned short int

Етикети: C променливи. char, int, unsigned, long, long long, float, double, long double, long float, лексикално обхват. Декларации на променливи. Зона на видимост. Инициализация на променливи. Имена на променливи. Експоненциална форма.

Променливи

Променливите се използват за съхраняване на стойности (sic!). Променливата се характеризира със своя тип и име. Да започнем с името. В C променливата може да започва с долна черта или буква, но не и с число. Променливата може да включва английски знаци, цифри и долна черта. Променливата не трябва да съвпада с ключови думи (това са специални думи, които се използват като контролни структури, за дефиниране на типове и т.н.)

Автоматичен двойно международен структура
прекъсване друго дълго превключвател
регистрирам typedef char външен
връщане нищожен случай плува
неподписан по подразбиране за подписана
съюз направи ако размер на
летлив продължи enum къс
докато в редица
А също и редица други думи, специфични за тази версия на компилатора, например далеч, близо до, мъничък, огромен, асм, asm_и т.н.

Например правилните идентификатори са
a, _, _1_, Sarkasm, a_long_variable, aLongVariable, var19, defaultX, char_type
неверен
1a, $ value, a-long-value, short

C е език, чувствителен към малки и големи букви.Променливите с име a и A, или end и END, или perfectDark и PerfectDarK са различни променливи.

Променливи типове

Типът на променливата определя

  • 1) Размерът на променливата в байтове (колко байта памет компютърът ще разпредели за съхраняване на стойността)
  • 2) Представяне на променливата в паметта (както в двоична форма битовете ще бъдат разположени в разпределената област на паметта).
Има няколко основни типа в si. Нека ги разделим на две групи - цели числа и числа с плаваща запетая.

Цяла

  • char- размерът е 1 байт. Е винаги! Това трябва да се помни.
  • къс- размер 2 байта
  • международен- размер 4 байта
  • дълго- размер 4 байта
  • дълго дълго- размер 8 байта.
Тук трябва да се направи забележка. Размерът на променливите в C не е дефиниран изрично като размер в байтове. Стандартът посочва само това

char<= short <= int <= long <= long long

Горните стойности са специфични за VC2012 компилатора на 32-битова машина. Така че, ако вашата програма зависи от размера на променлива, не бъдете твърде мързеливи, за да разберете нейния размер.

Сега нека дефинираме максималното и минимално число, което променлива от всеки тип може да съхранява. Числата могат да бъдат както положителни, така и отрицателни. Отрицателните числа използват един бит за съхранение на знака. Понякога знакът е необходим (например съхраняваме банковата сметка, температура, координата и т.н.), а понякога не е необходим (тегло, размер на масива, възраст на лицето и т.н.). За това C използва модификатора signed и unsigned. unsigned char - всичките 8 бита за число, общо имаме набор от числа от 00000000 до 11111111 в двоична форма, тоест от 0 до 255 signed char от -128 до 128. В C променливите са подписани по подразбиране . Следователно записването на char и signed char са еквивалентни.

Раздел. 1 Размерът на целочислените типове в si.
Тип Размер, байтове Минимална стойност Максимална стойност
неподписан char 1 0 255
подписан char
(въглен)
1 -128 127
неподписано кратко 2 0 65535
подписан кратко
(къс)
2 -32768 32767
unsigned int
(неподписан)
4 0 4294967296
подписан вт
(int)
4 -2147483648 2147483647
unsigned long 4 0 4294967296
подписан дълго
(дълго)
4 -2147483648 2147483647
unsigned long long 8 0 18446744073709551615
подписан дълго дълго
(дълго дълго)
8 -9223372036854775808 9223372036854775807

размер на

C има оператор, който ви позволява да получите размера на променлива в байтове. sizeof е променлива, или sizeof (променлива) или sizeof (тип). Това е точно операторът, защото функцията няма начин да получи информация за размера на типовете по време на изпълнение. Нека напишем малка програма за проверка на размерите на променливите.

#включи #включи int main () (char c; short s; int i; long l; long long L; // Извикване sizeof като "функция" printf ("sizeof (char) =% d \ n", sizeof (c)); printf ("sizeof (short) =% d \ n", sizeof (s)); printf ("sizeof (int) =% d \ n", sizeof (i)); printf ("sizeof (long) =% d \ n ", sizeof (l)); printf (" sizeof (long long) =% d \ n ", sizeof (L)); // Извикване като оператор printf (" sizeof (char) =% d \ n ", sizeof c); printf ("sizeof (short) =% d \ n", sizeof s); printf ("sizeof (int) =% d \ n", sizeof i); printf ("sizeof (long) =% d \ n ", sizeof l); printf (" sizeof (long long) =% d \ n ", sizeof L); _getch ();)

(Мисля, че е ясно, че променливите могат да имат всяко валидно име). Тази програма можеше да бъде написана и по-проста

#включи #включи int main () (printf ("sizeof (char) =% d \ n", sizeof (char)); printf ("sizeof (short) =% d \ n", sizeof (short)); printf ("sizeof ( int) =% d \ n ", sizeof (int)); printf (" sizeof (long) =% d \ n ", sizeof (long)); printf (" sizeof (long long) =% d \ n ", sizeof (дълъг дълъг)); // не може да извика sizeof като оператор за име на тип // sizeof int - грешка при компилацията _getch ();)

В B един и същи тип може да има няколко имена.
кратък === кратък инт
дълго === дълго международен
long long === дълго дълго int
unsigned int === unsigned

Типове с плаваща запетая

  • плува- 4 байта,
  • дълга плувка- 8 байта
  • двойно- 8 байта
  • дълъг двоен- 8 байта.
Ето и стойностите за VC2012, стандартния размер на типовете плаващи елементи<= long float <= double <= long double все числа с плавающей точкой - со знаком.

Препълване на променлива

C не наблюдава препълвания на променливи. Това означава, че като постоянно увеличаваме стойността на, да речем, променлива от тип int, в крайна сметка ще "нулираме стойността"

#включи #включи void main () (неподписан a = 4294967295; int b = 2147483647; // Препълване на неподписан тип printf ("% u \ n", a); a + = 1; printf ("% u", a); // Препълване подписан тип printf ("% d \ n", b); b + = 1; printf ("% d", b); getch ();)

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

Постфиксно обозначение на типа

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

  • 11 - номер от тип int
  • 10u - неподписан
  • 22l или 22L - дълги
  • 3890ll или 3890LL - дълги дълги (също lL или Ll)
  • 80.0f или 80.f или 80.0F - float (трябва да има десетична точка в записа)
  • 3.0 - номер от тип двоен
Експоненциалната нотация също обозначава двойник по подразбиране. #включи #включи int main () (printf ("sizeof (int) =% d \ n", sizeof (10)); printf ("sizeof (unigned) =% d \ n", sizeof (10u)); printf ("sizeof ( long) =% d \ n ", sizeof (10l)); printf (" sizeof (long long) =% d \ n ", sizeof (10ll)); printf (" sizeof (float) =% d \ n ", sizeof (10.f)); printf ("sizeof (double) =% d \ n", sizeof (10.)); printf ("sizeof (double) =% d \ n", sizeof (10e2)); gettch ();)

Следният код обаче няма да генерира грешки, защото има имплицитно преобразуване на тип

Int a = 10u; двойно g = 3.f;

Шестнадесетичен и осмичен формат

Когато работите с числа, можете да използвате шестнадесетични и осмични формати за представяне. Шестнадесетичните числа започват от 0x, осмичните числа започват от нула. Съответно, ако числото започва с нула, то не трябва да съдържа цифри по-високи от 7:

#включи #включи void main () (int x = 0xFF; int y = 077; printf ("hex x =% x \ n", x); printf ("dec x =% d \ n", x); printf ("oct x =% o \ n ", x); printf (" oct y =% o \ n ", y); printf (" dec y =% d \ n ", y); printf (" hex y =% x ", y); getch ();)

Експоненциална нотация за числа

Експоненциалната форма на представяне на число е представянето на число във формата M e ± p, където М- числова мантиса, стр- мощност десет. В този случай мантисата трябва да има един знак различен от нула преди десетичната запетая.
Например 1,25 === 1,25e0, 123,5 === 1,235e2, 0,0002341 === 2,341e-4 и т.н.
Изгледите 3.2435e7 са еквивалентни на 3.2435e + 7
Има и друго понятие („инженерство“), при което степента трябва да бъде кратна на три. Например 1,25 === 1,25e0, 123,5 === 123,5e0, 0,0002341 === 234,1e-6, 0,25873256 === 258,73256e-3 и т.н.

Деклариране на променливи

В C променливите винаги се декларират в началото на блок (блокът е част от код, ограничена с къдрави скоби)

<возвращаемый тип> <имя функции> (<тип> <аргумент>[, <тип> <аргумент>]) (декларации на променливи всичко останало)

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

Int a; двоен параметър;

Можете да декларирате множество променливи от един и същи тип, като разделите имената със запетая

Дълъг дълъг arg1, arg2, arg3;

например

#включи #включи int main () (int a = 10; int b; докато (a> 0) (int z = a * a; b + = z;))

Променливите са декларирани тук аи бвътрешна функция главен, и променливата zвътре в тялото на цикъла. Следният код ще доведе до грешка при компилация

Int main () (int i; i = 10; int j;)

Това е така, защото променливата е декларирана след оператора за присвояване. Когато декларирате променливи, можете да ги инициализирате незабавно.
int i = 0;
В този случай инициализацията при деклариране на променлива не се счита за отделен оператор, така че следният код ще работи

Int main () (int i = 10; int j;)

Първоначалната стойност на променливата

Много е важно да запомните, че променливите в C не са инициализирани на нула по подразбиране, както в много други езици за програмиране. След деклариране на променлива, той съхранява "боклук" - произволна стойност, останала в областта на паметта, която е била разпределена за променливата. Това се дължи преди всичко на оптимизацията на програмата: ако няма нужда от инициализация, тогава няма нужда да губите ресурси за писане на нули (забележка: глобалните променливи се инициализират с нули, защо е така, прочетете тази статия).

#включи #включи int main () (int i; printf ("% d", i); getch ();)

Ако стартирате тази програма на VC, тогава по време на изпълнение ще излети предупреждение
Неуспешна проверка по време на изпълнение #3 - Променливата "i" се използва без да е инициализирана.
Ако щракнете върху "Продължи", програмата ще покаже "боклук". В много други компилатори няма да има предупреждение, когато програмата се изпълни.

Променлив обхват

Променливите могат да бъдат локални (декларирани във функция) и глобални. Глобалната променлива е видима за всички функции, декларирани в този файл. Локална променлива е ограничена до своя обхват. Когато казвам, че променливата е „видима някъде“, това означава, че е дефинирана на това място и може да се използва. Например, помислете за програма, която има глобална променлива

#включи #включи int глобален = 100; void foo () (printf ("foo:% d \ n", глобален);) void bar (int global) (printf ("bar:% d \ n", глобален);) int main () (foo () ; бар (333); вземи ();)

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

#включи #включи int глобален = 100; int main () (int global = 555; printf ("% d \ n", глобален); getch ();)

Програмата ще отпечата 555. Както в предишния случай, локалната променлива е "по-важна". Променлива, декларирана в определен обхват, не се вижда извън него, например

#включи #включи int глобален = 100; int main () (int x = 10; (int y = 30; printf ("% d", x);) printf ("% d", y);)

Този пример няма да се компилира, защото променливата гсъществува само в рамките на своя блок.
Ето още един пример, когато променливите, декларирани в блок, се припокриват.

#включи #включи int глобален = 100; int main () (int x = 10; (int x = 20; (int x = 30; printf ("% d \ n", x);) printf ("% d \ n", x);) printf ( "% d \ n", x); getch ();)

Програмата ще изведе
30
20
10
Глобалните променливи трябва да се избягват. Често можете да чуете това. Нека се опитаме да разберем защо. Във вашите прости проекти глобалните изглеждат добре. Но представете си, че имате приложение, което

  • 1) Разработено от няколко души и се състои от стотици хиляди редове код
  • 2) Работи в множество нишки

Първо, глобална променлива, ако е видима за всички, може да бъде променена от всяка част на програмата. Променили сте глобална променлива, искате да я напишете и друга част от програмата вече е презаписала различна стойност в нея (всъщност това е цял клас проблеми, които възникват в многонишкова среда). Второ, при големи размери на проекти е невъзможно да се следи кой и кога е създал глобални променливи. В примерите по-горе можете да видите как променливите могат да се припокриват една с друга и същото ще се случи в голям проект.

Разбира се, има ситуации, в които глобалните променливи правят програмата по-лесна, но такива ситуации не се случват често и не в домашната ви работа, така че НЕ СЪЗДАВАЙТЕ ГЛОБАЛНИ ПРОМЕНИМИ!
Променливите могат да бъдат не само цели числа и с плаваща запетая. Има много други видове, които ще разгледаме по-късно.