Визначення покажчика функції
Щоб визначити покажчик на функцію, яка не має аргументів і не повертає значення, ви говорите:
void (*funcPtr)();
Коли ви дивитесь на таке складне визначення, як кращий, найкращий спосіб напасти на нього - почати з середини та виходити назовні. "Починати з середини" означає починати з назви змінної, яка є funcPtr. "Виправити вихід" означає шукати праворуч найближчий предмет (нічого в цьому випадку; права дужка не зупиняє вас), потім дивитися вліво (вказівник, позначений зірочкою), потім дивитися вправо ( порожній список аргументів, що вказує на функцію, яка не приймає аргументів), потім дивиться вліво (недійсна, що означає, що функція не має значення повернення). Цей рух вліво-вправо-вправо працює з більшістю декларацій.
Щоб ознайомитись, "починайте з середини" ("funcPtr - це ..."), перейдіть праворуч (нічого там - вас зупиняє права дужка), перейдіть ліворуч і знайдіть "*" (" ... вказівник на ... "), перейдіть праворуч і знайдіть порожній список аргументів (" ... функція, яка не бере аргументів ... "), перейдіть ліворуч і знайдіть порожнечу (" funcPtr is вказівник на функцію, яка не бере аргументів і повертає недійсність ”).
Вам може бути цікаво, чому * funcPtr вимагає дужок. Якщо ви їх не використовували, компілятор побачив би:
void *funcPtr();
Ви б оголосили функцію (яка повертає порожнечу *), а не визначати змінну. Ви можете подумати про компілятор як про той самий процес, який ви робите, коли він з'ясує, що має бути декларація чи визначення. Їм потрібні ті круглі дужки, щоб "наштовхнутися проти", тому він повертається ліворуч і знаходить "*", замість того, щоб продовжувати праворуч і знаходити порожній список аргументів.
Складні декларації та визначення
Крім того, коли ви зрозумієте, як працює синтаксис декларацій C і C ++, ви зможете створити набагато складніші елементи. Наприклад:
//: C03:ComplicatedDefinitions.cpp
/* 1. */ void * (*(*fp1)(int))[10];
/* 2. */ float (*(*fp2)(int,int,float))(int);
/* 3. */ typedef double (*(*(*fp3)())[10])();
fp3 a;
/* 4. */ int (*(*f4())[10])();
int main() {} ///:~
Пройдіться по кожному з них та скористайтеся орієнтацією праворуч-ліворуч, щоб визначити це. Число 1 говорить, що "fp1 - вказівник на функцію, яка приймає цілий аргумент і повертає вказівник на масив з 10 недійсних покажчиків".
Число 2 говорить, що "fp2 - вказівник на функцію, яка бере три аргументи (int, int і float) і повертає вказівник на функцію, яка приймає цілий аргумент і повертає поплавок".
Якщо ви створюєте безліч складних визначень, можливо, ви хочете використовувати typedef. Число 3 показує, як typedef економить, вводячи складний опис кожного разу. У ньому сказано: "fp3 - це вказівник на функцію, яка не бере аргументів, і повертає вказівник на масив з 10 покажчиків на функції, які не беруть аргументів і повертають парні". Потім він говорить: "a - це один із цих типів fp3". typedef загалом корисний для складання складних описів із простих.
Число 4 - це оголошення функції замість визначення змінної. У ньому сказано, що "f4 - це функція, яка повертає вказівник на масив з 10 покажчиків на функції, які повертають цілі числа".
Ви рідко, якщо коли-небудь знадобиться, такі складні декларації та визначення, як ці. Однак, якщо ви перейдете до вправ їх з'ясувати, ви навіть не будете злегка турбуватися злегка складними, з якими ви можете зіткнутися в реальному житті.