МАРК РЕГНЕРУС ДОСЛІДЖЕННЯ: Наскільки відрізняються діти, які виросли в одностатевих союзах
РЕЗОЛЮЦІЯ: Громадського обговорення навчальної програми статевого виховання ЧОМУ ФОНД ОЛЕНИ ПІНЧУК І МОЗ УКРАЇНИ ПРОПАГУЮТЬ "СЕКСУАЛЬНІ УРОКИ" ЕКЗИСТЕНЦІЙНО-ПСИХОЛОГІЧНІ ОСНОВИ ПОРУШЕННЯ СТАТЕВОЇ ІДЕНТИЧНОСТІ ПІДЛІТКІВ Батьківський, громадянський рух в Україні закликає МОН зупинити тотальну сексуалізацію дітей і підлітків Відкрите звернення Міністру освіти й науки України - Гриневич Лілії Михайлівні Представництво українського жіноцтва в ООН: низький рівень культури спілкування в соціальних мережах Гендерна антидискримінаційна експертиза може зробити нас моральними рабами ЛІВИЙ МАРКСИЗМ У НОВИХ ПІДРУЧНИКАХ ДЛЯ ШКОЛЯРІВ ВІДКРИТА ЗАЯВА на підтримку позиції Ганни Турчинової та права кожної людини на свободу думки, світогляду та вираження поглядів
Контакти
Тлумачний словник Авто Автоматизація Архітектура Астрономія Аудит Біологія Будівництво Бухгалтерія Винахідництво Виробництво Військова справа Генетика Географія Геологія Господарство Держава Дім Екологія Економетрика Економіка Електроніка Журналістика та ЗМІ Зв'язок Іноземні мови Інформатика Історія Комп'ютери Креслення Кулінарія Культура Лексикологія Література Логіка Маркетинг Математика Машинобудування Медицина Менеджмент Метали і Зварювання Механіка Мистецтво Музика Населення Освіта Охорона безпеки життя Охорона Праці Педагогіка Політика Право Програмування Промисловість Психологія Радіо Регилия Соціологія Спорт Стандартизація Технології Торгівля Туризм Фізика Фізіологія Філософія Фінанси Хімія Юриспунденкция |
|
|||||||
Складні оголошення мови
В мові С/С++ дозволяється створювати складні визначення. При їх інтерпретації слід керуватися наступними правилами:
· починати інтерпретацію слід із ідентифікатора, який є початком визначення;
· чим ближче модифікатор розміщується до ідентифікатора, тим вище його пріоритет;
· квадратні і круглі дужки мають однаковий пріоритет і розглядаються зліва направо;
· модифікатори - квадратні і круглі дужки справа від ідентифікатора мають пріоритет вище, ніж зірочка зліва від ідентифікатора;
· круглі дужки використовуються для об’єднання частин визначення, які мають більш високий пріоритет. Тому, якщо справа зустрілася кругла закриваюча дужка, то необхідно дані вимоги застосувати всередині дужок;
· ключові слова near, far, huge модифікують елемент чи вказівник справа;
· якщо за ключовими словами near, far чи huge безпосередньо слідує ідентифікатор, то слово визначає, де буде знаходитися даний елемент: в стандартному сегменті даних (near) чи в інших сегментах (far або huge). Ключове слово huge не може бути використане для визначення функції.
Розглянемо деякі визначення і оголошення:
double *z[5];
/* z - масив із п’яти вказівників на змінні типу double */
double (*z)[5]; /* z - вказівник на масив из п’яти елементів типу double */
int (*fun(double *)[]; /* fun - функція, яка має параметром вказівник на double і повертає вказівник на масив чисел типу int */;
int (*(*fun(double*))[3])(int []); 6 4 1 3 2 5 8 7 /* fun - функція, яка має параметром вказівник на double і повертає як значення , вказівник на масив із трьох елементов, кожний ізяких є вказівником на функцію, яка отримує за вхідні параметри масив чисел типу int і повертає ціле число */'' (*fun(int * *)) [5]; 5 1 4 2 3 6 /* fun - функція, яка має вхідним параметром вказівник на вказівник на тип int і повертає вказівник на масив із п’яти чисел типу int */.
extern int(*fun(char *))(int *); 7 4 1 3 2 6 5 /* fun - функція, яка має вхідним параметром вказівник на char і повертає вказівник на функцію, яка має параметром вказівник на int і повертає значення int extern */
char **argv; char let=*++*argv;
/* із масиву вказівників на char вибирається вказівник (*argv), значення цього вказівника збільшується на одиницю (++*argv), потім вибирається символ, який відповідає цьому вказівнику, и присваивоюється змінній let .*/ char *( *( *( *fun) (int*))[5])(double *); 10 7 5 2 1 4 3 6 9 8 /* fun - вказівник на функцію, яка має параметром вказівник на тип int і повертає вказівник на массив із пяти елементів, кожнй із яких є вказівником на функцію, яка має параметром вказівник на double і повертає вказівник на тип char */
double *fun ()[5][10]; 6 3 1 2 4 5 /* fun - функція, яка повертає вказівник на масив із пяти елементів, кожний елемент якого десятиелементний масив типу double */
int(*(*(*mas)[5][3])(double,double))(int *); 8 6 4 2 1 3 5 7 /*mas - вказівник на двовимірний масив із пятнадцяти елементів, кожний із яких є вказівником на функцію, яка має два вхідні параметри типу double і повертає значення вказівник на функцію, параметром для якої є вказівник на тип int і яка повертає значення типу int */ double far funct(double *); 4 2 1 3 /* funct - функція, для виклику якої використовується 4-байтова адреса (2 байти -сегмент, 2 байти - зміщення, яка має параметром вказівник на тип double і повертає значенне типу double */
int far*near*ptr;
/* ptr - ближній (2 байти - зміщення) вказівник на масив дальніх (far) вказівників на тип int */
int far* *ptr;
/* ptr - вказівник на дальній вказівник на тип int */ int far funct(void); int (far *pf) (void); pf=funct; /* funct - функція, яка викликається по4-байтовій адресі, pf дальній вказівник на функцію, йому присвоюється адреса входу у функцію funct */
Розглянемо приклад.
#include <iostream.h> char с[]="+-"; /* Обчислює суму дробових чисел, поки не нуль і записує результат в кінець */ char *fl(double *a) { double s=0; while(*a) s+=*a++; *a++=s; *a=0; return ((*(a-1)>0)?c:c+1; }
/* Обчислює добуток дробових чисел, поки не 0 і записує результат в кінець */
char *f2(double *а) { double p=1; while (*a) p*=*a++; *a++=p; *a=0; return ((*(a-1)>0) ? c: c+1; }
/* Обчислює суму двох останніх дробових чисел і записує результат в кінець */
char *f3(double *a) { double t=0; while (*a) a++;) t=*(a-1)+*(a-2); *a++=t; *a=0; return ((*(a-1)>0) ? c: c+1; }
/* Зауваження: всі три функції повертають вказівник на символ ''+'' або ''-'' */ // Тип tpf - вказівник на функцію виду fl, f2 , f3.
typedef char *(*tpf)(double *);
// Два масиви вказівників типу tpf
tpf pf1[3]={f1, f2, f3} tpf pf2[3]={f2, f1, f3}
/* Обчислює суму цілих . чисел, поки не 0, і повертає вказівник на масив вказівників на функції f1, f2, f3 в порядку, який залежить від суми ( > чи < 0 ) */ / Еквівалентна наступному запису // сhar *( *( *(fun)(int *) )[З]) (double *)
// (tpf введено для спрощення розуміння запису)
tpf ( *(fun) (int *а) ) [3] { int s=0; while(*a) s+=*a++; if(s>=0) return &pfl; return &pf2; } void print(char *s, double *a) /* Виводить масив нa екран */ { cout << s; while (*a) cout << *a++;
void main ( ) /* Головна функція */ { char s[2]; /* Масив, у який послідовно записуваються /* результати виконання функцій із масиву р */ char *(*(*(*pf)(int *))[3])(double *)=fun; /* вказ. на fun */ int i[]={l, -2, 3, -5, -6, 0}; /* Масив цілих чисел (йогo сума визначає пoрядок виконання функцій fl, f2, f3) */. double d[30]={0.002, -0.1, 2.3, -10.23, 1,0};
//* Масив дробових чисел (над ним виконують дії функції f1, f2, f3) */
tpf (*p)[3]; /* вказівник на масив вказівників tpf */ p=(*pf)(i); /* виконуємо fun */ print ("Результуючий масив:", d); /* Виводимо поч. масив дроб. чисел */ s[0]=*(*p)[0](d); /* Виконуємо першу, */ s[1]=*(*р)[1](d); /* другу, */ s[2]=*(*р)[2](d); / і третю функції із масиву р, */ print ("Початковий масив:" , d); /* Виводимо результуюч. масив дроб. чисел */ cout << s; /* Виводимо знаки чисел, що дописуються */ } Читайте також:
|
||||||||
|