Як визначається пріоритет у покажчиках С?


14

Я зіткнувся з двома заявами вказівника, що у мене виникають проблеми з розумінням. Моє розуміння правил пріоритетності виглядає приблизно так:

Operator             Precedence             Associativity
(), [ ]                  1                  Left to Right
*, identifier            2                  Right to Left
Data type                3

Але навіть враховуючи це, я не можу зрозуміти, як правильно оцінити такі приклади:

Перший приклад

float * (* (*ptr)(int))(double **,char c)

Моя оцінка:

  1. *(ptr)
  2. (int)
  3. *(*ptr)(int)
  4. *(*(*ptr)(int))

Потім,

  1. double **
  2. char c

Другий приклад

unsigned **( * (*ptr) [5] ) (char const *,int *)
  1. *(ptr)
  2. [5]
  3. *(*ptr)[5]
  4. *(*(*ptr)[5])
  5. **(*(*ptr)[5])

Як я повинен їх читати?


1
Питання про те, як мова обробляє її функції, є актуальною тут.

Відповіді:


7

Моя здогадка для першого : ptr - вказівник на функцію, яка приймає за параметр int, і повертає вказівник на функцію, яка приймає в якості параметрів вказівник на вказівник на подвійне і char, а повертає вказівник на плавання.

Інтерпретація :

(* ptr) (int)

говорить, що ptr - вказівник на функцію, що приймає int як аргумент. Щоб дізнатися, що повертає ця функція, нам потрібно розширити наш погляд:

(* (* ptr) (int))

це означає, що функція повертає покажчик на іншу функцію. Параметри цієї іншої функції:

(подвійний **, знак c)

і воно повертається

плавати *

А для другого : ptr - вказівник на масив з п’яти покажчиків на функції, які приймають за параметри постійний вказівник на char та вказівник на int, повертаючи вказівник на покажчик неподписаного int.

Інтерпретація :

(* (* ptr) [5])

оголошує ptr як вказівник на масив з п'яти покажчиків на прийняття функції

(char const *, int *)

як аргументи і повернення

без підпису **


7

Ви можете спробувати метод «Спіраль за годинниковою стрілкою», щоб зрозуміти ці божевільні декларації:

http://c-faq.com/decl/spiral.anderson.html

Я про це також блогував:

http://www.kalekold.net/index.php?post=4


Дякую за відповідь Але в методі годинникової спіралі, з чого починати в моєму випадку? У прикладах, наведених за посиланням, є прості приклади. Я не в змозі зіставити своє рівняння з цим методом.
trapaank

1
слід почати зі свого ідентифікатора: ptr. у вас буде: "ptr - вказівник на функцію, яка приймає int і повертає вказівник на функцію, яка приймає покажчик на покажчик на подвійний і char, а повертає вказівник на поплавок". спробуйте спіраль, і ви отримаєте те саме.
Ремо.Д

1

Це покажчик функції. Людина, яка написала це, могла б краще використовувати typedefs, щоб зробити це зрозумілішим.

Фактично вказівник функціонує з цими параметрами. float * myfunc (подвійний **, char)


4
Моя обставина, що людина, яка це написала, - це вчитель.
mouviciel

Будемо сподіватися, що це не вчитель, тому що вам не потрібно знати таке лайно, як це. Хоча я гадаю, що хороший вчитель спочатку вдарить вас по обличчю такими виразами, дозволяючи вам почухати голову, намагаючись їх інтерпретувати, а потім покаже, як правильно використовувати typedef.

1
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.