Лекции по обектно-ориентирано програмиране



страница5/16
Дата25.07.2016
Размер0.95 Mb.
#6568
ТипЛекции
1   2   3   4   5   6   7   8   9   ...   16

8. Изброен тип.

Изброеният тип се въвежда в ANSI C, има го и в C++;

синтаксис:

enum [име_на_тип] { списък от стойности} [списък от променливи];


стойностите са идентификатори; подобно на структури можем да дефинираме променливи заедно с описанието на изброения тип;

например:

enum Boolean { true, false} f;
можем да дефинираме променливи отделно (но само ако сме указали име на съответния изброен тип);
enum Boolean i, j; //в C++ enum може да се изпусне;

в C ключовата дума enum може да се изпусне с дефиниция с typedef;


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

например:

f = false;

if (i!=true)

printf(“Грешка при изчисление!\n”);
компилаторът присвоява на идентификаторите в списъка от стойности цели числа в нарастващ ред, като започва от 0; присвояването се извършва отляво надясно;

например:

f = 0; //също като f = false;

някои компилатори (например Borland C и C++) в такъв случай дават предупреждение; чрез явно преобразуване можем да избегнем предупреждението:

f = (Boolean) 0;
някои компилатори като Borland C и C++ позволяват идентификатор от списъка да бъде инициализиран, като следващите идентификатори получават нарастващи с 1 стойности, освен ако не са инициализирани;
enum counter { start, first, second, tenth = 10, eleventh} c;

компилаторът ще даде стойност 0, 1, 2 на start, first, second и

10, 11 на tenth, eleventh;
в Borland C++ броят байтове, които се разпределят за променлива от изброен тип зависи от стойностите на изброените константи; например, ако всички константи са от тип char, за променливата ще се разпредели 1 байт; в противен случай се използват 2 байта и стойността на променливата от изброен тип ще се интерпретира като int;
enum EXP { a, b, c, d, e, f} Box;

int k = 2;

Box = (enum EXP)(k+1);  Box = d;

Box = k+2;//компилаторът дава предупреждение


името на изброения тип, както имената на типове структури и обединения, може да съвпада с имена на променливи в програмата;
typedef enum { Monday = 1, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday} DAYS;

DAYS weekday, *ptr;

int current_day, to_end, from_start;

scanf (“%d”, ¤t_day);

week_day = Sunday; // weekday = (DAYS) 7;

to_end = week_day – current_day;

from_start = Monday;

Текстови и двоични файлове

Текстов файл (поток) – последователност от символи; той може да бъде разделен на редове, като всеки ред е с произволна дължина и завършва със символа за нов ред (‘\n’); всеки символ се съхранява в отделен байт;

Двоичен файл (поток) – последователност от байтове; той съдържа информацията във вида в който тя се съхранява в оперативната памет; при двоичния файл няма преобразуване на данните – само се прави копие, докато при текстовия файл се прави преобразуване на данните преди се запишат (прочетат); с двоичния файл се прави икономия на външна памет и се печели време; обикновено двоичните файлове се използват за съхраняване на данни от тип структура;
обикновено входа и изхода са буферирани; буферът е временна област в паметта, в която се запомнят въвежданите и извежданите данни; при извеждане, когато буферът се запълни, неговото съдържание се предава в блок и процеса на буферизация започва отново; така се ускорява процеса на предаване на данните;

например при въвеждане функцията getchar() чете един символ от буфера след като в него е записан целия въвеждан ред от клавиатурата (т.е. след натискане на Enter); функциите getch() и getche(), с прототипи описани в conio.h, четат директно от клавиатурата; разликата между двете функции е, че getch() не извежда символа на екрана;

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

при вход и изход от ниско ниво, буферите са разположени в работни области на оперативната памет;

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

stdin – стандартен файл за вход от клавиатурата;

stdout – стандартен файл за изход на екрана;

stderr – стандартен файл за грешки;

тези стандартни файлове са достъпни чрез указатели, които имат същите имена; по подразбиране при scanf се чете от stdin и при

printf се извежда в stdout;

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

етапи при работа с файлове:



  • отваряне на файла

  • обработка

    • четене (компонентите се четат последователно от файла без да се променят)

    • писане (компонентите се записват във файла в реда на тяхното извеждане)

    • актуализация (компонентите се четат от файла и се променя тяхното съдържание)

  • затваряне на файла



9. Текстови файлове. Функции fopen, fclose, getc, putc, fgetc, fputc, ungetc, fscanf, fprintf.

Входът и изходът в C се осъществяват със стандартни функции, описани в stdio.h;

функции, които са описани в stdio.h и са от високо ниво за работа с файлове:

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

например:

FILE *fp;

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

функция fopen;

прототип: FILE *fopen (const char *filename, const char *mode);

функцията fopen отваря файла с име filename и като резултат връща указател към отворения файл; filename е име на файл, така както той се задава в операционната система, т.е. fopen прави връзка между името на файла и указателя към файла, който се използва по-късно в програмата;

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


  • “r” – за четене от файл

  • “w” – за създаване на нов файл

  • “a” – за добавяне към съществуващ файл

  • “r+” – за четене от файл и актуализация

  • “w+” – за създаване на файл и актуализация

  • “a+” – за добавяне към съществуващ файл и актуализация

за работа с текстови файлове, към mode прибавяме ‘t’; например:

“rt”, “wt”, “r+t”  “rt+” и т.н.;

за работа с двоични файлове, към mode прибавяме ‘b’; например:

“rb”, “ab”, “a+b”  “ab+” и т.н.

функцията fopen връща указател NULL при грешка; ако указател към файл има стойност NULL, това значи, че файлът не е отворен; например:


  • няма място на хард диска

  • писане върху защитена за писане дискета или диск;

  • отваряне на несъществуващ файл за четене;

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

пример:

FILE *fp;



if ( ( fp = fopen (“name”, “w”))==NULL)

printf (“Невъзможно е отварянето на файла!\n”);


във всички функции по-надолу се предполага, че указателят fp е инициализиран чрез fopen (с изключение на случаите когато използваме стандартните файлове);
функция fclose;

прототип: int fclose (FILE *fp);

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

ако изпълнението на програмата завършва в главната функция или с функцията exit, автоматично се изпълнява fclose за всички отворени файлове; въпреки това препоръчително е програмистът да затваря всички използвани файлове;

функцията връща като резултат EOF, когато има грешка и 0, ако е изпълнена успешно;
функция getc;

прототип: int getc (FILE *fp);

тази функция връща символа от текущата позиция и увеличава указателят към текущата позиция да сочи към следващия символ от входния поток (файлът сочен от fp); прочетеният символ се преобразува към int без да се отчита при разширението знаковият бит, т.е. символът се интерпретира като unsigned char и се добавят нули при преобразуването; при успешно изпълнение getc връща прочетения символ; при грешка при въвеждането или при достигане на край на файла, функцията връща EOF;

getc(stdin)  getchar()

пример:

int c;


while ( (c = getc (fp))!=EOF)


функция putc;

прототип: int putc (int c, FILE *fp);

функцията извежда символът c в изходния поток, т.е. във файла, сочен от fp; тя връща изведения символ или EOF при грешка;

putc (c, stdout)  putchar()

пример:


char msg[] = “Здравейте!\n”

int i = 0;

while (msg[i])

putc (msg[i++], stdout);


ако функциите getc и putc са реализирани като макроси (например в Borland C++), тогава в стандартната библиотека на компилатора има функции fgetc и fputc, които не са макроси и са еквивалентни на getc и putc;

тяхните прототипи са:

int fgetc (FILE *fp);

int fputc (int c, FILE *fp);

функция ungetc;

прототип: int ungetc (int c, FILE *fp);

тази функция връща обратно символ (например въведен чрез getc) на съответното място във входния поток (сочен от fp); тя се използва когато въвеждаме избирателно само определени символи от файла; функцията връща като резултат върнатия символ при успешно изпълнение или EOF при грешка;

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


int i = 0, ch;

while ( (ch = getchar())!=EOF && isdigit(ch))

i = i*10 + ch – 48;

if (ch!=EOF)

ungetc (ch, stdin); //връщаме символа в буфера на stdin
int isdigit (int ch) е макрос, дефиниран в ctype.h, връща 0, ако ch не е цифра и число различно от 0, ако ch е цифра;
в Borland C++, ако след еднократно изпълнение на getchar или getc се изпълни многократно ungetc, при четенето след това ще се извежда на едно и също място във входния поток (в буфера);

функцията ungetc не е приложима при небуфериран вход;


функция fscanf;

прототип: int fscanf (FILE *fp, const char *format, );

тази функция има еквивалентно изпълнение на функцията scanf, но чете от произволен входен поток (сочен от fp);

fscanf (stdin)  scanf


функция fprintf;

прототип: int fprintf (FILE *fp, const char *format, );

тази функция има еквивалентно изпълнение на функцията printf, но извежда в произволен изходен поток (сочен от fp);

fprintf (stdout)  printf






Сподели с приятели:
1   2   3   4   5   6   7   8   9   ...   16




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

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