Cポインターの優先順位はどのように決定されますか?


14

私は理解に苦労している2つのポインタ宣言に遭遇しました。優先ルールの私の理解は次のようになります。

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

2番目の例

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

それらをどのように読むべきですか?


1
言語がその機能をどのように処理するかについての質問は、ここで話題になります。

回答:


7

最初の推測:ptrは、パラメーターとしてintを受け取る関数へのポインターであり、パラメーターとしてdoubleとcharへのポインターを受け取り、floatへのポインターを返すパラメーターへのポインターを返します。

解釈

(* ptr)(int)

ptrは、intを引数として取る関数へのポインターであると言います。その関数が返すものを発見するには、ビューを拡張する必要があります。

(*(* ptr)(int))

これは、関数が別の関数へのポインタを返すことを意味します。他の関数のパラメーターは次のとおりです。

(ダブル**、char c)

そしてそれは戻ります

浮く *

2番目の場合:ptrは、charへの定数ポインターとintへのポインターをパラメーターとして取る関数への5つのポインターの配列へのポインターであり、unsigned intのポインターへのポインターを返します。

解釈

(*(* ptr)[5])

関数取得への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を受け取り、doubleおよびcharへのポインターへのポインターを受け取り、floatへのポインターを戻す関数へのポインターを返す関数へのポインターです」。スパイラルを試してみると、同じ結果が得られます。
Remo.D

1

これは関数ポインターです。それを書いた人はそれをより明確にするためにtypedefをよりうまく利用できたかもしれません。

実際には、これらのパラメーターを持つ関数へのポインターです。float * myfunc(double **、char)


4
私の賭けは、それを書いた人が先生だということです。
mouviciel

このようながらくたを知る必要はないので、それが教師ではないことを願っています。良い先生は、最初にこれらのような表現で顔を平手打ちし、それらを解釈しようとして頭を傷つけ、次に typedefを適切に使用する方法を示します。

1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.