|
Размещение структурных переменных в памятиПри анализе размеров структурных переменных иногда число байт, выделенных компилятором под структурную переменную оказывается больше, чем сумма байт ее полей. Это связано с тем, что компилятор выделяет участок ОП для структурных переменных с учетом выравнивания граней, добавляя между полями пустые байты по следующим правилам: - структурные переменные, являющиеся элементами массива начинаются на границе слова, т.е. с четного адреса; - любое поле структурной переменной начинается на границе слова, т.е. с четного адреса и имеет четное смещение по отношению к началу переменной; - при необходимости в конец переменной добавляется пустой байт, чтобы общее число байтов было четное.
Объединения Объединение - поименованная совокупность данных разных типов, размещаемых с учетом выравнивания в одной и той же области памяти, размер которой достаточен для хранения наибольшего элемента. Объединенный тип данных декларируется подобно структурному типу: union ID_объединения { описание полей }; Пример описания объединенного типа: union word { int nom; char str[20]; }; Пример объявления объектов объединенного типа: union word *p_w, mas_w[100]; Объединения применяют для экономии памяти в случае, когда объединяемые элементы логически существуют в разные моменты времени либо требуется разнотипная интерпретация поля данных. Например, поток сообщений по каналу связи пусть содержит сообщения трех видов: struct m1 { char code; float data[100]; }; struct m2 { char code; int mode; }; struct m3 { char code, note[80]; }; Элемент code - признак вида сообщения. Удобно описать буфер для хранения сообщений в виде struct m123 { char code; union { float data[100]; int mode; char note[80]; }; }; Практически все вышесказанное для структур имеет место и для объединений. Декларация данных типа union, создание переменных этого типа и обращение к полям объединений производится аналогично структурам. Пример использования переменных типа union: ... typedef union q { int a; float b; char s[5]; } W; void main(void) { W s, *p = &s; s. a = 4; printf(“\n Integer a = %d, Sizeof(s.a) = %d”, s.a, sizeof(s.a)); p -> b = 1.5; printf(“\n Float b = %f, Sizeof(s.b) = %d”, s.b, sizeof(s.b)); strcpy(p->s, “Minsk”); printf(“\n String a = %s, Sizeof(s.s) = %d”, s.s, sizeof(s.s)); printf(“\n Sizeof(s) = %d”, sizeof(s)); getch(); } Результат работы программы: Integer a = 4, Sizeof(s.a) = 2 Float b = 1.500000, Sizeof(s.b) = 4 String a = Minsk, Sizeof(s.s) = 5 Sizeof(s) = 5
Перечисления Перечисления - средство создания типа данных посредством задания ограниченного множества значений. Определение перечислимого типа данных имеет вид enum ID_перечислимого_типа { список_значений }; Значения данных перечислимого типа указываются идентификаторами. Например: enum marks { zero, two, three, four, five }; Транслятор последовательно присваивает идентификаторам списка значений целочисленные величины 0,1,...,. При необходимости можно явно задать значение идентификатора, тогда очередные элементы списка будут получать последующие возрастающие значения. Например: enum level { low=100, medium=500, high=1000, limit }; Примеры объявления переменных перечислимого типа: enum marks Est; enum level state; Переменная типа marks может принимать только значения из множества {zero, two, three, four, five}. Основные операции с данными перечислимого типа: - присваивание переменных и констант одного типа; - сравнение для выявления равенства либо неравенства. Практическое назначение перечисления - определение множества различающихся символических констант целого типа. Пример использования переменных перечислимого типа: ... typedef enum { mo=1, tu, we, th, fr, sa, su } days; void main(void) { days w_day; // Переменная перечислимого типа int cur_day, _end, _start; // Текущий день недели, начало и конец недели, соответственно clrscr(); puts(“ Введите день недели (от 1 до 7): ”); scanf(“%d”, &cur_day); w_day = su; _start = mo; _end = w_day - cur_day; printf(“\n Понедельник - %d день недели, \ сейчас %d - й день и \n\ до конца недели %d дней (дня)”, _start, cur_day, _end); getch(); } Результат работы программы: Введите день недели (от 1 до 7): 5 Понедельник - 1 день недели, сейчас 5 - й день и до конца недели 2 дней (дня)
18. Файлы в языке С
Файл – это набор данных, размещенный на внешнем носителе и рассматриваемый в процессе обработки и пересылке как единое целое. В файлах размещаются данные, предназначенные для длительного хранения. Различают два вида файлов: текстовые и бинарные. Текстовые файлы представляют собой последовательность ASCII символов и могут быть просмотрены и отредактированы с помощью любого текстового редактора. Бинарные (двоичные) файлы представляют собой последовательность данных, структура которых определяется программно. В языке Си имеется большой набор функций для работы с файлами, большинство которых находятся в библиотеках stdio.h и io.h. Открытие файла Каждому файлу присваивается внутреннее логическое имя, используемое в дальнейшем при обращении к нему. Логическое имя (идентификатор файла) - это указатель на файл, т.е. на область памяти, где содержится вся необходимая информация о файле. Формат объявления указателя на файл следующий: FILE *указатель на файл; FILE - идентификатор структурного типа, описанный в стандартной библиотеке stdio.h и содержащий следующую информацию: type struct {
} FILE;
Прежде, чем начать работать с файлом, т.е. получить возможность чтения или записи информации в файл, его нужно открыть для доступа. Для этого обычно используется функция FILE* fopen (char * ID_файла, char *режим); она берет внешнее представление - физическое имя файла на носителе (дискета, винчестер) и ставит ему в соответствие логическое имя. Физическое имя, т.е. имя файла и путь к нему задается первым параметром - строкой, например, “a:Mas_dat.dat” - файл с именем Mas_dat.dat, находящийся на дискете, “d:\\work\\Sved.txt” - файл с именем Sved.txt, находящийся на винчестере, в каталоге work. Внимание, обратный слеш (\), как специальный символ в строке записывается дважды! При успешном открытии функция fopen() возвращает указатель на файл (в дальнейшем - указатель файла). При ошибке возвращается NULL. Данная ситуация обычно возникает, когда неверно указывается путь к открываемому файлу. Например, если в дисплейном классе нашего университета, указать путь, запрещенный для записи (обычно, разрешенным является d:\work\). Второй параметр - строка, в которой задается режим доступа к файлу: w - файл открывается для записи; если файла с заданным именем нет, то он будет создан; если такой файл существует, то перед открытием прежняя информация уничтожается; r - файл открывается только для чтения; если такого файла нет, то возникает ошибка; a - файл открывается для добавления в его конец новой информации; r+ - файл открывается для редактирования данных - возможны и запись, и чтение информации; w+ - то же, что и для r+; a+ - то же, что и для a, только запись можно выполнять в любое место файла; доступно и чтение файла; t - файл открывается в текстовом режиме; используются поля r, w, a, r+, w+, a+; b - файл открывается в двоичном режиме. Текстовый режим отличается от двоичного тем, что при открытии файла как текстового пара символов «перевод строки», «возврат каретки» заменяется на один символ: «перевод строки» для всех функций записи данных в файл, а для всех функций вывода символ «перевод строки» теперь заменяется на два символа: «перевод строки», «возврат каретки». По умолчанию файл открывается в текстовом режиме. Пример: FILE *f; - объявляется указатель на файл f; f = fopen ("d:\\work\\Dat_sp.cpp", "w"); - открывается для записи файл с логическим именем f, имеющим физическое имя Dat_sp.cpp, находящийся на диске d, в каталоге work. или более кратко: FILE *f = fopen ("d:\\work\\Dat_sp.cpp", "w");
Закрытие файла После работы с файлом доступ к нему необходимо закрыть. Это выполняет функция int fclose (указатель файла). Например, из предыдущего примера файл закрывается так: fclose (f); Для закрытия нескольких файлов введена функция, объявленная следующим образом: void fcloseall (void); Если требуется изменить режим доступа к файлу, то для этого сначала необходимо закрыть данный файл, а затем вновь его открыть, но с другими правами доступа. Для этого используют стандартную функцию: FILE* freopen (char *ID_файла, char *режим, FILE *указатель_файла); Эта функция сначала закрывает файл, объявленный «указателем_файла» (как это делает функция fopen), а затем открывает файл с «именем_файла» и правами доступа «режим». В языке С имеется возможность работы с временными файлами, которые нужны только в процессе работы программы и которые надо удалить после выполнения части вычислений. В этом случае используется функция: FILE* tmpfile (void); которая создает на диске временный файл с правами доступа «w+b», после завершения работы программы или после закрытия временного файла он автоматически удаляется.
Запись - чтение информации Все действия по чтению-записи данных в файл можно разделить на три группы: - операции посимвольного ввода-вывода; - операции построчного ввода-вывода; - операции ввода-вывода по блокам. Рассмотрим основные функции, применяемые в каждой из указанных трех групп операций. Посимвольный ввод-вывод В функциях посимвольного ввода-вывода происходит прием одного символа из файла или передача одного символа в файл:
Построчный ввод-вывод В функциях построчного ввода-вывода происходит перенос из файла, или в файл строк символов:
Блоковый ввод-вывод В функциях блокового ввода-вывода работа происходит с целыми блоками информации:
Форматированный ввод-вывод производится функциями:
Данные функции аналогичны функциям scanf () и printf (), рассмотренным раньше, только добавлен параметр – указатель на файл.
Текстовые файлы Для работы с текстовыми файлами удобнее всего пользоваться функциями fprintf(), fscanf(), fgets() и fputs(). Создание текстовых результирующих файлов обычно необходимо для оформления отчетов по лабораторным и курсовым работам. Рассмотрим пример создания текстового файла: #include<stdio.h> void main(void) { FILE *f1; int a=2, b=3; If(!(f1=fopen(“d:\\work\\f_rez.txt”,”w+t”))) { puts(“Файл не создан!”); return; } fprintf(f1,” Файл результатов \n”); fprintf(f1,” %d плюс %d = %d\n”,a,b,a+b); fclose(f1); } Просмотрев содержимое файла, можно убедиться, что данные в нем располагаются точно как на экране при использовании функции printf().
Бинарные файлы Бинарные (двоичные) файлы обычно используются для организации баз данных, состоящих, как правило, из объектов структурного типа. При чтении-записи бинарных файлов удобнее всего пользоваться функциями, выполняемыми блоковый ввод-вывод fread () и fwrite (). Рассмотрим наиболее распространенные функции с помощью которых можно организовать работу с файлами:
Пример программы работы с файлом структур: ... struct Sved { char Fam[30]; float S_Bal; } zap,zapt; char Spis[]="c:\\bc31\\work\\Sp.dat"; FILE *F_zap; FILE* Open_file(char *, char *); void main (void) { int i, j, kodR, size = sizeof(Sved); while(1) { puts("Создание - 1\nПросмотр - 2\nДобавление - 3\nВыход - 0"); switch(kodR = getch()) { case ‘1’: case ‘3’: if(kodR==1) F_zap = Open_file (Spis,"w+"); else F_zap = Open_file (Spis,"a+"); while(2) { cout << "\n Fam "; cin >> zap.Fam; if((zap.Fam[0])=='0') break; cout << "\n Средний балл: "; cin >> zap.S_Bal; fwrite(&zap,1,size,F_zap); } fclose(F_zap); break; case ‘2’: F_zap = Open_file (Spis,"r+"); int nom=1; while(2) { if(!fread(&zap,size, 1, F_zap)) break; printf(" %2d: %20s %5.2f\n", nom++, zap.Fam, zap.S_Bal); } fclose(F_zap); break; case ‘0’: return; // exit(0); } // Конец While(1) } // Конец Switc } // Конец программы
FILE* Open_file(char *file, char *kod) { FILE *f; if(!(f = fopen(file, kod))) { puts(“Файл не создан!”); getch(); exit(1); } else return f; }
Список рекомендуемой литературы
1. Бусько В.Л., Корбит А.Г. и др. Программирование. Лабораторный практикум для студентов 1-2-го курсов всех специальностей БГУИР всех форм обучения. Часть 2. Основы программирования на алгоритмическом языке С. 2. Аксенкин М.А., Целобенок О.Н. Язык С. - Мн.: Унiверсiтэцкае, 1995. – 302 c. 3. Березин Б.И., Березин С.Б. Начальный курс С и С++. – М.: Диалог-МРТИ,1999. - 288 с. 4. Берри В., Микинз Б. Язык СИ: введение для программистов. - М.: Финансы и статистика,1988. 5. Больски М.Н. Язык программирования СИ. Справочник. - М.: Радио и связь, 1988. 6. Демидович Е.М. Основы алгоритмизации и программирования. Язык СИ. - Мн.: Бестпринт, 2001. – 440 c. 7. Касаткин А.И., Вольвачев А.Н. Профессиональное программирование на языке Си: Oт Turbo–C к Borland C++: Справочное пособие – Мн.: Вышэйшая школа,1992. - 240 с. 8. Касаткин А.Н. Профессиональное программирование на языке СИ. Управление ресурсами. Справочное пособие. Мн.: Высш. школа.1992 9. Керниган Б., Ритчи Д. Язык программирования Си. - М.: Финансы и статистика,1992. - 271 с. 10. Климова Л.И. С++. Практическое программирование. - М.: Кудиц-Образ, 2001. – 587 c. 11. Котлинская Г.П., Галиновский О.И. Программирование на языке СИ. - Мн.: Выш.шк., 1991. – 155 c. 12. Подбельский В.В., Фомин С.С. Программирование на языке Си. М.: Финансы и статистика. 2001. 13. Романовская Л.М., Русс Т.В., Свитковский С.Г. Программирование в среде СИ для ПЭВМ ЕС. - М.: Финансы и статистика, 1992. 14. Страуструп Б. Язык программирования С++. 2-е изд.: В 2 т. Киев: ДиаСофт,1993. 15. Тимофеев В.В. Программирование в среде С++ Builder 5. - М.: БИНОМ, 2000. 16. Уингер Р. Язык Турбо СИ. - М.: Мир, 1991. 17. Уэйт М., Прама С., Мартин Д. Язык СИ. Руководство для начинающих. - М.: Мир, 1988. 18. Фьюэр А. Задачи по языку СИ. - М.: Финансы и статистика, 1985. 19. Хэнкок Л., Кригер М. Введение в программирование на языке СИ. - М.: Радио и связь,1986. 20. Шилд Г. Программирование на Borland С++. - Мн.: ПОПУРРИ, 1999. – 800 c. 21. Юлин В.А., Булатова И.Р. Приглашение к СИ. - Мн.: Высш.шк., 1990.
Список используемой литературы 1. Синицын А.К. Конспект лекций по курсу «Программирование» для студентов 1-2-го курсов радиотехнических специальностей. - Мн.: БГУИР, 2001. - 75с.: ил. 10. Приложение 1 Что вызывает тренды на фондовых и товарных рынках Объяснение теории грузового поезда Первые 17 лет моих рыночных исследований сводились к попыткам вычислить, когда этот... ЧТО ПРОИСХОДИТ, КОГДА МЫ ССОРИМСЯ Не понимая различий, существующих между мужчинами и женщинами, очень легко довести дело до ссоры... Что делает отдел по эксплуатации и сопровождению ИС? Отвечает за сохранность данных (расписания копирования, копирование и пр.)... Система охраняемых территорий в США Изучение особо охраняемых природных территорий(ООПТ) США представляет особый интерес по многим причинам... Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:
|