構造体に関しまして(c言語初心者です)

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
kirincyan

構造体に関しまして(c言語初心者です)

#1

投稿記事 by kirincyan » 14年前

初めまして、c言語初心者です。
現在、構造体に関して勉強しています。

構造体に関して教えて頂きたいのですが、
以下のようなコードを生成して、
コンパイルするとエラーが発生するのですが、
その理由がよくわかりません。
レベルの低い質問で申し訳ありません。

[コード][エラー内容][コンパイル環境]を以下に記載します。
どなたか解決方法がお分かりになれば、ご教授頂けないでしょうか。
よろしくお願いします。

コード:

#include <stdio.h>

typedef struct sAst{
    char A1;
    char A2;
}sAst;

typedef struct sBst{
    char a;
    int b;
    sAst* pAst;
}sBst;


int main()
{
    sAst Ast1[] = {{1, 25},
                   {2, 26},
                   {3, 27}};

    sBst Bst1[] = {'M', 19, Ast1};

    printf("Bst1=%d\n", sizeof(Bst1));

    return 0;
}
[エラー内容]
上記コードをTest.cというファイルに保存してコンパイルを行うと以下のエラーが発生します。

    Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
    Test.c:
    エラー E2063 Test.c 21: 不正な初期化(関数 main )

コードの以下の行でエラーが発生しているようなのですが、
その理由がよくわかっていません。

sBst Bst1[] = {'M', 19, Ast1};


[コンパイル環境]
コンパイラー:Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
OS :Windows7

mert

Re: 構造体に関しまして(c言語初心者です)

#2

投稿記事 by mert » 14年前

sBst Bst1[] = {'M', 19, Ast1};

この文の左のBst1[]は、sBst型の配列をあらわしています。
ですが右側は、ひとつのsBst型の値です。

要するに、

int a[]=1;

こういう状況になっているのだと思います。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 構造体に関しまして(c言語初心者です)

#3

投稿記事 by beatle » 14年前

gcc 4.6.1を用いてコンパイルしてみました。

コード:

$ gcc main.c --ansi --pedantic
main.c: In function 'main':
main.c:21:5: warning: initializer element is not computable at load time [enabled by default]
main.c:21:5: warning: initializer element is not computable at load time [enabled by default]
Bst1を初期化するときに使っているAst1は定数ではない、という警告は出ていますが、
それ以外の所ではエラーや警告は出ていません。
僕も、実際にコンパイルしてみる前はmertさんと同じ意見だったのですが、実際にコンパイルが通ってしまったので
もしかしたら規格で決まっている正しい初期化方法なのかもしれません。調べていませんが。

ちなみにmertさんが例として挙げた

コード:

int a[] = 1;
はエラーになりました。

kirincyanさんはAst1の初期化はうまく書けていますね。配列の定義と初期化の基本は

コード:

要素の型 配列名[] = { 要素0, 要素1, 要素2 };
ですね。で、構造体自体は

コード:

Hoge hoge = { foo, bar, baz };
と初期化します。つまり、構造体の配列は

コード:

Hoge hogeArray[] = { {foo0, bar0, baz0}, {foo1, bar1, baz1}, {foo2, bzr2, bzr2} };
ですね。

kirincyan

Re: 構造体に関しまして(c言語初心者です)

#4

投稿記事 by kirincyan » 14年前

mertさん、beatleさん、どうもありがとうございます。

一度、beatleさんが試されたコンパイラーを使ってみようと思います。

もしも、
Borland C++ 5.5.1でコンパイルエラーの発生しないような、
以下と同じ意味合いとなる記述方法がある場合、またご教授願えればありがたいです。

sBst Bst1[] = {'M', 19, Ast1};

よろしくお願いします。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 構造体に関しまして(c言語初心者です)

#5

投稿記事 by beatle » 14年前

kirincyan さんが書きました:もしも、
Borland C++ 5.5.1でコンパイルエラーの発生しないような、
以下と同じ意味合いとなる記述方法がある場合、またご教授願えればありがたいです。

sBst Bst1[] = {'M', 19, Ast1};
僕が書いたやり方ではだめでしたか?

non
記事: 1097
登録日時: 15年前

Re: 構造体に関しまして(c言語初心者です)

#6

投稿記事 by non » 14年前

sBst Bst1[] = {'M', 19, NULL};
ではエラーがでませんでした。
ということは、コンパイラが、Ast1をアドレスに変換するタイミングと、初期化するタイミングのパスが
同じなのかもしれませんね。

でも
int a=0;
int *b=&a;
は、コンパイラに通りました。
non

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 構造体に関しまして(c言語初心者です)

#7

投稿記事 by beatle » 14年前

もしかしたら、構造体の初期化は

コード:

Hoge hogeArray[] = { foo0, bar0, baz0, foo1, bar1, baz1, foo2, bzr2, bzr2 };
と書いてもアリなのかもしれません。とりあえず

コード:

sBst Bst1[] = {'M', 19, 0, 'A', 1, 0};
はgcc --ansi --pedanticでコンパイルが通りますし、sizeof(Bst1)は24になります。
もちろんBst1[0].a == 'M', Bst1[1].a == 'A'と、きちんと初期化されています。

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: 構造体に関しまして(c言語初心者です)

#8

投稿記事 by ISLe » 14年前

Borland C++ 5.5.1はこんなコードもコンパイルできません。

コード:

#include <stdio.h>
int main(void) {
    int i=10;
    int *a[] = {&i}; /* エラー E2063 */
    printf("%d\n", *a[0]);
    return 0;
}
構造体や配列の初期化に一時変数のアドレスは使えません。
コンパイラの仕様です。

kirincyan

Re: 構造体に関しまして(c言語初心者です)

#9

投稿記事 by kirincyan » 14年前

beatleさん、皆様、情報ありがとうございます。

同コードをgccを使用して、エラーがでないことを確認しました。

極力、どのコンパイラーでもエラーが発生しないようなコードが作成できるように
学習を続けます。

不明なことがあればまた質問させて頂きますので、よろしくお願いします。

閉鎖

“C言語何でも質問掲示板” へ戻る