300 likes | 577 Views
Структури от данни. Структурата е група от данни ( елементи ) от различен тип с общо име ( идентификатор ). Дефиниране на модел (шаблон) на структура struct идентификатор { тип_на_елемент1 идентификатор_на_елемент1 ; тип_на_елемент2 идентификатор_на_елемент ; . . . }; Памет
E N D
Структури от данни • Структурата е група от данни (елементи) от различен тип с общо име (идентификатор). • Дефиниране на модел (шаблон) на структура struct идентификатор { тип_на_елемент1идентификатор_на_елемент1; тип_на_елемент2идентификатор_на_елемент; . . . }; • Памет • Елементите на структурата заемат последователни клетки в паметта на компютъра, достатъчни да се разположат всички елементи.
Пример: Тип СТУДЕНТ с информацияза факултетен номер, име, факултет, специалност и успех се дефинира: struct student {int facN; char name [30]; /* име */ char fac [30]; /* факултет */ char spec [20]; /* специалност */ float uspeh; /* успех */ }; • Дефиниране на данни от тип структура student • student a,b,*p; //p = &s; (р е указател към структура) • За една променлива от тип student необходимата памет е:
Достъп до елемент на структурата • Операция точка (.) променлива_структура.идентификатор_на_елемент • Указателна операция (->) указател_към_структура->идентификатор_на_елемент • Операции за достъп а.uspeh=5.65; е еквивалентно на(&s)->uspeh=5.65; p->uspeh=5.65;(*p).uspeh=5.65; strcpy(а.name, "Иван Петров"); strcpy(p->name, "Иван Петров"); • Инициализиране на структури struct student а ={1234567, "Иван Петров", “ФЕТТ", “ЕТ", 5.50};
Вложени структури • Вложената структура съдържа елементи, които представляват структури. • Достъпът до елементите на вложена структура се осъществява чрез последователно използване на операциите (.) или (->). Пример: Тип АДРЕС се влага в тип СТУДЕНТ. • struct address • { char state [20]; /* държава */ • char city [20]; /* град */ • char streetAndNumber [20]; /* улица, номер */ • int zip; /* пощенски код */ • }; • struct student • { int facN; • char name [30]; • char fac [30]; • char spec [20]; • float uspeh; • struct address addr; • };
Дефиниране на елемент на второ ниво (zip) struct student s; s.addr.zip=1000; Приложение • Структурите се използват за създаване на абстракции от данни. • Пример: Тип КОМПЛЕКСНО ЧИСЛО /* Дефиниране на комплексно число. Умножение на комплексни числа */ #include <stdio.h> struct complex /*Структура за комплексно число*/ { double re; /* Реална част */ double im; /* Имагинерна част */ };
struct complex product(struct complex x, struct complex y); int main () { struct complex z1, z2, z3; printf(”Въведи z1: ”); scanf("%lf %lf", &z1.re, &z1.im); printf(”Въведи z2: ”); scanf("%lf %lf", &z2.re, &z2.im); z3=product(z1, z2); printf("(%.2lf,%.2lf)*(%.2lf,%.2lf)=(%.2lf,%.2lf)\n", z1.re, z1.im, z2.re, z2.im, z3.re, z3.im); return 0; } //функция за умнжение на 2 комплексни числа struct complex product(struct complex x, struct complex y) { struct complex z; z.re = x.re*y.re-x.im*y.im; z.im = x.im*y.re+x.re*y.im; return(z); }
Масив от структури • Дефиниране structидентификатор_на_структураидентификатор_на_масив[израз]; structstudentgroup [30]; • group е масив от 30 елемента, като всеки елемент е от тип structstudent. • Операции • Достъп до елемент на структурата в масива • Чрез операция адресиране и операция точка (.) идентификатор_на_масив[индекс].идентификатор_на_елемент • Чрез операция намиране на стойност по адрес и указателна операция (->) *(указател+индекс)->идентификатор_на_елемент
group[4].uspeh=5.65; еквивалентно на *(group+4)->uspeh=5.65; • Инициализиране struct student group [2]= {{1234567,"Иван Иванов",“ФЕТТ",“ЕТ",5.00}, {5432785,”Ина Пеева”,”ФЕТТ”,”ЕТ”,4.83} }; или struct student group [2]= {1234567,"Иван Иванов",“ФЕТТ",“ЕТ",5.00, 5432785,”Ина Пеева”,”ФЕТТ”,”ЕТ”,4.83 }; • Приложение – за създаване на бази данни
Задаване имена на типове typedef • Може да дефинира ново име на съществуващ тип. • Този процес помага машинно-зависимите програми да бъдат по-преносими. typedefстар_тип нов_тип;//стар_тип е допустим тип //нов_тип е ново име за тип typedef struct student stud; • Пример: Данните за студенти включват: име и успех. Да се напишат функции за: 1) въвеждане на студенти в масив от структури; 2) отпечатване на данните за студентите; 3) изчисляване на среден успех.
#include<stdio.h> 1/4 #include<conio.h> #include <string.h> #include <stdlib.h> #define MAX 20 typedef struct { char name[80]; float mark; }stud; stud in(); int enter(stud *p[], stud s[]); void print(stud *s[],int n); void sort(stud *s[],int n); Програма за обработка на масив структури – вариант 1 Попълване на масива, извеждане на масива, подреждане по големина на оценки
void main() 2/4 { stud *p[MAX], s[MAX]; int n; n=enter(p,s); print(p,n); sort(p,n); printf("Sled sortirane po uspeh\n"); print(p,n); } stud in() { stud t; printf("name:"); gets(t.name); printf("mark:"); scanf("%f",&t.mark); fflush(stdin); return t; } Програма за обработка на масив структури – вариант 1 Попълване на масива, извеждане на масива, подреждане по големина на оценки
int enter(stud *p[],stud s[]) 3/4 { int n,i; printf("broi str:"); scanf("%d",&n); fflush(stdin); for(i=0;i<n;i++) { s[i]=in(); p[i]=&s[i]; } return n; } void print(stud *s[],int n) { int i; for(i=0;i<n;i++) printf("%s %6.2f\n",s[i]->name,s[i]->mark); } Програма за обработка на масив структури – вариант 1 Попълване на масива, извеждане на масива, подреждане по големина на оценки
void sort(stud *s[],int n) 4/4 { stud *temp; int i,j,f=1; while(f!=0) { f=0; for(i=0; i<n-1; i++) if(s[i]->mark < s[i+1]->mark) { temp=s[i]; s[i]=s[i+1]; s[i+1]=temp; f=1; } } } Програма за обработка на масив структури – вариант 1 Попълване на масива, извеждане на масива, подреждане по големина на оценки
#include<conio.h> 1/4 #include <string.h> #include <stdlib.h> #include <ctype.h> #define MAX 20 #define STOP " " typedef struct { char name[80]; float mark; }stud; int in(stud *s[]); //въвеждане на студенти void out(stud *s[],int n); //извеждане на студенти float aver(stud *s[],int n);//определяне среден успех Програма за обработка на масив структури – вариант 2 Попълване на масива, извеждане на масива, определяне на среден успех
Програма за обработка на масив структури – вариант 2 Попълване на масива, извеждане на масива, определяне на среден успех void main() 2/4 { stud *t[MAX]; int n; n=in(t); out(t,n); printf("Sreden uspeh=%.2f\n",aver(t,n)); free (t); }
Програма за обработка на масив структури – вариант 2 Попълване на масива, извеждане на масива, определяне на среден успех //Функция за попълване на масива от структури3/4 int in(stud *s[]) { int i=0; char t[10]; while(printf(“Въведи структура %d\n",i), s[i]=(stud *)malloc(sizeof(stud)), printf(“Въведи име или празна позиция \n"), strcmp(gets(s[i]->name),STOP)&&i<MAX) { printf(“Въведи оценка:"); s[i]->mark=atof(gets(t)); i++; } return i; }
Програма за обработка на масив структури – вариант 2 Попълване на масива, извеждане на масива, определяне на среден успех //Функция за извеждане на масива от структури 4/4 void out(stud *s[],int l) { int i; for(i=0;i<l;i++) printf("%s %6.2f\n",s[i]->name,s[i]->mark); } //Функция за определяне на средно аритметично от оценки float aver(stud *s[],int n) { int i; float sum; for(i=0,sum=0;i<n;i++) sum+=s[i]->mark; return sum/n; }
Полета от битове • Полетата от битове са елементи на структури, които представляват набор от последователни битове. • Дефиниране • struct идентификатор • { • тип_на_поле идентификатор_на_поле:размер_на_поле; • . . . • };
Където: • идентификатор- име на структурата • тип_на_поле - int, unsigned, signed (някои компилатори допускат само unsigned) • идентификатор_на_поле - име на поле отбитове • размер_на_поле - брой бита в полето • Заделената памет е както при struct • Операции - всички операции както при structс • изключение на: • Не се допускат указатели към полета от битове т.е. адресна операция; • Не се допуска масив от полета от битове; • Кодът с полета от битове зависи от конкретния компютър - при някои полетата се изпълняват отдясно наляво, а при други - отляво надясно.
Приложение • Ако е ограничена паметта, логически променливи (истина/лъжа) могат да се съхранят само в 1 бит. • Някои устройства предават информация, кодирана в битове. • Някои декодиращи процедури изискват достъп до отделните битове вътре в байта. • Пример: Тип СВЕТОФАР – състояние (2 бита): 00 – червено, 01 – жълто, 10 – зелено: #include <stdio.h> struct trafficLight /* Тип свтофар */ { unsigned state:2; /* Състояние */ };
int main() {struct traficLight t; do { printf("Въведи t.state="); scanf("%d“, &t.state); }while(t.state < 0 || t.state > 2); switch(t.state) {case 0:printf ("Червена светлина\n"); break; case 1: printf ("Жълта светлина\n"); break; case 2: printf ("Зелена светлина\n"); break; } return 0; }
Обединение inion • Обединение е група от данни (елементи) от различен тип с общо име (идентификатор), които се припокриват в паметта. • Дефиниране unionидентификатор { тип_на_елементидентификатор_на_елемент; . . . }; • Памет • Отделената памет е достатъчна за най-дългия елемент на обединението.
Пример: union u_type { int i; char c; }; union u_type u, *p; • Операции • Всички операции както при struct;
Приложение – за специализирано преобразуване на типове. #include <stdio.h> union uType { int i; char c; }; int main () { union uType u, *p; printf ("Размер = %d\n", sizeof(uType)); p=&u; u.i=10; p->c='*'; printf ("u.i=%d u.c=%c\n",u.i, u.c); return 0; }
Данни от изброим тип (с изброими стойности)enum • Данни с изброими стойности е подредено крайно множество от константни стойности, които могат да приемат променливите от този тип. • Дефиниране enumидентификатор{списък_от_константни_стойности}; • Идентификаторът еиме на типа • списък_от_константни_стойности представлява идентификатор1, идентификатор2 …
Константните стойности на типа са подредени. • Те имат позиции, съответно 0, 1, 2, …, . • Те са целочислени константи и могат да участват в изрази и оператори. • Константните стойности на типа могат да се инициализират. • Променливите от тип enumне могат директно да се въвеждат и извеждат. • Пример: Тип “ден” enum day{Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}; enum day today, yesterday, tomorrow; today = Monday; /* today=1; */ yesterday = today-1;/* yesterday=0;т.е. yesteterday=Sunday;*/ tomorrow = today+1;/* tomorrow=2;т.е. tomorrow=Tuesday; */
Пример: Използва се променлива тип enum там, където е необходима цяла променлива. #include <stdio.h> enum color_code {black, brown, red, orange, yellow}; void main () { enum color_code color; char value; printf(“въведи цяло число:"); value = getchar(); switch (value) { case '0': color=black; break; case '1': color=brown; break; case '2': color=red; break; case '3': color=orange; break; case '4': color=yellow; break; default:printf(“грешно въведена” “ стойност\n"); }
switch(color) { case black: printf("black"); break; case brown: printf("brown"); break; case red: printf("red"); break; case orange: printf("orange"); break; case yellow: printf("yellow"); break; } for(color=black;color <= yellow;color++) printf("\nдесетичната стойност е: %d\n",color); }