0

これが私が混乱したコードです。誰かがこのコードを修正してくれたら大変助かりますか?

 int (*(x)())[2];
int main()
{
   int (*(*y)())[2]=x;

   x();
   return 0;
}

int (*(x)())[2]
{
  int **str;
  str=(int*)malloc(sizeof(int)*2);
  return str;
}

xによって返されたときにポインターの配列を割り当てる方法?isはmallocのみのソリューションを使用していますか?

前もって感謝します

4

3 に答える 3

1

何を達成しようとしているのかは完全には明らかではないため、複数の可能性について説明します。

まず、C で複雑な宣言を読み書きする方法を復習します。

単項よりも優先順位が高いこと()を覚えておいてください。したがって、ポインタの配列であり、一方は配列へのポインタです。同様に、はポインタを返す関数であり、 は関数へのポインタです。 []**a[](*a)[]*f()(*f)()

毛むくじゃらの宣言を読み込もうとしているときは、上記のルールを思い出しながら、一番左の識別子から始めて解決してください。したがって、

 int (*(x)())[2];

として読む

        x            -- x
       (x)           -- x
       (x)()         -- is a function
      *(x)()         -- returning a pointer
     (*(x)())[2]     -- to a 2-element array
 int (*(x)())[2]     -- of int

この場合、すぐ周囲のかっこxは冗長であり、削除できます: int (*x())[2];.

このような関数を作成して使用する方法は次のとおりです。

int (*x())[2]
{
  int (*arr)[2] = malloc(sizeof *arr);  // alternately, you could simply write
  return arr;                           // return malloc(sizeof (int [2]));
}                                       // type of *arr == int [2]

int main(void)
{
  int (*p)[2] = NULL;                   // alternately, you could write
  ...                                   // int (*p)[2] = x();
  p = x();
  ...
  free(p);
}

arr、、pおよびx()すべての宣言が同じに見えることに注意してください。それらはすべてパターンに適合しますint (*_)[2];これは重要です。あるものを として宣言しT (*p)[N]、別のものをとして宣言するとT **q、それらの型は異なり、互換性がない可能性があります。の配列へのポインターTは、へのポインターへのポインターとは異なる型ですT

を返す関数へのポインターの配列を作成することが目標の場合、int型は のようint (*f[2])();になります。

      f          -- f
      f[2]       -- is a 2-element array
     *f[2]       -- of pointers
    (*f[2])()    -- to functions
int (*f[2])();   -- returning int

それは次のようになります。

int foo() {...}
int bar() {...}

int main(void)
{
  int (*f[2])() = {foo, bar};
  ...
}

を返す関数が必要な場合はf、少しトリッキーです。C 関数は配列型を返すことができません。それらは配列へのポインターのみを返すことができるため、関数宣言は次のように構築されます

        g            -- g
        g()          -- is a function
       *g()          -- returning a pointer
      (*g())[2]      -- to a 2-element array
     *(*g())[2]      -- of pointers
    (*(*g())[2])()   -- to functions
int (*(*g())[2])()   -- returning int

そして、そのようなビースティは次のように使用されます。

int foo() {...}
int bar() {...}

int (*(*g())[2])()
{
  int (*(*f)[2])() = malloc(sizeof *f);
  (*f)[0] = foo;     // the type of the *expressions* foo and bar
  (*f)[1] = bar;     // is `int (*)()`, or pointer to function
  return f;          // returning int
}

int main(void)
{
  int (*(*p)[2])();
  int x, y;
  ...
  p = g();
  x = (*(*p)[0])();
  y = (*(*p)[1])();
  ...
  free(p);
  ...
}

置換メソッドを使用して、外部から内部への毛むくじゃらの宣言を構築することもできることに注意してください。そう、

int x();                   -- x is a function returning int
int (*p)();                -- replace x with (*p) to get a pointer to a function
                                 returning int
int (*a[2])();             -- replace p with a[2] to get an array of pointers 
                                 to functions returning int
int (*(*q)[2])();          -- replace a with (*q) to get a pointer to an array
                                 of pointers to functions returning int
int (*(*g())[2])();        -- replace q with g() to get a function returning
                                 a pointer to an array of pointers to functions
                                 returning int.

同じ結果、異なるパス。私は最初の方法を好みますが、どちらでも機能するはずです。

多くの人typedefが、読みやすくするために使用することを推奨しています。

typedef int ifunc();        // ifunc is a synonym for "function returning int"
typedef ifunc *pifunc;      // pifunc is a synonym for "pointer to function
                            //   returning int
typedef pifunc farr[2];     // farr is a synonym for "2-element array of
                            //   pointer to function returning int
typedef farr *pfarr;        // pfarr is a synonym for "pointer to 2-element
                            //   array of pointer to function returning int

pfarr g() 
{
  pfarr f = malloc(sizeof *f);
  (*f)[0] = foo;
  (*f)[1] = bar;
  return f;
}

int main(void)
{
  pfarr p = g();
  int x, y;
  x = (*(*p)[0])();
  y = (*(*p)[1])();
  ...
}

はい、宣言は読みやすくなっていますが、 の宣言pと式の間に関連はありません(*(*p)[1])()なぜtypedefsその式がそのように書かれているのかを理解するには、すべての をくまなく調べて、それぞれの のメンタル マップを作成する必要があります。typedef

はい、次のような宣言int (*(*g())[2])()は、目を曇らせるように設計されており、その背後にあるすべてを隠して、typedefIMO の状況を悪化させます。

于 2012-06-26T18:16:47.493 に答える
0

この次のコードは、関数へのポインターの配列を提供し、配列の割り当て、受け渡しの標準的な手順が適用されます。

#include <stdio.h>
#include <stdlib.h>

typedef int (*XFunc())();

XFunc *x[2]; /* array of XFunc pointers */

int f1()
{
    printf("1\n");
    return 1;
}

int f2()
{
    printf("2\n");
    return 2;
}

int main()
{
    x[0] = (XFunc*)f1;
    x[1] = (XFunc*)f2;

    x[0]();
    x[1]();    

    return 0;
}

上記のポインターxは、(固定)配列の最初の要素を指します。このポインター値は、別の変数に割り当てられる値です。

于 2012-06-26T12:58:43.680 に答える
0

あなたが何をしたいのかわからない、多分これが役立つかもしれません

#include<stdio.h>      // printf
#include<stdlib.h>     // malloc free

int *x();              // forward declaration because used before definition

int main() {
    int *y=x();        // y is a pointer on int 
    printf ("%d %d\n", y[0], y[1]);
    free(y);           // must call free because dynamic allocation
    return 0;
}

int *x() {
    int *res;
    res=(int*)malloc(sizeof(int)*2);   // dynamic allocation of an array of two int
    // should check res != NULL
    res[0]=10;
    res[1]=20;
    return res;
}
于 2012-06-26T12:41:11.047 に答える