web-dev-qa-db-ja.com

構造体を外部に作成し、typedefを定義する方法

Cでツリーアルゴリズムを実装しようとしています。完全に独立したヘッダーファイル(b_tree_ds.h)でextern構造体を宣言しています。次に、この構造体を使用するすべてのソースファイルにファイルをインポートする予定です。そのため、ヘッダーでexternを使用して宣言する必要があります。

問題は、typedefを定義したいということです。コンパイラは、複数のストレージクラスのエラーを返します。どうすればいいですか。

typedef extern struct node {
    struct node* left;
    struct node* right;
    int key;    // contains value
}NODE;

実際の問題は次のとおりですが、まだ修正できません。最近、ヘッダーファイルと共に複数のソースファイルを使用して、コードを移植可能かつ階層的にする方法を学びました。そうするために、私はこのプリンシパルを使用してツリープログラムを作成するのに疲れました。ここに私のファイルがあります

b_tree_ds.h-これには、ツリーのノードのデータ構造の宣言が含まれます。これは、ツリーのさまざまな機能を実装するさまざまな機能(さまざまなソースファイルにある可能性があります)に呼び出すことができます

typedef struct node {
    struct node* left;
    struct node* right;
    int key;    // contains value
}NODE;

Typedef extern struct nodeのようにexternを追加しようとすると、複数のストレージクラスのエラーが発生しますが、それを見逃すと、複数の定義でエラーが発生します。

私の他のソースファイルはこちら

traverse.h-トラバース関数の宣言を含みます

void traverse_print (NODE* p);

ここでも、不明な識別子NODEのエラーが発生します

traverse.c-その関数の定義が含まれています

#include <stdio.h>
#include "b_tree_ds.h"
#include "traverse.h"

void traverse_print(NODE* p)
{
    if(p->left != NULL)
    {
        traverse_print(p->left);
    }

    if (p->right != NULL)
    {
        traverse_print(p->right);
    }

    printf ("\n%d",p->key);
}

最後にmain.c

#include <stdio.h>
#include "traverse.h"

void main()
{
    // input
    NODE p;

    printf("\nInput the tree");
    input_tree (&p);

    printf("\n\nThe tree is traversing ...\n")
    traverse_print(&p);
}

void input_tree (NODE *p)
{
    int in;
    int c;
    NODE *temp;

    printf("\n Enter the key value for p: ");
    scanf("%d", &in);
    p->key  =in;
    printf ("\n\nIn relation to node with value %d",in);
    printf ("Does it have left child (Y/N): ")
    if ((c = getchar()) == Y);
    {
        //assign new memory to it.
        temp = (NODE *)malloc(sizeof(NODE));
        input_tree(temp);
    }
    printf ("\n\nIn relation to node with value %d",p->key);

    printf ("\nDoes it have right child (Y/N): ")
    if ((c = getchar()) == Y);
    {
        //assign new memory to it.
        temp = (NODE *)malloc(sizeof(NODE));
        input_tree(temp);
    }
}

これはそのような実践への私の最初の試みです。私のプログラムの構造化が良いか、何か他のものを試すべきかを提案してください。

17
simar

構造体externを作成することはできません。 include-guardで保護されたヘッダーで定義し、必要な場所にそのヘッダーを含めるだけです。

SquareRootOfTwentyThreeの編集

次の方法 でこれらのサームを使用します。

構造タイプ定義は、構造の一部であるメンバーを記述します。 structキーワードとそれに続くオプションの識別子(構造タグ)および中括弧で囲まれたメンバーのリストが含まれます。

構造体宣言は、宣言にメンバーの括弧で囲まれたリストがないことを除いて、構造体定義と同じ形式です。

したがって、「定義」はまさに私が意味したものです。

25
cnicutar

Cでは、構造体にはリンケージがなく、オブジェクトと関数のみがリンケージします。だからあなたはこれを書くことができます:

// header file 'node.h'

typedef struct node_
{
    /* ... */
} node;

extern node root_node;

次に、どこかに実装を提供します。

// source file

#include <node.h>

node root_node;
27
Kerrek SB

ヘッダーファイルでこのようにnode.hを宣言します

#ifndef NODE_H
#define NODE_H

#ifdef  __cplusplus
extern "C" {
#endif

typedef struct node {
        struct node* left;
        struct node* right;
        int key;    // contains value
    }NODE;


#ifdef  __cplusplus
}
#endif

#endif  /* NODE_H */  

このヘッダーファイルを任意のcプログラムに含めて、次のように使用できます。

NODE* newNode = NULL;
1