Como a precedência é determinada nos ponteiros C?

14

Eu me deparei com duas declarações de ponteiro que estou tendo problemas para entender. Meu entendimento das regras de precedência é mais ou menos assim:

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

Mas, mesmo considerando isso, não consigo descobrir como avaliar os seguintes exemplos corretamente:

Primeiro exemplo

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

Minha avaliação:

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

Então,

  1. double **
  2. char c

Segundo exemplo

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

Como devo lê-los?

trapaank
fonte
1
Perguntar sobre como um idioma lida com seus recursos está no tópico aqui.

Respostas:

7

Meu palpite para o primeiro : ptr é um ponteiro para uma função que assume como parâmetro um int e retorna um ponteiro para uma função que leva como parâmetros um ponteiro para ponteiro para dobrar e um caractere, e retorna um ponteiro para flutuar.

Interpretação :

(* ptr) (int)

diz que ptr é um ponteiro para uma função que usa int como argumento. Para descobrir o que essa função retorna, precisamos expandir nossa visão:

(* (* ptr) (int))

isso significa que a função retorna um ponteiro para outra função. Os parâmetros dessa outra função são:

(duplo **, caractere c)

e retorna

float *

E para o segundo : ptr é um ponteiro para uma matriz de cinco ponteiros para funções que tomam como parâmetros um ponteiro constante para char e um ponteiro para int, retornando um ponteiro para um ponteiro de int não assinado.

Interpretação :

(* (* ptr) [5])

declara ptr como um ponteiro para uma matriz de cinco ponteiros para uma função

(char const *, int *)

como argumentos e retornando

não assinado **

Daniel Scocco
fonte
7

Você pode tentar o método 'The Clockwise Spiral' para entender essas declarações insanas:

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

Também escrevi sobre isso aqui:

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

Gary Willoughby
fonte
Obrigado pela resposta. Mas no método The Clockwise Spiral, de onde começar no meu caso? Nos exemplos dados no link, existem exemplos simples. Não sou capaz de combinar minha equação com esse método.
precisa saber é o seguinte
1
você deve começar pelo seu identificador: ptr. você terá: "ptr é um ponteiro para uma função que recebe um int e retorna um ponteiro para uma função que leva um ponteiro para um ponteiro para um double e um char e retorna um ponteiro para um float". tente o spyral e você obterá o mesmo.
Remo.D
1

É um ponteiro de função. A pessoa que o escreveu poderia ter feito melhor uso dos typedefs para torná-lo mais claro.

Na verdade, é um ponteiro para funcionar com esses parâmetros. float * myfunc (duplo **, caractere)

Michael Shaw
fonte
4
Minha aposta é que a pessoa que escreveu é o professor.
Mouviciel
Vamos esperar que não seja o professor, porque você não precisa saber porcaria como essa. Embora eu suponha que um bom professor primeiro lhe dê um tapa na cara com expressões como estas, permitindo que você coça a cabeça tentando interpretá-las e depois mostre como usar o typedef corretamente.