- PR -

C言語の構造体を配列の様に見る事は可能?

投稿者投稿内容
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-08-18 14:21
引用:

コブラさんの書き込み (2004-08-18 13:14) より:

足りんと言うなら足りるようにするまで。


たーぞうさんの本質を解決していません。

> それやとデータ件数が65536件までに限定されてしまいます

また、i++;だけでは、ファイルに65537件以上のデータがあった場合、アクセスする領域が上限を超えてしまいます。
if ((++i) >= MAX) {fprintf(stderr,"over max count."); exit(-1);}
通りすがり
会議室デビュー日: 2004/07/02
投稿数: 8
投稿日時: 2004-08-19 00:23
皆さん、親切に返答して頂いて大変有り難うございました。

全く関係無い板にスレッドを作って申し訳ないです。
御指摘通り、書いたスレッドが間違っておりました、以後気をつけます。

スレッドも違う事ですしなんとか出来そうなので、
これで一端、終結させて頂きます。
特にJitta様の御意見は大変参考になりました。

本当に有り難う御座います。

[ メッセージ編集済み 編集者: 通りすがり 編集日時 2004-08-19 00:28 ]
はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2004-08-19 13:55
はにまるです。質問です。

引用:

Jittaさんの書き込み (2004-08-18 08:40) より:
 まず、charで確保する領域ですが、40バイト+nullで41とか、21ですか?しかし、sizeofで、配列のサイズを出してみてください。宣言しているバイト数をそのまま計算したのとは違うと思います。内部で最小単位に丸められます。8バイト単位にしておきましょう。
コード:
struct book{ 
    struct book *next; /* 次のデータへのポインタ←慣例的に一番前 */
    char title[48]; 
    char author[24]; 
    int bookid; 
    int abaiable; 
};




何故、8バイト単位なのですか?
よくあるメモリ領域無駄無く利用する為のテクニックでしょうか?
興味で質問しておりますが、そのあたりの説明サイトとかあればお教え下さい。
お願い致します。
まいるどきゃっと
大ベテラン
会議室デビュー日: 2004/08/12
投稿数: 135
お住まい・勤務地: 群馬
投稿日時: 2004-08-19 14:18
まいるどきゃっとです。こんにちは。

はにまるさんと質問かぶってしまいますが、Jittaさんが8バイト単位で配列を宣言しているのはなぜでしょうか?

私もC言語を覚えたての頃は、構造体の配列を8バイト単位で宣言していましたが、今ではやめています。理由は、

(1) 後からソースを見た人にとって、何を意図した数字か分かりにくい。
(2) 必要な長さと8バイト単位の長さの2重管理になってしまう。
(3) Cコンパイラの実装にとらわれた考え方に基づいている。
(4) そもそも、8バイト単位にする意味が思いつかなかった。

といった所でしょうか。
もしかしたらメリットはあるのかもしれませんが、ソースのメンテナンス性を下げてまで行う理由を見つけられませんでした。

そんなわけで、最大長の決まっている配列の場合は、8バイト単位で宣言するのをやめました。
今でも、バッファのような、長さをきっちり決める必要がなく多少余裕があったほうがいいものは、8バイト単位(というより2のn乗)にしています。
でもそれは、単にきりのいい数字と感じているからです。

ちなみに、普段私が構造体を書くときは、以下のようにしています。

コード:
enum {
    BOOK_TITLE_MAX  = 40, /* 書名の最大長 */
    BOOK_AUTHOR_MAX = 20, /* 著者名の最大長 */
};

typedef struct Book Book;
struct Book{
    Book    *next;                          /* 次のデータへのポインタ */
    char    title[BOOK_TITLE_MAX + 1];      /* 書名 */
    char    author[BOOK_AUTHOR_MAX + 1];    /* 著者名 */
    int     bookid;                         /* 本ID */
    int     available;                      /* 貸し出しフラグ */
};



# 定数宣言が#defineじゃなくてenumなのは、「プログラミング作法」の影響です
okutin
ベテラン
会議室デビュー日: 2003/12/11
投稿数: 98
お住まい・勤務地: 広島
投稿日時: 2004-08-19 14:38
こんにちは。

引用:

はにまるさんの書き込み (2004-08-19 13:55) より:

何故、8バイト単位なのですか?
よくあるメモリ領域無駄無く利用する為のテクニックでしょうか?
興味で質問しておりますが、そのあたりの説明サイトとかあればお教え下さい。
お願い致します。




明示的にバウンダリ調整を行うことで、移植性を高めるためでしょう。
例えばintのサイズが4バイトの環境で以下のような構造体を定義した場合、
コード:
struct hoge{ 
    char hoge1[3]; 
    int hoge2; 
};


処理系やコンパイルオプションの違いなどで、sizeofの結果が8の場合と7の場合が考えられます。
また、他言語や他OSとのソケット等を使った通信を行う場合などでも問題が出てきたりすることがあります。
コンパイラによって勝手に大きさを変えられる前に自前で変えておこうということだと思います。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-08-19 14:43
引用:

はにまるさんの書き込み (2004-08-19 13:55) より:

何故、8バイト単位なのですか?
よくあるメモリ領域無駄無く利用する為のテクニックでしょうか?


 正しくは「8」ではなく、「最小単位」です。これは、struct宣言を見て計算したバイト数と、sizeofで算出されるバイト数をあわせることが目的です。

引用:

まいるどきゃっとさんの投稿より:

(1) 後からソースを見た人にとって、何を意図した数字か分かりにくい。
(2) 必要な長さと8バイト単位の長さの2重管理になってしまう。
(3) Cコンパイラの実装にとらわれた考え方に基づいている。
(4) そもそも、8バイト単位にする意味が思いつかなかった。


1→文字列の終端まで含めて、宣言します。配列宣言で+1とかはしません。
2→よって、2重管理になるとは思いません。
3→もちろん、コンパイラの実装によって異なります。
4→8バイトではなく、「最小単位」です。

 コンパイラには、アライメントを整えない、というオプションがありますが、これをON(整えない)にするなら意味はありません。OFF(整える)とすると、宣言上のバイト数と実際のバイト数が異なります。このとき、外部データ仕様書に
char 3バイト
int
char 4バイト
と書いてあると、実際のバイト数と異なります。しかし、バイト境界を意識して設計することで、そのような食い違いによるバグを作り込む可能性が減ります。


 Borland系コンパイラの場合、「データの配置境界」で、1,2,4,8バイトから選択できるようです。
 .NETでは・・・Visual C++の「コンパイラオプション」をざっと眺めましたが、該当するオプションを見つけられませんでした。
→yさん、ぢゃん♪さん、補足ありがとうございます。確認しました。
→「/Zp 構造体メンバをパックします。」
 Sunのコンパイラでは、missalignだったかな?

[ メッセージ編集済み 編集者: Jitta 編集日時 2004-08-19 15:28 ]
y
会議室デビュー日: 2003/12/03
投稿数: 3
投稿日時: 2004-08-19 15:19
Visual C++ではコンパイラオプションの/Zpで指定できます。
1、2、4、8、16から選べます。

ソース中のある構造体のみ変更したいときは
#pragma pack(1)  ←アライメントを1に設定
構造体定義
#pragma pack()  ←アライメントをデフォルトに戻す
のようにも使えます。
ぢゃん♪
大ベテラン
会議室デビュー日: 2003/06/12
投稿数: 208
お住まい・勤務地: 都内
投稿日時: 2004-08-19 15:20
引用:

 .NETでは・・・Visual C++の「コンパイラオプション」をざっと眺めましたが、該当するオプションを見つけられませんでした。


ソース埋め込みなら #pragma pack(〜) 、コンパイラなら /Zp〜 、ですね。
# 懐かしい……。

スキルアップ/キャリアアップ(JOB@IT)