Елементите на един масив могат да бъдат данни от произволен тип, в частност те могат да бъдат структури;
например:
struct rec
{ int k;
int l;
};
struct rec a[5]; //a – масив с пет елемента от структурен тип rec;
еквивалентна форма на горната дефиниция:
struct rec
{ int k;
int l;
} a[5];
обръщението към полетата на структура, която е елемент на масив е следното: a[1].k – полето k в структурната променлива (елемент от масив) a[1]; аналог. a[1].l е полето l на a[1];
така означените полета се разглеждат като обикновени променливи, те могат да участват в изрази, да се предават като параметри във функции и т.н.; достъпът до елементите на масива може да се осъществява и чрез използването на името на масива, което е указател-константа към първия елемент на масива;
например:
(*(a+1)).k a[1].k (a+1) -> k (използваме операция ‘->’);
можем да използваме указател променлива, като го инициализираме с адреса на първия елемент от масива;
например:
struct rec *ptr;
ptr = a;
(ptr+1) сочи към a[1], (ptr+1)->k е полето k на структурната променлива a[1];
изменянето на указателя с операцията ++ (--) съответно го увеличава (намаля) така, че да сочи следващия (предишния) елемент от масива със структурните променливи;
масив от структури може да бъде предаван като параметър на функция; например:
void fun (int x, struct rec a[])
{ …
}
можем да имаме следното обръщение:
fun (5, a);
в ANSI C и C++ елемент на масив от структура може да се предава директно като параметър на функция; например:
void trick (struct rec x)
{ …
}
можем да имаме следното обръщение:
trick (a[2]);
в K&R C, ANSI C и C++ ние можем да предадем указател към елемент на масив като параметър на функция; например:
void trick (struct rec *p)
{ …
}
можем да има следното обръщение:
trick (a + 2);
само в C++ елементите на масив от структури могат да се предават по име чрез псевдоним; например:
void trick (struct rec &x)
{ …
}
можем да имаме следното обръщение:
trick (a[2]);
можем да имаме масив от структури и самата структура да съдържа поле масив; например:
struct type
{ int b[3];
int k;
} a[5];
до елементите на масив поле достигаме по обичайния начин:
int x; x = a[3].b[1];
масив от структури се инициализира по общоприетия начин с тази особеност, че началните стойности за всеки елемент на масива може да се заграждат във фигурни скоби; например:
struct type c[2] = { { 1, 2}, { 3, 5} };
пример:
#define LIMIT 5
struct array
{ float z;
int k;
};
struct array a[LIMIT];
да се сортират елементите на масива a по полето k във възходящ ред;
реализираме метода на бързото сортиране – идеята се състои в намиране на онова място на даден (случайно избран) елемент x от масива, което той би заел, ако масивът е сортиран; в процеса на търсене на мястото на елемента x, останалите елементи от масива се разменят по такъв начин, че след завършване на функцията, елементите които са наляво от x са не по-големи от x, а тези надясно от x са не по-малки от него; така първоначалната задача за сортиране на един масив се свежда до задача за сортиране на два масива (наляво от x и надясно от x); за всеки от тях прилагаме същата функция, т.е. функцията quick е рекурсивна;
void quick (struct array *p, int left, int right)
{ int i = left, j = right, x = p[ (i + j)/2 ];
struct array r;
do {
while ((p+i)->k < x) i++;
while ((p+j)->k > x) j--;
if (i<=j)
{ r = *(p+i);
*(p+i) = *(p+j);
*(p+j) = r;
i++; j--;
}
}
while (i <=j);
if (left < j) quick (p, left, j);
if (i < right) quick (p, i, right);
}
5. Дефиниране на имена на типове.
Една удобна езикова конструкция в C е дефинирането на нови имена на типове на променливи;
синтаксис:
typedef стар_тип нов_тип;
тук стар_тип е име на допустим за езика тип на променлива; освен това може стар_тип да е име на тип, който е вече дефиниран в програмата с typedef; нов_тип е ново име, заместващо името, описано в стар_тип; нов_тип е произволен, допустим за езика идентификатор, различен от имената на променливите в съответната област на действие;
примери:
typedef int PRIM;
PRIM i, j; //дефиниране на променливи i, j от тип PRIM тип int;
typedef float real;
real x, y;
за 4 – байтов тип Integer;
typedef int Integer; //32-битов компилатор
typedef long int Integer; //16-битов компилатор
Важно: С typedef не се дефинира нов тип, а се дава ново име на вече съществуващ тип;
чрез използването на typedef, програмата става лесно преносима за различни платформи;
описанието typedef може да се използва със сложни типове данни като масиви, структури, указатели към масиви и структури, обединения;
примери:
typedef float Exp[100];
Exp a, b; float a[100], b[100];
typedef char *word;
word p, q; char *p, *q;
можем да дефинираме ново име на прототип на функция;
например:
typedef char *fun(int);
fun arc; //дефиниране на функция arc, която връща указател към
char и има един параметър от тип int;
също така, можем да задаваме ново име на тип структура;
struct address
{ char town[20];
char street[20];
int num;
}
typedef struct
{ char name[30];
struct address adr;
char egn[11];
} officer;
officer a; //дефиниране на структурна променлива от тип officer
по този начин избягваме ключовата дума struct;
предимства при използването на typedef:
-
увеличава се пригледността на програмата
-
при дефиниране на променливите се постига по-компактно записване
-
постига се по-добра преносимост на програмата
Сподели с приятели: |