Типове данни

Скаларни типове данни

1. Обща класификация на типовете в С++

Езикът С++ има вградени типове данни, които се поддържат от езика. Те са два вида: скаларни (прости) и структурни (съставни). На програмиста се дава възможност да дефинира и собствени типове при възникване на необходимост. Вградените скаларни типове данни са: целочислен, реален, символен и логически (булев) тип.

Тип на данните се нарича категория данни, която има следните характеристики:

  • множество от допустими стойности;
  • множество от допустими операции;
  • множество от отношения (релации) между елементите на типа;
  • множество от стандартни функции за типа (ако има такива).

2.Целочислен тип

Целочисленият тип данни е предназначен за обработка на цели числа. Запазената дума за деклариране на променливи от този тип в С++ е int.

Множеството от допустими стойности зависи от компилатора. В средата за програмиране Borland C диапазонът на този тип е от -32768 до 32767. А в Microsoft Visual C++ диапазонът е от -2147483648 до 2147483647. За по-голяма яснота ще разглеждаме диапазона, използван в Borland C.

Количеството памет за една променлива или константа от тип int е 2B.

В таблицата са дадени различните модификатори, които може да се използват, и как те променят типа в Borland C.

ИмеДиапазонПамет
char, signed char-128до127
unsigned char0до255
short, signed short-32 768до32 7672B
unsigned short0до65 5352B
int , signed int-32 768до32 7672B
unsigned, unsigned int0до65 5352B
long, signed long-2147483648до21474836474B
unsigned long0до42949672954B
  • Аритметични операции

Операциите над даден тип се извършват посредством оператори, които се изпълняват над даден операнд или операнди.

Унарни операции – извършват се над един операнд с операторите + и -, записани преди операнда. Те имат същото действие, както и в математиката – да потвърдят или да променят знака на дадено число.

Бинарни операции – извършват се точно над два операнда с операторите +,-

,*,/ и %, записани между операндите.

Два последователни аритметични оператора може се допуснат, само ако единият от тях е унарен.

Оператори за:Означение:Примери:
ОперацияРезултат
Събиране+24+7 -32+8631 54
Изваждане8-4 322-4214 -99
Умножение*5*4 5*-320 -15
частно при целочислено деление/10/3 22/53 4
остатък при целочислено деление%10%3 22%51 2

Примери, реализирани с езика С++:

Декларираме:             int a=21,b=-12,c=10;

унарни операции са:

a=+b;     a=-b;

бинарни операции са:

c=25+4;   c=25-4;

c=a+b;    c=a-b;

а=c*2;    b=c/a;

  • Изрази с аритметични оператори

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

Примери:          Декларираме:             int a=3,b=-2,c=4;

c=25+4+1; c=25-4-1;

c=a+b-c;  c=a-b-с;

a=b*c-2;  b=a/2*c;

В математическите изрази операциите имат приоритет и така се знае кое действие се извършва първо.

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

Ако разгледаме израза 5+6*3 в математиката, резултатът от изчислението ще бъде 23. Това е така, защото операцията умножение има по-висок приоритет от събирането, поради което първо се извършва умножението, а след това събирането.

Приоритет на операторите в низходящ ред:

Най-висок         () (изразите в скоби)

+,- (унарни)

*,/,%

Най-нисък         +,- (бинарни)

За смяна нa приоритета се използва операторът “златни” скоби (). Първо се изчислява изразът, записан в скобите. Ако в даден израз са включени няколко израза в скоби, те се изчисляват в реда на задаването им от ляво на дясно. Броят на отварящите и затварящите скоби трябва да бъде равен.

*Примери:

Изразът (5+6)*3=33 “ е различен от „5+6*3=23

(3+6)/(8-5)=3″ е различен от „3+6/8-5=3+0-5=-2

Могат да се използват вложени изрази със скоби например (2*(2+(3*(5-2)))/5, като при тях изчислението започва от най-вътрешните скоби и се спазва приоритета на операциите.

  • Оператори за сравнение

Операторите за сравнение, които се използват в езика С++ са дадени в следната таблица:

ОператорОписание
по-малко
<=по-малко или равно
по-голямо
>=по-голямо или равно
==Равно
!=Различно

Kато резултат от сравнението се връща логическа стойност 1 или 0 (true или false).

Следните примери показват резултата от операции за сравнение.

461.fla             Тази визуализация трябва да се преработи с вас!!!

cout<<(5>4);     5>4    – истина (1)    мониторче,

cout<<(-2<-20);  -2<-20 – лъжа   (0)    показващо резултата: 101101

cout<<(6==6);    6==6   – истина (1)    със стрелки

cout<<(6>=6);    6>=6   – истина (1)

cout<<(5>=6);    5>=6   – лъжа     (0)

cout<<(4!=16);   4!=16  – истина (1)

  • Вградени функции

За целочислен тип данни е вградена функцията abs(x), която връща абсолютната стойност на аргумента x. За да се използва тази функция, е необходимо в началото на програмата да се включи библиотеката math.h.

Примери:

cout<<abs(-12); “ извежда 12

int a=abs(12);

cout<<a;        “ извежда 12

Задача 1: Да се състави програма, която въвежда цяло трицифрено число и извежда на екрана сумата и произведението от цифрите му.

Решение:

Нека е въведено числото 123.

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

Цифрата на стотиците 1 получаваме като частно при целочислено деление на 100 à 123/100.

Цифрата на единиците 3 получаваме като остатък при целочислено деление на 10 à 123%10;

Цифрата на десетиците получаваме като извършим две последователни целочислени деления на 10 à 123/10%10:

– първото деление 123/10 дава като резултат частно 12;

– второто деление 12%10 дава като резултат остатък 2, което е търсената цифра.

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

I начин:

#include<iostream.h>
int main()
{ 
  int x,a,b,c,s,p;
  cout<<"x="; cin>>x;
  a=x/100;
  b=x/10%10;
  c=x%10;
  s=a+b+c;
  p=a*b*c;
  cout<<"sum="<<s<<endl;
  cout<<"pr="<<p<<endl;
  return 0;
}  

II начин:

#include<iostream.h>
int main()
{ 
  int x,a,b,c;
  cout<<"x=";
  cin>>x;
  a=x/100;
  b=x/10%10;
  c=x%10;
  cout<<"sum="<<a+b+c<<endl;
  cout<<"pr="<<a*b*c<<endl;
  return 0;
}  
III начин:
#include<iostream.h>

int main()
{
	int x;
	cout<<"x=";
	cin>>x;
	cout<<"sum="<<x/100+x/10%10+x%10<<endl;
	cout<<"pr="<<x/100*x/10%10*x%10<<endl;
	return 0;
}

Кое решение според вас е най-рационалното и защо?

3. Реален тип

Реалните типове в С++ са float и double.

ИмеДиапазонПамет
float-3.4*1038 до 3.4*1038
doluble-1.74*10308 до 1.74*10308

За записване на реални числа се използват два начина:

  • в дробно-десетичен формат;
  • в експоненциален формат.

В записа на реалните числа се използва десетична точка (‘.’).

Примери за реални константи са:

3.54   4.0  65.  0.55 .25

3.15e+2 -7.8E+5   12.8e-7

Примери за деклариране на реални променливи:

float a;         // реална променлива от тип float

double b=32.1;   // реална променлива от тип double

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

Точността на типа float е до 7 значещи цифри след десетичната точка.

float a=12.1234567;

Точността на типа double е до 14 значещи цифри след десетичната точка.

double b=32.12345678999999;

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

Примери:

cout<<2.0; // извежда 2

cout<<12.24000; // извежда 12.24

  • Аритметични операции:

+, – (унарни)

*, /

+, -(бинарни)

Тези операции се извършват както при целочисления тип, с едно изключение – деленето не е целочислено и на реални числа не може да се намира остатък от деление.

  • Операции за сравнение

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

  • Вградени математически функции

Поради необходимостта от използване на някои математически действия, в езика С++ има вградени функции. Те могат да се използват като в началото на програмата се включи заглавния файл math.h. Ще представим някой от тях с кратко описание.

ФункцияОписание
ceil(x)Намира най-малкото цяло число >=x. Намереното число е от тип double.
floor(x)Намира най-голямото цяло число <=x. Намереното число е от тип double.
Sqrt(x)Намира квадратен корен от числото x.
pow(x,n)Степенува xn
fabs(x)Намира абсолютната стойност на числото x.
sin(x)Намира sin x . Числото x се задава в радиани.
cos(x)Намира cos x . Числото x се задава в радиани.
tan(x)Намира tg x . Числото x се задава в радиани.

4. Логически тип в С++

Логическият тип в С++ се декларира със запазената дума bool. Той е вграден в почти всички по-нови компилатори. Съществуват компилатори, които не поддържат този тип. Въпреки това, те поддържат всички логически операции, характерни за типа. Името му идва от името на английския математик и логик Джордж Бул.

За променливите и константите от тип bool се заделя памет от 1B.

Допустими стойности са двете константи true и false (истина и лъжа), като true се представя с 1, а false с 0.

  • Логически оператори

За работа с логически тип се използват следните логически оператори:

  • Оператор за логическо отрицание (!). Този оператор се използва за промяна на логическата стойност на даден операнд. Действието на оператора (!) върху операнда А се представя от следната таблица:
A!A
truefalse
falsetrue

Синтаксис:

!<операнд>;

където:

! – оператор за логическо отрицание.

Семантика: Операторът (!) промененя стойността на <операнд> от true на false и обратно.

Примери:

bool a=true,b=false;

!a;       //стойността на променливата а става false

!!b;      стойността на променливата b остава false

  • Оператор за логическо “И” (&&). Този оператор се използва за логическо умножение на два операнда. Дефиницията на това действие е дадена в следната таблица:
ABA&&B
truetruetrue
truefalsefalse
falsetruefalse
falsefalsefalse

Синтаксис: <операнд1>&&<операнд2>;

Семантика: Като резултат от действието на оператора се връща логическа стойност, определена от зависимостта в таблицата, където с А и B са означени операндите.

  • Оператор за логическо “ИЛИ”(||). Този оператор се използва за логическо събиране на два операнда. Дефиницията на това действие е дадена в следната таблица:
ABA||B
truetrueTrue
truefalseTrue
FalsetrueTrue
Falsefalsefalse

Синтаксис: <операнд1>||<операнд2>;

Семантика: Като резултат от действието на оператора се връща логическа стойност, определена от зависимостта в таблицата, където с А и B са означени операндите.

  • Изрази с логически оператори

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

Най-висок         !   (логическо отрицание)

&& (логическо умножение)

Най-нисък    || (логическо събиране)

Примери за логически изрази:

ИзразРезултат
1||0&&0true
!1||0&&1false
false&&true||falsefalse
!(1||0&&1)false
false&&(true||false)false
(!1||0&&1)||(false&&true||false)false
!(!1||0&&1)||(false&&true||false)true

Резултатът от израза 1||0&&0 е true(1). Това се обяснява по следния начин: поради по-високия приоритет на оператора && първо се изчислява 0&&0, което е false(0). След това се изчислява новият израз 1||0, даващ резултат true(1).

5. Символен тип

Символният тип в С++ се декларира със запазената дума char.

Необходимата памет за записване на стойности от този тип е 1B.

Примери:

char symbol;

char a,b;

В С++ символният тип използва символите от така наречената ASCII – кодова таблица, вградена в компютъра. Броят на тези символи е 256, като на всеки символ съответства код от 0 до 255. Първите 128 символа са стандартни и при всички компютри те са едни и същи. докато при останалите съществуват различия.

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

Символите биват два вида:

  • графични
  • управляващи

От клавиатурата се въвеждат главно графични символи. Такива са букви, цифри и други знаци. Могат да се въвеждат също и някои управляващи символи – символ за нов ред (клавиша Enter), символ за връщане на курсора (BackSpace) и др.

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

Примери:

char s=’A’, symbol=’8’;

За задаване на управляващи символи се използват следните специални означения:

ОзначениеОписание на символа
\nзнак за преминаване на нов ред
\tхоризонтална табулация
\vвертикална табулация
\bвръща курсора с един символ назад
\rвръща курсора в началото на реда
\aиздава звуков сигнал
\0нулев символ, знак за край на низ
  • Операции над символни данни:
  • Намиране ASCII кода на даден символ

По даден символ може да се достигне до неговия ASCII-код чрез израза (int)ch, където ch е символна константа или променлива.

Примери:

cout<<(int)’a’;  извежда на екрана числото 97 (кода на символа a);

cout<<(int)’\0’;  извежда на екрана числото 0 (кода на символа \0).

  • Намиране на символ по зададен негов ASCII код

По зададен ASCII код може да се достигне до съответния символ чрез израза (char)num, където num е израз от целочислен тип.

Примери :

cout<<(char)97;                 извежда на екрана символа a;

cout<<(char)(20+45);    извежда на екрана символа A.

  • Аритметични операции

Над символни данни могат да се прилагат всички аритметични операции, допустими за целочислен тип данни. Тези операции се извършват над ASCII кодовете на съответните символи. Резултатът е цяло число.

Примери:

int b=’3’;

cout<<’a’+4;     //извежда 101

cout<<b+2;  //извежда 53

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

Пример:

cout<<’8’-‘0’;    извежда 8″ ’8’-‘0’“ изваждат се кодовете: 56–48=8

  • Логически операции

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

Управляващият символ ‘\0’ се преобразува до false (ASCII кодът му е 0);

Всички останали символи се преобразуват до true.

  • Операции за сравнение

Сравняват се кодовете на символите и полученият резултат е от логически тип.

Примери:

cout<<(‘А’>’а’);              извежда 0 (false)

cout<<(‘\n’==’\n’);       извежда 1 (true)

cout<<(‘Z’>=’\0’);         извежда 1 (true)

cout<<(‘a’<’b’);              извежда 1 (true)

cout<<(‘c’!=’c’);                        извежда 0 (false)

6. Специфични операции за числени величини

Съществуват две специфични групи операции за числени величини:

  • Операции за нарастване и намаляване

Означават се съответно с ++ и и се прилагат над предварително декларирана променлива.

Операцията ++ променя текущата стойност на променливата, като добавя 1, а операцията – променя стойността й, като изважда 1. Употребяват се в два варианта – преди или след променливата. В случай, че използваме записа а++ първо се добавя 1 към а, но изразът се изчислява със старата (до увеличаването на а) стойност. Ако използваме записа ++а, отново а се увеличава с 1, но изразът вече се изчислява с новополучената (увеличената) стойност.

Примери:

int a=20, b=15;

cout<<”a=”<<++a<<endl;       // извежда а=21

cout<<”а=”<<а<<endl;         // извежда а=21

cout<<”b=”<<b++<<endl;       // извежда b=15

cout<<”b=”<<b<<endl;         // извежда b=16

cout<<”a=”<<–a<<endl;       // извежда а=20

cout<<”а=”<<а<<endl;         // извежда а=20

cout<<”b=”<<b–<<endl;       // извежда b=16

cout<<”b=”<<b<<endl;         // извежда b=15

Мониторче, на което се извежда резултата (стрелки)!!

  • Комбинирани операции за присвояване

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

ОперацияПълна формаКратка форма
+=a=a+20a+=20
-=b=b-15b-=15
*=c=c*ac*=a
/=d=d/bd/=b
%=e=e%2e%=2

Примери:

int k=20, p=18;

double s=8.0, r=3.0;

k+=p;     // k=k+p=20+18=38

k/=p;     // k=k/p=38/18=2

k%=p-3;   // k=k%(p-3)= 2 %15 =2

s*=r;     // s=s*r=8.0*3.0=24.0

7. Връзка между типовете в С++. Преобразуване на типове.

При работа със скаларните типове много често се налага те да се преобразуват до точно определен тип. За тази цел в езика С++ са реализирани два начина:

  • неявно преобразуване на типовете;
  • явно преобразуване на типовете.
  • Неявното преобразуване се извършва от компилатора при определени условия, без да се указва от програмиста.

Правила, при които компилаторът извършва неявно преобразуване на типовете:

  • винаги когато се използват логически оператори се извършва неявно преобразуване на вградените типове в С++ до логически тип;

При числовите типове числото 0 се преобразува до false, а всички останали числа до true.

При символен тип само символът ‘\0’ се преобразува във false, а всички останали символи до true.

Примери:

cout<<(24&&0);        //извежда 0

cout<<(‘\0’||2.5);    //извежда 1

  • прилагането на аритметични оператори над операнд от символен тип води до преобразуване на символа в цяло число, равно на неговия код;

Пример:

cout<<(‘5’*2);        //извежда 106 (53*2)
  • при пресмятане на аритметичен израз, в който участват операнди, заемащи различна по големина памет, всеки операнд от тип с по-малък брой байтове, се преобразува до тип, равен на операнда с най-голям брой байтове;

Пример:

cout<<(2-‘A’)*2.1;    //извежда -132.3

Най-голям брой байтове в израза ползва числото 2.1 (реален тип). Затова и резултатът е от реален тип.

  • при присвояване на стойност на променлива от числов и логически тип се прави преобразуване на типа на операнда (израза) до типа на променливата. Следната таблица дава преобразуванията, при които няма загуба на точност.
ТипПреобразува се до
boolвсички числови типове
shortint
unsigned shortunsigned int
floatdouble

Пример без загуба на точност:

double а=5;      // стойността на а се преобразува до 5.0

Пример със загуба на точност:

int b=3.52; // стойността на b се преобразува до 3

  • Явното преобразуване става като се използва една от следните две конструкции:

Синтаксис: (<име_на_тип>)<израз>;

Семантика: Преобразува стойността на <израз> до указания в скобите тип.

Примери:

(int)3.8;        //резултат: 3

(char)42;        //резултат: *

(double)10/4;    //резултат: 2.5

(double)(10/4);  //резултат: 2.0

В третия пример числото 10 се преобразува в реално, преди да бъде извършено делението, така резултатът от делението също е реално число. А в пример четири по-висок приоритет имат скобите – първо се извършва действието деление и резултатът се преобразува в реално число.

8. Манипулатори за форматиране на изхода

За да се укаже как точно трябва да се изведат резултатите, се използват манипулатори за форматиране на изхода. Те са стандартно дефинирани във файла iomanip.h. Този файл трябва да бъде включен в началото на програмата.

  • Манипулатор setw

Синтаксис: setw(<цял_израз>);

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

  • Манипулатор setprecision

Синтаксис: setprecision(<цял_израз>);

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

Примери:

cout<<setprecision(3)<<3.3123<<endl;     //извежда 3.312

cout<<setprecision(1)<<562.81<<endl;     //извежда 562.8

cout<<setprecision(1)<<32.47<<endl; //извежда 32.5