Константи, C за начинаещи, C
Константи с плаваща запетая
C++ ви дава възможност да записвате стойности от основните типове: символни константи, целочислени константи и константи с плаваща запетая. В допълнение, нула (0) може да се използва като константа от всеки тип указател, а символните низове са константи от тип char[]. Можете също да зададете символни константи. Символна константа е име, чиято стойност не може да бъде променена в нейния обхват. В C++ има три вида символни константи:
на всяка стойност от всякакъв тип може да се даде име и да се използва като константа чрез добавяне на ключовата дума const към нейното описание;
набор от целочислени константи може да се дефинира като enum;
всяко име на вектор или функция е константа.
Целочислените константи се предлагат в четири форми: десетични, осмични, шестнадесетични и символни константи. Десетичните знаци се използват най-често и изглеждат така, както бихте очаквали:
0 | 1234 | 976 | 12345678901234567890 |
Десетичната константа е от тип int, при условие че се вписва в int, в противен случай типът й е long. Компилаторът трябва да предупреждава за константи, които са твърде дълги, за да бъдат представени на машината.
Константа, която започва с нула, последвана от x (0x), е шестнадесетично число (база 16), а константа, която започва с нула, последвана от цифра, е осмично число (база 8). Ето примери за осмични константи:
0 | 02 | 077 | 0123 |
техните десетични еквиваленти са 0, 2, 63, 83. В шестнадесетичен запис тези константи изглеждат така:
0x0 | 0x2 | 0x3f | 0x53 |
Буквите a, b, c, d, e и f или техните еквиваленти с главни букви се използват съответно за представяне на числата 10, 11, 12, 13, 14 и 15. Осмичните и шестнадесетичните записи са най-полезни за записване на набор от битове; използването на тези нотации за изразяване на обикновени числа може да доведе до изненади. Например, на машина, където int е представено като шестнадесетично цяло число с двоично допълнение от две, 0xffff е отрицателното десетично число -1; ако се използват повече битове за представяне на цяло число, то ще бъде 65535.
Константи с плаваща запетая
Константите с плаваща запетая са от тип double. Както в предишния случай, компилаторът трябва да предупреди за константи с плаваща запетая, които са твърде големи за представяне. Ето някои константи с плаваща запетая:
1.23 .23 0.23 1. 1.0 1.2e10 1.23e-15
Имайте предвид, че интервал не може да се появи в средата на константа с плаваща запетая. Например 65.43 e-21 не е константа с плаваща запетая, а четири отделни лексикални знака (токени):
и ще изведе синтактична грешка. Ако искате да имате константа с плаваща запетая от тип float, можете да я дефинирате по следния начин:
const float pi = 3.14159265;
Въпреки че в C++ няма отделен символен тип данни, по-точно символът може да се съхранява в целочислен тип, той има специална и удобна нотация за знаци. Символна константа е знак, ограден в единични кавички; например "a" или "0". Такива символни константи всъщност са символни константи за целочислената стойност на символите в набора от символи на машината, на която ще се изпълнява програмата (което не е непременно същото като набора от символи, използван отна компютъра, където се компилира програмата). Следователно, ако работите на машина, използваща ASCII символен набор, тогава стойността "0" ще бъде 48, но ако вашата машина използва EBCDIC, тогава ще бъде 240. Използването на символни константи вместо десетична нотация прави програмата по-преносима. Няколко знака също имат стандартни имена, които използват обратната наклонена черта \ като екраниращ знак:
"\b" | върнете се обратно |
"\f" | превод на формат |
"\н" | нова линия |
"\r" | връщане на каретка |
"\T" | хоризонтален раздел |
"\v" | вертикален раздел |
"\\" | обратна наклонена черта (обратна наклонена черта) |
"\"" | единичен цитат |
"\"" | двойни кавички |
"\0" | нула, празен знак, цяло число 0 |
Противно на външния си вид, всеки е един герой. Можете също да представите знак като едно-, дву- или трицифрено осмично число (символът \ последван от осмични цифри) или едно-, дву- или трицифрено шестнадесетично число (\x последвано от шестнадесетични цифри). Например:
"\6" "\x6" 6 ASCII ack "\60" "\x30" 48 ASCII "0" "\137" "\x05f" 95 ASCII "_"
Това позволява всеки знак в машинния набор от знаци да бъде представен и по-специално да се вмъкват такива знаци в символни низове. Използването на цифрова нотация за знаци прави програмата непреносима между машини с различни набори от знаци.
Низовата константа е поредица от символи, оградени в двойни кавички:
Всяка низова константа съдържа един символ повече, отколкото изглежда; всички те в крайна сметка са празнисимвол "\0" със стойност 0.
Низът е от тип "вектор от съответния брой знаци", така че "asdf" е от тип char[5]. Празен низ се записва "" (и е от тип char[1]). Обърнете внимание, че за всеки низ s, strlen(s)==sizeof(s)-1, тъй като strlen() игнорира крайната 0. Конвенцията за обратна наклонена черта за неграфичен знак може също да се използва в рамките на низ. Това прави възможно представянето на двойни кавички и символа \ в низа. Най-често срещаният знак от този вид е знакът за нов ред "\n".
където 7 е ASKII стойността на знака bel (камбана).
Не е възможно да има "истински" нов ред в низ:
"това не е низ, , а синтактична грешка"
Редът обаче може да има обратна наклонена черта, непосредствено последвана от нов ред; и двете ще бъдат игнорирани.
Нов ред, предшестван от екраниране (обратна наклонена черта), не води до нов ред в низа, това е просто конвенция за запис.
Възможно е да има празен символ в низ, но повечето програми няма да приемат, че има знаци след него. Например, низът "asdf\000hjkl" ще бъде третиран от стандартни функции като strcpy() и strlen() като "asdf".
Когато вмъквате числова константа в низ с помощта на осмичен или шестнадесетичен запис, разумно е винаги да използвате трицифрено число. Четенето на записа е достатъчно трудно, без да се налага да се притеснявате дали знакът след константата е цифра или не. Разгледайте тези примери:
char v1[] = "a\x0fah\0129"; // "a" "\xfa" "h" "\12" "9" char v2[] = "a\xfah\129"; // "a" "\xfa" "h" "\12" "9" char v3[] = "a\xfad\127"; // "a" "\xfad" "\127"
Имайте предвид, че двуцифрената шестнадесетична нотация на машини с 9 битабайтовете няма да са достатъчни.
Ключовата дума const може да бъде добавена към декларация на обект, за да направи този обект константа, а не променлива.
const int model = 145; const int v[] = < 1, 2, 3, 4 >;
Тъй като нищо не може да бъде присвоено на константа, тя трябва да бъде инициализирана. Декларирането на нещо като const гарантира, че стойността му няма да се промени в обхвата:
модел = 145; // грешка model++; // грешка
Имайте предвид, че const променя типа, т.е. ограничава начина, по който обектът може да се използва, вместо да указва как трябва да бъде поставена константата. Следователно, например, е доста разумно, а понякога и полезно, да се опише функция като връщаща const:
const char* peek(int i) return private[i]; >
От друга страна, компилаторът може да използва факта, че даден обект е константа по няколко начина (в зависимост от това колко е умен, разбира се). Най-очевидното е, че не е необходимо да се разпределя памет за константа, тъй като компилаторът знае нейната стойност. Освен това постоянен инициализатор често (но не винаги) е постоянен израз, което означава, че може да бъде оценен по време на компилиране. Въпреки това, вектор от константи обикновено трябва да разпредели памет, тъй като компилаторът обикновено не може да разбере кои елементи от вектора са посочени в изрази. Въпреки това, на много машини, дори в този случай, може да се постигне повишаване на ефективността чрез поставяне на константните вектори в памет само за четене.
Използването на указател включва два обекта: самия указател и обекта, към който се сочи. Префиксът на декларация на указател с const прави обекта, но не самия указател, константа.
const char* pc = "asdf"; // указател къмконстанта pc[3] = "a"; // грешка pc = "ghjk"; // добре
За да се опише самият указател, а не посоченият обект, като константен, се използва операцията const*.
char *const cp = "asdf"; // постоянен указател cp[3] = "a"; // добре cp = "ghjk"; // грешка
За да направите двата обекта постоянни, и двата трябва да бъдат декларирани const.
const char *const cpc = "asdf"; // const указател към const cpc[3] = "a"; // грешка cpc = "ghjk"; // грешка
Обект, който е константа, когато е достъпен чрез един указател, може да бъде променлива, когато е достъпен по други начини. Това е особено полезно за функционални параметри. Чрез деклариране на параметър на указател като const, функцията не може да модифицира обекта, към който сочи.
char* strcpy(char* p, const char* q); // не може да промени q
int a = 1; const c = 2; const* p1 = &c; // добре const* p2 = &a; // добре int* p3 = &c; // грешка *p3 = 7; // променя стойността на c
Както обикновено, ако типът е пропуснат от декларацията, се приема, че е int.
Има друг метод за дефиниране на целочислени константи, който понякога е по-удобен от използването на const.
дефинира три цели константи, наречени изброители, и им присвоява стойности. Тъй като стойностите на изброителя се присвояват по подразбиране, започвайки от 0 във възходящ ред, това е еквивалентно на писане:
const ASM = 0; const AUTO = 1; const BREAK = 2;
Преброяването може да бъде наименувано.
Името enum става синоним на int, а не нов тип. Описването на променлива като ключова дума, а не просто int, може да даде на програмиста и компилатора намек, че използването е умишлено.
ключ; калъф на превключвател (ключ) ASM: // нещоправи счупване; case BREAK: // прави нещо счупено; >
кара компилатора да издаде предупреждение, защото се използват само две от трите стойности на ключовите думи.
Можете също да зададете изрично стойности на изброителя.
enum int16 sign=0100000, // знак most_significant=040000, // най-значим least_significant=1 // най-малко значим >;
Такива стойности не трябва да бъдат различни, нарастващи или положителни.