* Класове Памет, Разделно Компилиране
Публикувано на 24 октомври 2008 в раздел С/С++.
Класове Памет, Разделно Компилиране
Всяка променлива в С се характеризира с три атрибута:
1. Тип на променливата - определя стойностите, които променливата може да приема и съответно необходимото количество памет, което трябва да се задели
2. Област на действие - мястото в програмата, където тя е "видима", например разгледаните вече глобални променливи имат по-широка област на действие от локалните
3. Период на активност - част от времето за изпълнение на програмата, през което ще се съхранява последната текуща стойност
В зависимост от областта на действие и периода на активност на променливите в С казваме, че има четири класа памен: extern, auto, static и register.
I. Extern: Не се посочва явно при описанието на променливите. Този клас памет е отделен за "външни" или още "глобални" променливи. Тези променливи се записват в областта за данни на програмата и стойностите им се пазят до самия и край:
int i,j; // клас extern int func(){ ... } void main(){ ... }
Както казахме тези променливи са видими за всички функции и техните стойности се пазят до приключване на програмата.
II. Auto: Отново не се посочва явно при дефиницията. В този клас памет попадат всички "вътрешни" или още "локални" променливи. За тях се отделя памет в стека по време на изпълнение на функцията, в която са дефинирани. Периодът на активност съвпада с областта на действие.
// Формалните параметри x и y са от клас auto func(int x, int y){ // Локалните променливи също са от клас auto float z; for(...;...;...){ // a е от клас auto и е с период на активност до свършването на цикъла int a; }
III. Static: Трябва да се задава явно при декларацията на променливите. Областта от данни, в които се записват променливите е същата като при extern, тоест периода на активност е до края на изпълнението на цялата програма.
Ако дефинирате локална променлива като тип static, то ние просто променяме периода и на активност. Ако не е посочена изрична стойност, променливите от клас static се нулират при компилация. Например:
func(){ // i продължава да е локална променлива, но вече пазим стойността ѝ static int i; i++; ... }
След първото извикване на func промеливата i ще бъде със стойност 1. При повторно извикване на функцията старата стойност ще се е запазила и ще стане 2. Тъй като static не променя областта на действие, то за локални променливи е рядко приложим.
Когато опишем глобална променлива от тип static не променяме периода на активност. Областта на действие обаче се променя, когато става дума за разделно компилиране. Static ще направи променливата достъпна само във файла, в който е дефинирана.
IV. Register: Трябва да се задава явно при декларацията на променливите. Такъв клас памет могат да получат само локални променливи или формални параметри. Променливите от такъв клас се записват в машините регистри, тоест използват най-бързата памет на компютъра. Обикновено ще използваме клас register когато променливата се използва много пъти в изчисленията.
func(register int i){ register int x; ... }
Правилното използване на класове памет води до икономичност при употребата на машинни ресурси.
При разработването на големи и сложни програми е наложително да разделяме програмата на отделни модули. Чрез това се постига по-бързо и ефективно отстраняване на грешките в различните части на програмата и се създава възможност за независимо разработване на части от програмата. Много компилатори на С позволяват независимо компилиране на отделни входни файлове, които образуват една програма. Този процес се нарича "разделно компилиране".
Всеки модул от тези, на които разделяме програмата, представлява самостоятелен вхоен файл. На етап "свързване" обектните файлове на всички модули се обединяват в общ изпълним файл на цялата програма. Всеки програмен файл съдържа множество функции, но само един от тях има главна функция main.
Функциите в различните файлове обменят информация по два начина:
- Чрез обръщение на функции, съдържащи се в други файлове
- Чрез дефиниране на общи глобални променливи за всички файлове
Първият тип обмен на информация между файлове ви е вече позната - всички библиотеки, като ctype.h, stdio.h, stdlib.h, и тн., съдържат функции, които ние използваме.
За да може глобална променлива да бъде достъпна за други файлове е нужно да бъде повторно описана в тях, като се добавим думата extern преди декларацията ѝ:
extern <тип> <име>;
Добави коментар