Главная страница Случайная лекция Мы поможем в написании ваших работ! Порталы: БиологияВойнаГеографияИнформатикаИскусствоИсторияКультураЛингвистикаМатематикаМедицинаОхрана трудаПолитикаПравоПсихологияРелигияТехникаФизикаФилософияЭкономика Мы поможем в написании ваших работ! |
Структурный объект («Запись»)При использовании массива подразумевается, что: 1. Число его элементов ограничено. 2. Все элементы принадлежат к одному и тому же типу и имеют один и то же размер. 3. Доступ к элементам организуется в соответствии с их положением в массиве. Реальные множества данных редко бывают однотипными. Порядок использования данных может оказаться несущественным или может определяться значениями данных. Дополнительные методы агрегирования данных – структуры. Структура – элемент данных, содержащий набор полей неоднородного типа. Каждое поле имеет имя, обеспечивающее прямой доступ к данным в поле. Основные операции со структурами: Тип элемента структуры может быть любым: массив, структура, указатель на объект того же или ранее описанного структурного типа, указатель на функцию и т.д. Объявление структуры вводит новый производный тип, структурный тип. Объявление структуры задает имя структурной переменной и последовательность переменных величин, называемых элементами структуры, которые могут иметь различные типы. struct [имя_типа_структуры] { список объявлений элементов } [описатель [, описатель]…]; struct имя_типа_структуры описатель[, описатель]…; Имя_типа_структуры – идентификатор, который именует тип структуры, определяемый списком объявлений элементов. Элементы структуры могут быть как базовых, так и производных типов. Определение структурного типа без последующего списка описателей вводит только шаблон (формат, внутреннее строение) структуры. С именем структурного типа не связан никакой конкретный объект, с его помощью нельзя сформировать уточненные имена элементов. struct Point { char name[N]; float x, y; } xx, yy, coord[M], *pnt; … struct Point city_1, city_2, towns[M], *pt;
Для обращения к объектам, входящим в качестве элементов в конкретную структуру, используются уточненные имена: имя_объекта_структурного_типа . имя_элемента_структуры. yy . x = 0.756; yy . y = - 0.234; gets (coord[0] . name); scanf (”%f %f”, &coord[i] . x, &coord[i] . y); При определении структур возможна их инициализация: Struct address { char country[N], city[N], index [L]; int home, f; } sibiryak = {”Россия”, «Новосибирск”, ”630092”, 30, 26}; Указатель на структуру может входить в определение того же структурного типа. Значение указателя на структуру – это номер байта, начиная с которого структура размещается в памяти. Структурный тип задает её размеры и тем самым определяет, на какую величину изменится значение указателя, если к нему прибавить единицу.
Элементом структуры может быть структура, тип которой уже определен. Элементами структуры могут быть массивы, и массивы могут содержать в качестве элементов структуры. Идентификаторы элементов разных структур могут совпадать между собой и с идентификаторами обычных переменных. Для структур могут быть определены ссылки:
struct Point &refx = xx;
Функция может в качестве параметров получать и возвращать как результат: структуру, указатель на структуру и ссылку на структуру. Сходство и отличия массива и структуры:
Оба являются структурами со «случайным доступом» к элементам. Структура более универсальна, так как содержит элементы разных типов. Массив предоставляет большие возможности, так как селекторы его компонентов могут быть выражениями, а селекторы компонентов структуры – это фиксированные идентификаторы, задаваемые в описании типа. Размер структуры определяется операцией sizeof (имя_типа). Набор функций для работы с массивом структур: typedef struct Student { char Name [L]; // фамилия студента unsigned int Was_born; // год рождения char Code[L]; // шифр студента unsigned int Evaluates[N]; // экзаменационные оценки }; 1. Ввод / добавление информации о студентах. Student * Enter_Data (Student *base, int *k) { char temp[L]; int i; puts(" Вводи данные:"); fflush (stdin); for (i = *k; i < M; i++) { printf (" Фамилия:"); gets (base[i].Name); if (base[i].Name[0]=='\0') { *k = i; return base;} printf (" Год рождения:"); gets (temp); base[i].Was_born = atoi (temp); printf (" Шифр:"); gets (base[i].Code); base[i]. Evaluates [0] = 0; } *k = i; return base; } 2. Изменение данных о студентах (оценки за семестр). void Add_Ball (Student *base, int n) { char temp[L]; int i, j; puts (" Вводи оценки:"); for (i = 0; i < n; i++) { printf ("\n %s \t", base[i].Name); for (j = 0; j < N; j++) scanf ("%d", &base[i]. Evaluates [j]); } } 3. Упорядочение массива структур по убыванию среднего балла студентов. void Medium_Ball (Student *base, int n) { float Medium[M], temp; int i, j, k, sum; Student tmp; for (i = 0; i < n ; i++) { sum = 0; for (j = 0; j < N; j++) sum += base[i]. Evaluates [j]; Medium [i] = (float) sum / N; } for (i = 0; i < n - 1; i++) { k = i; for (j = i + 1; j < n ; j++) if ((Medium [k] - Medium [j]) < 0) k = j; temp = Medium [i]; Medium [i] = Medium [k]; Medium [k] = temp; tmp = base[i]; base[i] = base[k]; base[k] = tmp; } } 4. Сортировка массива структур по фамилиям студентов. void Sort_base (Student *b, int n) { int i, j, min; Student temp; for (i = 0; i < n - 1; i++) { min = i; for (j = i+1; j < n; j++) if (strcmp (b[min].Name, b[j].Name) > 0) min = j; temp = b[i]; b[i] = b[min]; b[min] = temp; } } 5. Бинарный поиск в упорядоченном массиве структур. void Bin_search (Student *base, int n) { int i, j, l = 0, r = n - 1, f = 0; char name[L]; printf (" Фамилия? "); scanf ("%s", name); while ((l<= r) && (f == 0)) { i = (l + r) / 2; if (strcmp (base[i].Name, name)==0) { f=1; printf ("\n %s \t %i \t %s \t", base[i].Name, base[i].Was_born, base[i].Code); for (int j = 0; j < N; j++) printf ("%d\t", base[i]. Evaluates [0]); break; } if (strcmp (base[i].Name, name) < 0) l = i + 1; if (strcmp (base[i].Name, name) > 0) r = i - 1; } if (f == 0) puts ("Нет данных!"); } 6. Вывод информации о студентах на экран. void Print_base (Student *base, int n, char *message) { puts (message); for (int i = 0; i < n ; i++) { printf ("\n %s \t %i \t %s \t", base[i].Name, base[i].Was_born, base[i].Code); for (int j = 0; j < N; j++) printf ("%d\t", base[i]. Evaluates [j]); } } 7. Сохранить информацию о студентах в бинарном файле. void Save_in_File (FILE* file_pnt, Student * base, int n) { int k = 0; while(k != n) // записываем записи в файл { fwrite ( & base [k], sizeof (Student), 1, file_pnt); k++; } } 8. Загрузить из файла данные о студентах. Student *Load_from_File (FILE* file_pnt, int &n) { int i = 0; Student *base; fseek (file_pnt, 0L, 2); // «встать» на конец файла n = ftell (file_pnt) / sizeof (Student); // определить количество записей base = (Student *) malloc (n * sizeof (Student)); // выделить память rewind (file_pnt); // «встать» на начало файла while (i < n) // считываем записи из файла { fread (&base [i], sizeof(Student), 1, f); i++; } return base; } Файлы Файл – поименованный участок памяти на диске. Последовательность данных, которые считываются из файла или записываются в файл, образуют поток. Поток управляет файловым указателем, который определяет текущую позицию в потоке. Библиотечные функции для работы с файлом: FILE *fopen (char *Name, char *Mode); открывает файл с именем Name в заданном режиме Mode, например, “w” – создает файл для записи, “r” – открывает файл для чтения, «w+» – создает файл для записи и чтения, “r+” – открывает файл для чтения и записи. Добавление литеры b в модификатор режима открытия файла явно указывает на то, что файл открывается как бинарный, например «wb+» или “rb+”. Функция возвращает указатель на файловый поток. int fclose (FILE *Stream); закрывает файловый поток, открытый функцией fopen(). int feof (FILE *stream); – обнаруживает конец файла в потоке.
int fseek (FILE *Stream, long offset, int whence); – позиционирует указатель в файле, на который ссылается поток Stream, на число байт, равное значению offset относительно начала (whence = 0), конца (whence = 2) или текущей позиции (whence = 1). Возвращает 0 при удачном смещении и 1 при ошибке. int rewind (FILE *stream); – устанавливает указатель файла на начало потока. long int ftell (FILE *stream); – возвращает положение указателя текущей позиции файла, связанного с потоком stream. int fgetc (FILE *stream); – возвращает следующий символ из потока. int fputc (int c, FILE *stream); – выводит символ в поток.
char *fgets (char *s, int n, FILE *stream); – получает строку символов из потока. int fputs (char *string, FILE *stream); – выводит строку символов в поток. size_t fread (void *ptr, size_t size, size_t n, FILE *stream); – считывает n блоков размером size в память по адресу ptr из потока stream. Возвращает количество прочитанных блоков. size_t fwrite (const void *ptr, size_t size, size_t n, FILE *stream); – записывает n блоков размером size из памяти по адресу ptr в поток stream. Возвращает количество записанных блоков.
int fflush (FILE *stream); – очищает поток. int remove (const char *filename); – удаляет файл. int rename (const char *oldname, const char *newname); – изменяет имя файла (можно использовать для пересылки).
Определить размер файла (в байтах) можно следующей последовательностью операторов: FILE * file_pnt = fopen (filename, “rt”); fseek (file_pnt, 0L, SEEK_END); printf (“ Размер файла %d байтов”, ftell (file_pnt)); Набор функций для работы с текстовым файлом: 1. Открыть файл. FILE *Open_file () { char filename [L]; FILE *f_pnt; puts ("\n Введи имя файла:"); gets (filename); if ((f_pnt = fopen (filename, "rt")) == NULL) { puts ("Файл не найден!"); return NULL;} return f_pnt; } 2. Исключить из строк файла заданную подстроку. Измененные строки сохранить в новом файле. char* Delete_Substring ( char* String, char* Substr) { char *ptr = String; int len = strlen (Substr); while (*ptr) if ((ptr = strstr (ptr, Substr)) != NULL) { *ptr = '\0'; strcat (String, (ptr + len)); } return String; } void Delete_from_String (FILE *f_inp, FILE *f_out, char *Delstr) { char string[N], *temp; while (!feof (f_inp)) { fgets (string, sizeof (string), f_inp); temp = Delete_Substring (string, Delstr); fputs (temp, f_out); } } 3. Заменить в каждой строке файла одну подстроку на другую. char* Replace ( char* String, char* Oldstr, char* Newstr) { char temp[N], *ptr = String; int len1 = strlen (Oldstr), len2 = strlen (Newstr); while (*ptr) if ((ptr = strstr (ptr, Oldstr))!= NULL) { *ptr = '\0'; strcpy (temp, String); strcat (temp, Newstr); strcat (temp, (ptr + len1)); ptr += len2; strcpy (String, temp); } return String; } 4. Вывести статистику появления ключевых слов в программе на языке Си. // Посимвольно читаем слово из файла void Read_Word ( char* s, FILE* fp) { char c ,*ps = s; c = fgetc (fp); while (!isalnum(c) && !feof (fp)) c = fgetc (fp);// пропускаем разделители while ( isalnum(c) && !feof (fp)) { *ps ++ = c; c = fgetc (fp);} // формируем слово *ps = '\0'; } // Определяем, является ли слово ключевым (бинарный поиск) int Is_Key_Word (char *Key[], int n, char *s) { int i, l = 0, k, r = n; do { i = (l + r) / 2; if ((k = strcmp (s, Key[i])) == 0) return i; if (k > 0) l = i + 1; else r = i - 1; } while (l <= r); return -1; } void Keywords (FILE *ft) { char *Keywords[] = {"break","case","char","do","double","else","float", "for","if","int","long","main","return","sizeof","struct", "switch","void","while"}; char word [L]; int n = sizeof (Keywords) / sizeof (char*); int *Counter = new int [n], i; for (i = 0; i < n; i++) Counter[i] = 0; while(!feof (ft)) { Read_Word(word, ft); if((i = Is_Key_Word (Keywords, n ,word)) >= 0) Counter[i] ++; } puts (" Статистика: "); for (i = 0; i < n; i++) printf ("%s \t %d\n", Keywords [i], Counter[i]); delete []Counter; }
Дата добавления: 2014-11-14; просмотров: 369; Нарушение авторских прав Мы поможем в написании ваших работ! |