1. ホーム
  2. c

[解決済み] C言語はそんなに難しくない:void ( *( *f[] ) () ) ()

2022-04-23 17:44:59

質問

今日、ある写真を見たので、解説をお願いします。そこで、その写真を紹介します。

このようなコードが実用化されることはあるのだろうかと、戸惑いを覚えました。ググってみたら、別の写真が これ redditのエントリーで、その写真がこちらです。

では、この "reading spirally" は何か有効なものなのでしょうか?Cコンパイラはこのように解析するのでしょうか?

この変なコードについて、もっと簡単な説明があれば最高なのですが。

それとは別に、このようなコードは役に立つのでしょうか?もしそうなら、どこで、いつ?

があります。 質問 についてですが、単にその適用方法や、そのルールで表現した場合の読み方について聞いているわけではありません。そのような式の使い方やスパイラルルールの有効性についても質問しています。これについては、すでに素敵な回答が掲載されています。

どのように解決するのですか?

というルールがあります。 時計回り・螺旋の法則" を使えば、複雑な宣言の意味を見つけることができます。

から c-faq :

簡単な3つのステップがあります。

  1. 未知の要素から、らせん状に時計回りに進み、次の要素に出会ったら、対応する英文に置き換えてください。

    [X] または []

    => 配列Xのサイズ... または 配列のサイズ未定...

    (type1, type2)

    => type1とtype2を渡して返す関数...

    *

    => ポインタは...

  2. すべてのトークンがカバーされるまで、これを螺旋状/時計回りに続ける。

  3. 括弧の中にあるものは必ず最初に解決してください

上記のリンク先で例を確認することができます。

また、あなたを助けるためにというウェブサイトがあることに注意してください。

http://www.cdecl.org

C言語の宣言を入力すると、その英語の意味が表示されます。例えば

void (*(*f[])())()

が出力されます。

f を void を返す関数へのポインタの配列として宣言します。

EDITです。

のコメントでご指摘の通りです。 ランダム832 スパイラルルールは配列の配列を扱わないので、(ほとんどの)配列の宣言で間違った結果を導くことになります。例えば int **x[1][2]; は、スパイラルルールでは [] よりも優先順位が高い * .

配列の配列の前では,螺旋の法則を適用する前に,まず明示的に括弧を付けることができる.例えば int **x[1][2]; と同じです。 int **(x[1][2]); (C言語でも有効)優先順位とスパイラルルールにより、 "x is an array 1 of array 2 of pointer to pointer to int" と正しく読み取りますが、これは正しい英語の宣言です。

なお、この問題については、以下の記事でも取り上げています。 回答 によって ジェームス・カンゼ (ご指摘の ハックス をコメントで紹介しました)。