База данных, построенная на основе классов

Министерство  образования и науки Российской Федерации

Федеральное агентство по образованию 
 
 

ГОУ ВПО  «Уральский государственный технический  университет -УПИ»

Факультет ускоренного обучения

Кафедра микропроцессорной техники 
 
 
 
 
 
 
 
 
 
 
 

База  данных, построенная на основе классов.

КУРСОВАЯ  РАБОТА 
 
 
 
 
 
 
 
 
 
 
 

Руководитель       С.С. Ваулин

Студент гр. СПВ-35012УК    Зубарев А.А

    
 
 
 

Екатеринбург 2008 г.

 

Содержание 
 
 
 
 

Введение 

1. Постановка  задачи 

2. Общее описание  программы 

3. Описание классов 

4. Описание методов классов 

5. Процедура main () 

6. Блок схема  процедуры main 

Список литературы 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Введение 

     Предполагается, что в идеальном случае разработка программы делится на три этапа: вначале необходимо добиться ясного понимания задачи, затем определить ключевые понятия, используемые для ее решения, и, наконец, полученное решение выразить в виде программы. Однако, детали решения и точные понятия, которые будут использоваться в нем, часто проясняются только после того, как их попытаются выразить в программе. Именно в этом случае большое значение приобретает выбор языка программирования.

      Во  многих задачах используются понятия, которые трудно представить в программе в виде одного из основных типов или в виде функции без связанных с ней статических данных. Такое понятие может представлять в программе класс. Класс - это тип; он определяет поведение связанных с ним объектов: их создание, обработку и уничтожение. Кроме этого, класс определяет реализацию объектов в языке, но на начальных стадиях разработки программы это не является и не должно являться главной

заботой. Для  написания хорошей программы  надо составить такой набор классов, в котором каждый класс четко представляет одно понятие. Обычно это означает, что программист должен сосредоточиться на вопросах: Как создаются объекты данного класса? Могут ли они копироваться и

(или) уничтожаться? Какие операции можно определить над этими объектами? Если на эти вопросы удовлетворительных ответов не находится, то, скорее всего, это означает, что понятие не было достаточно ясно сформулировано. Тогда, возможно, стоит еще поразмышлять над задачей и

предлагаемым  решением, а не немедленно приступать к программированию, надеясь в  процессе него найти ответы. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

1. Постановка  задачи 

     1.1 Создать класс, обеспечивающий хранение данных, и защищающий эти данные от использования вне класса.

     1.2 Создать класс, обеспечивающий  хранение экземпляров предыдущего  класса в списке.

     1.3 Написать программу которая выполняла следующие процессы: создание нового элемента, удаление элемента из списка, поиск элемента в списке, сохранение списка, вывод списка . 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

2. Общее описание программы. 
 
 

     В данном курсовом проекте разрабатывается  примитивная программа сотрудников предприятия. В программе присутствуют два класса: класс elem и класс sp. Экземпляр класса elem содержит информацию об одном сотруднике. Класс sp предназначен для хранения экземпляров класса elem в полносвязном списке и возможностью изменения списка (добавление нового элемента, удаление элемента, сохранение списка в файле и т.д.). 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 

3. Описание классов. 
 
 

3.1 Класс elem. 

class elem

{

char fam[30],oth[30],name[30];

int nom;

elem *p1,*p2;

public:

void set_elem ();

void show_elem();

friend class sp;

}  ; 

     Класс содержит строковые массивы fam, name, oth в которых хранится информация соответственно об фамилии, имени, отчестве сотрудника и поле целого типа nom для хранения уникального номера сотрудника. Поля указатели p1 и p2 предназначены ля организации хранения экземпляров класса в виде полносвязного списка p1 – указатель на предыдущий элемент, а p2 – указатель на следующий элемент списка. В классе объявлены два метода set_elem и show_elem. Первый предназначен для ввода данных о сотруднике, а второй для вывода информации о сотруднике на экран (ниже данные методы рассмотрены более поробно). Класс sp, рассмотренный ниже, объявлен дружественным классу elem ( friend class sp ). Дружественный потому что методы класса sp должны непосредственно изменять указатели в классе elem  

3.2 Класс sp. 

class sp

{

elem *head,*temp1,*temp2;

public:

void init ();

void new_el ();

void del_el ();

void poisk ();

void show_sp();

void save ();

void free_m();

} 
 
 
 

 

     Поле  указатель head типа elem является вершина списка и предназначено для хранения указателя на первый элемент списка. Назначение полей temp1 и temp2 будет понятно при рассмотрении метода new_el. 

В классе объявлены  семь методов: 

init – инициализация экземпляра класса (инициализация списка).

new_el – создание нового элемента списка.

del_el – удаление выбранного элемента списка.

poisk – поиск элемента по номеру.

show_sp – вывод списка на экран.

save – сохранение списка в файле.

free_m – освобождение памяти при выходе из программы. 

Каждый метод подробно рассмотрен в следующем разделе. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 

4. Описание  методов классов. 
 

4.1 Класс elem.

4.1.1 Метод set_elem. 

void elem::set_elem ()

{

clrscr ();

printf ("Conduct surname\n");

scanf("%s",fam);

printf ("Conduct patronymic\n");

scanf("%s",oth);

printf ("Conduct name\n");

scanf("%s",name);

printf("Conduct number\n");

scanf("%u",&nom);

} ;

       С помощью функции printf пользователю предлагается вести имя, фамилию, отчество или номер а с помощью функции scanf введённые с клавиатуры данные записываются в соответствующее поле в соответствующем формате. 
 
 
 
 
 
 
 

4.1.2 Метод show_elem. 

void elem::show_elem()

{

printf("\nSurname of the employee:      %s",fam);

printf("\n\nPatronymic of the employee:   %s",oth);

printf("\n\nName of the employee:         %s",name);

printf("\n\nOrganic number:               %u\n\n",nom);

};

 С помощью функции printf  выводятся донные о сотруднике.

 
 
 
 
 
 
 
 
 

4.2 Класс sp. 

4.2.1 Метод new_el. 

void sp::new_el()

{

temp1=new elem;

temp1->set_elem(); 

if (head==NULL)

{

head=temp1;

temp1->p1=NULL;

temp1->p2=NULL;

temp2=temp1;

}

else

{

temp2->p2=temp1;

temp1->p1=temp2;

temp1->p2=NULL;

temp2=temp1;

}

} ; 

Предназначен  для создания нового элемента и добавления его в конец списка. Указатели temp1 и temp2, объявленные в классе предназначены для хранения промежуточных данных temp1, хранит адрес нового элемента, а temp2 адрес предыдущего элемента. Память для нового элемента выделяется процедурой new, затем методом set_elem заполняются поля элемента. Далее проверяется, является ли элемент первым в списке if (head==NULL) и, если да, то указателю head присваивается указатель на данный элемент и также указателю temp2 для использования его при добавлении нового элемента. Если же  список уже существует, то элемент добавляется в коней списка. Предыдущий элемент связывается с новым (temp2->p2=temp1), а новый с предыдущим (temp1->p1=temp2). Указателю на следующий элемент присваивается NULL (temp1->p2=NULL). Указатель на новый элемент сохраняется в переменной temp2  (temp2=temp1), для использования его при добавлении нового элемента списка. 

 
 
 
 
 
 
 
 
 
 

4.2.2 Метод free_m. 

void sp::free_m ()

{

elem *q1,*q2;

if (head!=NULL)

{

q1=head;

while (q1->p2!=NULL)

{

q2=q1->p2;

delete q1;

q1->p1=NULL;

q1->p2=NULL;

q1=q2;

}

delete q1;

delete head;

head=NULL;

q1=NULL;

}

} 
 

      Предназначен  для освобождении памяти при выходе из программы.

Указатель q1 нужен для хранения адреса текущего элемента списка, а q2 следующего. q1 присваивается адрес первого элемента списка (q1=head), затем в условии цикла, проверяется не является ли текущий элемент последним (q1->p2!=NULL) и если условие истинно, то в q2 сохраняется адрес следующего элемента (q2=q1->p2), а текущий освобождается (delete q1). Затем q1 присваивается адрес текущего элемента (q1=q2) и цикл повторяется. Далее освобождается последний элемент списка и голова списка (delete head). Так же, проверяется существует ли список вообще (if (head!=NULL) ) и, если нет то выводится соответствующее сообщение (printf ("The list does not exist\n\n"). 
 
 

 
 
 
 
 
 
 
 
 
 
 
 

4.2.3 Метод del_el. 
 

void sp::del_el()

{

elem *p,*tp1,*tp2;

int t1=1,t2=0; 

if (head!=NULL)

{

p=head;

while (p->p2!=NULL)

{

p=p->p2;

++t1;

}

printf("The base conteins %u",t1);

printf(" of elements.\n\n");

printf ("What element you want to remove ?\n\n");

scanf("%u",&t2);

if (t2<=t1)

{

p=head;

int i=1;

while (i!=t2)

{

p=p->p2;

i++;

}

if (p->p1!=NULL && p->p2!=NULL)

{

tp1=p->p1;

tp2=p->p2;

delete (p);

tp1->p2=tp2;

tp2->p1=tp1;

}

else if (p->p1==NULL)

{

tp1=p->p2;

delete (p);

head=tp1;

head->p1=NULL;

}

else if (p->p2==NULL)

{

tp1=p->p1;

delete(p);

tp1->p2=NULL;

temp2=tp1;

}

}

else printf ("Such element is not present\n\n");

}

else printf("The list does not exist\n\n");

};    

 

Предназначен  для удаления выбранного элемента списка. Переменная предназначена для хранения адреса текущего элемента списка, tp1 и tp2 для 

хранения предыдущего  и последующего элементов.

      Сначала, проверяется существует ли список if (head!=NULL)и, если да, то в цикле проверяется сколько элементов в списке и записывается в переменную t1. Затем пользователю предлагается ввести номер элемента, который он хочет удалить. Номер записывается в переменную t2. Затем проверяется есть ли элемент с таким номером в списке if (t2<=t1) и в цикле

while (i!=t2) осуществляется переход на выбранный элемент. После чего выясняется, где находится выбранный элемент, в начале if (p->p1==NULL), конце if (p->p2==NULL) или между элементами списка          if (p->p1!=NULL && p->p2!=NULL) и удаляется соответствующим образом. При удалении элемента из конца списка, указателю temp2 необходимо присвоить адрес предыдущего элемента т.к. он используется при добавлении нового элемента. 

4.2.4 Метод poisk. 

void sp::poisk()

{

elem *p;

int t1,t2=0; 

if (head!=NULL)

{

p=head;

printf ("Conduct number\n");

scanf ("%u",&t1); 

while (p->p2!=NULL)

{

if (p->nom==t1)

{

p->show_elem();

t2++;

}

p=p->p2; 

};      // end while 

if (t2==0) printf ("Such element is not present\n\n");

}

else printf("The list does not exist\n\n"); 

};

 

     Осуществляет  поиск элемента по номеру (поле nom). Сначала как и в остальных методах проверяется наличие списка if (head!=NULL). Затем пользователю предлагается ввести табельный номер искомого сотрудника, который записывается в переменную t1. В цикле while (p->p2!=NULL) осуществляется перебор всех элементов списка и вывод тех элементов, поле nom которых совпадает с номером, введённым пользователем. Если не найдено ни одного элемента, то выводится соответствующее сообщение     if (t2==0) printf ("Such element is not present\n\n"). 
 

4.2.5 Метод show_sp. 

void sp::show_sp()

{

elem *p=NULL;

if (head!=NULL)

{

p=head ;

printf("\n");

printf("BASE: ");

printf("\n\n");

p->show_elem();

while ((p->p2)!=NULL)

{

p=p->p2;

p->show_elem();

} ;

}

else printf ("The list does not exist\n\n"); 

};

     Процедура достаточно проста и не требует подробного пояснения. После проверки наличия  списка if (head!=NULL), список выводится в цикле помощью метода show_elem(). 
 
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

4.2.6 Метод save. 

Сохраняет список в файле.  

void sp::save()

{

int i;

char g[30];

elem *p;

FILE *list;

list=fopen("\\base.txt","wt"); 

if (list!=NULL)

{ 

if (head!=NULL)

{ 

p=head; 

while (p->p2!=NULL)

{

fprintf(list,"%s\n%s\n%s\n%u\n",p->fam,p->oth,p->name,p->nom);

p=p->p2;

}

fprintf(list,"%s\n%s\n%s\n%u\n",p->fam,p->oth,p->name,p->nom); 

} 

else printf("The list does not exist\n\n"); 

}

else printf ("File of database is not created"); 
 

fclose(list);

}; 

     Сохраняет список в файле. Файл создаётся с  помощью процедуры   fopen . Затем проверяется создан ли файл и существует ли список после чего при выполнении этих двух условий список сохраняется в цикле с помощью процедуры fprintf.

 
 
 
 
 
 
 
 
 
 
 

4.2.7 Метод init. 

     Процедура достаточно большая и текст её можно просмотреть в распечатке листинга программы, которая приведена в качестве приложения.

      Данный  метод осуществляет инициализацию  списка, которая заключается в  проверке существования файла базы данных и, если он существует, то происходит чтение дынных из файла и создание списка.

      При чтении из файла считываются символы перевода строки \n, которые необходимо удалить т.к. при сохранении списка они также попадут в файл :

     while(j<=30)

     {

     if (p->oth[j]=='\n') p->oth[j]=p->oth[j+1];

     j++;

     }

     Затем создаётся список. Если файл базы данных не создан или пуст, то выводится соответствующее сообщение. Ещё один нюанс заключается в том, что необходимо удалить последний элемент списка т.к. последним символом файла является символ перевода строки, то он благополучно считывается и в результате этого создаётся пустой элемент списка, который необходимо удалить, что делается в конце процедуры:

     tp=tp->p1;

     tp->p2=NULL;

     delete(p);

     После создания списка переменной temp2 присваивается указатель на последний элемент списка temp2=p->p1;, которая используется при добавлении нового элемента в список.  
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Список  литературы 

1. Бьери Страуструп "Язык программирования С++" 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Листинг программы 
 
 

#include <stdio.h>

#include <conio.h>

#include <process.h>

#include <dos.h>

#include <io.h>

#include <string.h> 
 
 

class elem

{

char fam[30],oth[30],name[30];

int nom;

elem *p1,*p2;

public:

void set_elem ();

void show_elem();

friend class sp;

}  ; 
 
 
 

class sp

{

elem *head,*temp1,*temp2;

public:

void init ();

void new_el ();

void del_el ();

void poisk ();

void show_sp();

void save ();

void free_m();

}; 
 
 
 
 

//       Methods of class elem 

void elem::set_elem ()

{

clrscr ();

printf ("Conduct surname\n");

scanf("%s",fam);

printf ("Conduct patronymic\n");

scanf("%s",oth);

printf ("Conduct name\n");

scanf("%s",name);

printf("Conduct number\n");

scanf("%u",&nom);

} ; 
 
 

void elem::show_elem()

{

printf("\nSurname of the employee:      %s",fam);

printf("\n\nPatronymic of the employee:   %s",oth);

printf("\n\nName of the employee:         %s",name);

printf("\n\nOrganic number:               %u\n\n",nom);

};

//           end class elem 
 
 
 
 
 

//        Methods of   class   sp

void sp::free_m ()

{

elem *q1,*q2;

if (head!=NULL)

{

q1=head;

while (q1->p2!=NULL)

{

q2=q1->p2;

delete q1;

q1->p1=NULL;

q1->p2=NULL;

q1=q2;

}

delete q1;

delete head;

head=NULL;

q1=NULL;

}

} 

void sp::init ()

{ 
 

FILE *fn;

char t1[30];

int i=30,j=0;

elem *p,*tp;

fn=fopen("\\base.txt","rt"); 

if (fn!=NULL)

{

fgets(t1,i,fn);

if(feof(fn)==0)

{

fclose(fn);

fn=fopen("\\base.txt","rt");

head=NULL; 

while  (!feof(fn))

{

p=new(elem); 

fgets(p->fam,i,fn);

while(j<=30)

{

if (p->fam[j]=='\n') p->fam[j]=p->fam[j+1];

j++;

}

j=0; 

fgets(p->oth,i,fn);

while(j<=30)

{

if (p->oth[j]=='\n') p->oth[j]=p->oth[j+1];

j++;

}

j=0; 

fgets(p->name,i,fn);

while(j<=30)

{

if (p->name[j]=='\n') p->name[j]=p->name[j+1];

База данных, построенная на основе классов