Для чого потрібна '*' перед ім'ям функції?
const double * f1(const double ar[], int n);
const double * f2(const double * ar, int n);
const double * f3(const double [], int);
const double * f4(const double *, int);
Вивчаю покажчики на функції. Всі ці функції приймають масив і його довжину. arr
представляє адресу масиву. До параметрів питань немає. Підкажіть будь ласка:
- для чого потрібна
*
передf1, f2, f3, f4
. -
*
може зустрічатися тільки в прототипах або у визначенні функції теж? -
* (показчик)
вказує на тип який повертається функцією?
Де можна почитати конкретно про такі випадки? Буду дуже вдячний за відповідь.
Відповіді на питання (4)
Питання тут, скоріше, в тому, як читати проголошення функцій (та змінних) в C. Історично склалося, що це дещо заплутано. Базове правило: читаємо від ідентифікатора, який визначається, спершу в дужках, потім праворуч, потім ліворуч; але групи ключових слів читаються разом зліва направо. Отже,
const double * f1(const double ar[], int n);
f1 - це функція, що приймає (список параметрів const double ar[], int n
) - далі праворуч нема куди, читаєм ліворуч - яка повертає *
- вказівник на const double
.
const double * (* func_ptr)(const double *, int);
func_ptr
- це:
*
- вказівник на
(const double *, int)
- функцію, що приймає параметри такого типу
*
- і повертає вказівник на
const double
int *ptr_array[10];
ptr_array - це масив вказівників на int.
int (*ptr_to_array)[10];
ptr_to_array - це вказівник на масив з 10 int-ів.
int (*func_array[10])(int x);
func_array - це
[10]
- масив з 10
*
- вказівників на
(int x)
- функції, що приймають int
int
- і повертають int.
int(*(*func_array1[10])(int x))(int);
func_array1 - це
[10]
- масив з 10
*
- вказівників на
(int x)
- функції, що приймають int
*
- і повертають вказівник
(int)
- на функцію, що приймає int
int
- і повертає int.
Через ці всі складнощі наполегливо раджу все, складніше за дві базові конструкції, проголошувати окремими типами за допомогою typedef
або (в C++) using
:
typedef int (*IntFunc)(int x);
IntFunc - це вказівник на функцію, що приймає int та повертає int
IntFunc func_array[10];
typedef IntFunc IntFuncGetter(int);
IntFuncGetter func_array1[10];
func_array та func_array1 визначені так само, як і раніше, але значно читаніше.
Якщо ви зуміли дочитати до цього місця, то, гадаю, вам уже не буде проблемою прочитати визначення функцій у питанні.
- символ * означає посилання.
- нічого особливого в читанні.
- просто є дентифікатор, будь чого може бути, різниця тільки в написанні чого небуть поруч, від цього залежить призначення ідентифікатора, то функція чи просто тип-посилання.
- тут видно що розібрались що то є функція.
- а зліва від ідентифікатора може бути лише допустиме.
- у випадку функції нас цікавить повертаємий тип.
- тут константне посилання на double.
- тобто прийнявши десь повернутий результат роботи функції
константне посилання на doubleв ідентифікатор який обовязково має співпадати. - значення послання за цим ідентифікатором не можна змінити на інше посилання
Функція описується так:
тип_що_повертається им'я_функції([тип1 аргумент1 [, тип2 аргумент2] ...)
Так що
const double * f2(const double * ar, int n);
const double *
- тип який повертається, f2
- ім'я функції, const double *
- тип першого аргументу ar
, int
- тип другого аргументу n
.
Так зрозуміліше?
На друге питання - "прототип" і визначення повинні збігатися (крім, хіба що, імен аргументів), так що *
потрібна точно так же, щоб вказувати тип який повертається.
Покажчик на функцію даного типу буде мати вигляд
const double * (* func_ptr)(const double *, int);
Рекомендую серію відео-курсів C++ українською, зокрема по вказівникам: