1

C で抽象データ型 STACK を実装する割り当てがあります。データ型の性質上、メモリを割り当てる必要があるキー構造が必要です。私の問題は、今のところ、初期化関数がキー構造へのポインターを取得することをインストラクターが主張していることです。init() 関数は、構造体に必要なメモリを割り当て、フィールドをゼロに設定するだけですが、渡されるポインタにはそのメモリ位置を割り当てる必要があります。

関数にポインターを返すか、2 つ星のポインターを渡すことなく、これを行う方法は考えられません。どちらも許可されていません。関数プロトタイプは次のようにする必要があります (ここで、stackT* は主要な STACK データ構造へのポインターです)。

    void init(stackT* stack);

私はこれを思いつきました、そしてそれはうまくいきます:

    void init(stackT** stack){
        *stack = (stackT*) malloc(sizeof(stack));
        (*stack)->count = 0;
        return;
    }

しかし、それは割り当ての制限を順守しません。


tl;dr バージョン:

基本的に、STACK データ構造 (&stackPtr) への元のポインターのアドレスを、1 つ星のポインターを引数として取り、ポインター型の警告を受け取らない関数に渡すにはどうすればよいですか? さらに、引数を(stackT* stack)以下のコードに変更すると、どちらの方法でも同じものを渡しているにもかかわらず、機能しません。これが私の問題です。

ポインターをポインターに渡す場合は、引数を2つ星のポインターにする必要があると思いました..コンパイラーは、ポインターを逆参照するときに何を扱っているかを知る必要があります。

いずれにせよ、制限があるため、これを行う方法がわかりません。私の意見では、これは不必要に難しくしているだけです。

4

4 に答える 4

3

コメントで指摘されているように、あなたは意図を見逃していると思います。

stackT「ルート」インスタンスは、ローカルで宣言できるように、よく知られた構造にする必要があるという考えだと思います。次に、インスタンスinit()によって記述された実際のスタックをセットアップするために呼び出します。stackT

int push_four(void)
{
  stackT my_stack;

  init(&my_stack);
  push(&my_stack, 1);
  push(&my_stack, 2);
  push(&my_stack, 3);
  push(&my_stack, 4);
}

上記は、スタックが整数を格納していることを前提としています。つまり、内部の割り当ては次のinit()ようになります。

void init(stackT *stack)
{
  stack->items = malloc(64 * sizeof *items);
  stack->count = 0;
}

そして、これは、次のような宣言を想定しています。

typedef struct {
  int *items;
  size_t count;
} stackT;

もちろん、デフォルトの最大深度 (64) は へのパラメーターであるinit()必要があり、 の戻り値をチェックする必要があります (ただしキャストはしないでください!)malloc()などです。

于 2013-09-11T12:59:44.100 に答える
2

通常、複雑な構造がある場合、コントロールがstructあり、そのコントロールには実際のメモリへのポインターがあります。

例:

struct stack_control_s {
    void * memory;
    size_t memory_size;
    size_t current_size;
};

次に、制御構造へのポインターをイニシャライザーに渡して、実際の作業を実行させます。

#define STACK_MIN_SIZE 0x100
int stack_init(struct stack_control_s * stack) {
    memset(stack, 0, sizeof(*stack));

    stack->memory = calloc(STACK_MIN_SIZE, 1);

    if (!stack->memory)
        return -1; //error

    stack->memory_size = STACK_MIN_SIZE;

    return 0; // all good
}

これは、私がかつて作成した一般的な C リストのヘッダーを少し変更したものです。スタックとして使用できるようにマクロに追加しました。多分これはあなたにいくつかのインスピレーションを与えるでしょう:

list_t.h

使用する:

list_t(char) mylist;
list_init(&mylist);

list_push(&mylist, 'A');

printf("%c\n", list_pop(&mylist));
于 2013-09-11T13:00:13.303 に答える