3

3つのファイルがあります:source1.c source2.c header.h

2つのソースファイルにはヘッダーが含まれています。

これはヘッダーのコードです:

struct
{
    int a;
    int b
} x;

ここで何が起こるかというと、構造体がグローバルになり、2つのソースファイルがxという構造体を共有するようになります。なぜこれが起こるのですか?

次のコードを書くと、2つのグローバル変数が作成されることを私は知っています。ソースファイルごとに1つ。(グローバルを共有しません)

int x = 0;

最後のコードは私には理にかなっていますが、構造体のコードは本当にわかりません。

編集:
うーん、ここのみんなは私がリンカーエラーを取得する必要があると思います。私の現在のコードは組み込みシステム(nxtOSEK)用です。後で通常のCプログラムに変換してみます。

EDITEDIT:
通常のCの例に戻ります。ご覧のとおり、構造体だけでなく通常の変数でも可能です。

source1.c

#include "header.h"

int main(void)
{
    f();
    x = 1;
    f();
}

source2.c

#include "header.h"

void f()
{
    printf("source2: %i\n", x);
}

header.h

#include <stdio.h>

int x;

出力

source2: 0
source2: 1

xが機能するために宣言してはならないことに注意してください。そうしないと、ここで誰もが言ったようにリンカーエラーが発生します。(なぜそれが埋め込みシステムで動作するのかわかりません。)

また、EricPostpischilの正解を読み間違えたようです。

4

2 に答える 2

10

初期化子を持つファイルスコープでのオブジェクト識別子の外部宣言は定義です。初期化されているため、宣言int x = 0;は定義です。x

初期化子を持たないファイルスコープでのオブジェクト識別子の外部宣言は、暫定的な定義です。宣言struct {…} x;は初期化されていないため、暫定的な定義ですx

リンク時に複数の定義があるとエラーが発生します。

リンク時の複数の仮定義は、ゼロで初期化される単一の定義に合体されます。

に変更int x = 0;してint x;も、リンクエラーは発生しません。に変更struct {…} x;するstruct {…} x = {0};と、リンクエラーが発生します。

于 2012-09-28T17:16:12.873 に答える
9

以下のコードの一部

struct
{
    int a;
    int b;
} x;

タグのないx型の変数を宣言します。structこれは、単一のコンパイル単位で使用する予定の静的構造体では問題structありませんが、複数の.cファイル間で共有する場合は、そのようにしないでください。代わりに、のタグを定義するstructか、タグを作成し、構文typedefを使用してそのタイプの変数を個別に宣言する必要があります。srtruct my_struct

次に例を示します。

このstruct宣言をヘッダーに入れます。

struct a_and_b
{
    int a;
    int b;
};

この変数宣言を.cファイルに入れます。

static struct a_and_b x;

これxでグローバルではなくなりました。.cファイル内でアクセスできますが、外部からは表示されません。グローバルにしたいが、リンカーエラーを回避したい場合は、次を追加します。

extern struct a_and_b x;

ヘッダーにstatic追加し、.cファイルの宣言から削除します。

于 2012-09-28T16:49:06.213 に答える