パスワードを忘れた? アカウント作成
この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。

Cに欲しい機能 インデックス番号付き構造体配列」記事へのコメント

  • enumは0から順番に割り振られることが保証されてるので、そのまま配列indexに使えると思いますが…

    // indexをIDとして定義
    enum{
      ColorId_Info,
      ColorId_Warn,
      ColorId_Error,
    }ColorId;
     
    // 引きたい内容の構造体
    typedef struct{
      int r, g, b,
      const char *name,
    }ColorInfo;
     
    // 引きたい内容の実態
    static const ColorInfo = colorInfos[] = {
      {0, 32, 64, "Info"},
      {0, 64, 128, "Warn"},
      {0, 128, 255, "Error"},
    };
     
    // 以下、引く機能は概念コード
    size_t getNumColorInfos(){ return sizeofを使ったいつものトリックで要素数 };
    ColorInfo *getcolor(color_id)
    {
      if (0 <= color_id && color_id < getNumColorInfos()) return &(colorInfos[color_id]);
      return NULL;
    }

    って感じで。enum定義とColorInfo配列インデックスとの対応が非明示的なのが気になるなら、

    enum{
      ColorId_Info=0,
      ColorId_Warn=1,
      ColorId_Error=2,
    }ColorId;

    と、明示的に割り当てた方が、対応がわかりやすいですかね。

    あと、
    > 実際、こういうコードを書き出すジェネレータを自分で書こうかとも思ったのですが、エラー行番号がコンパイラと元コードで一致しないなど、諸々面倒でやっていません。
    ジェネレータ側で、#line ディレクティブを使って、ジェネレート元のファイル名・行番号を

    #line 行番号 "ファイル名"

    という形式で出力しておけば、コンパイラエラーなどは#lineで指定したもので表示されるようになりますよ。

    • コメントで頂いた通り、enumと構造体配列の対応が非明示的なのが、今のやり方では満足いかない理由のひとつです。

      #line ディレクティブは思いつきませんでした。
      でもコンパイラの行番号表示をこちらから指示するのはちょっと不安に感じますね。

      親コメント
    • by Anonymous Coward

      > > enum{
      > > ColorId_Info=0,
      > > ColorId_Warn=1,
      > > ColorId_Error=2,
      > > }ColorId;
      > と、明示的に割り当てた方が、対応がわかりやすいですかね。

      構造体配列の方が連番になっていることが前提なので、明示的に割り当てると逆にトラブルの元じゃないですかね。
      うっかり数字を抜かしたり入れ替えてしまったりした場合に分かりにくい。

      これに加えてさらに、C99で導入された配列初期化の拡張を使うと良いと思います。

      // 引きたい内容の実態
      static const ColorInfo colorInfos[] = {
          [ColorId_Info] = {0, 32, 64, "In

192.168.0.1は、私が使っている IPアドレスですので勝手に使わないでください --- ある通りすがり

処理中...