- - PR -
C言語の構造体を配列の様に見る事は可能?
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-08-18 14:21
たーぞうさんの本質を解決していません。 > それやとデータ件数が65536件までに限定されてしまいます。 また、i++;だけでは、ファイルに65537件以上のデータがあった場合、アクセスする領域が上限を超えてしまいます。 if ((++i) >= MAX) {fprintf(stderr,"over max count."); exit(-1);} | ||||||||
|
投稿日時: 2004-08-19 00:23
皆さん、親切に返答して頂いて大変有り難うございました。
全く関係無い板にスレッドを作って申し訳ないです。 御指摘通り、書いたスレッドが間違っておりました、以後気をつけます。 スレッドも違う事ですしなんとか出来そうなので、 これで一端、終結させて頂きます。 特にJitta様の御意見は大変参考になりました。 本当に有り難う御座います。 [ メッセージ編集済み 編集者: 通りすがり 編集日時 2004-08-19 00:28 ] | ||||||||
|
投稿日時: 2004-08-19 13:55
はにまるです。質問です。
何故、8バイト単位なのですか? よくあるメモリ領域無駄無く利用する為のテクニックでしょうか? 興味で質問しておりますが、そのあたりの説明サイトとかあればお教え下さい。 お願い致します。 | ||||||||
|
投稿日時: 2004-08-19 14:18
まいるどきゃっとです。こんにちは。
はにまるさんと質問かぶってしまいますが、Jittaさんが8バイト単位で配列を宣言しているのはなぜでしょうか? 私もC言語を覚えたての頃は、構造体の配列を8バイト単位で宣言していましたが、今ではやめています。理由は、 (1) 後からソースを見た人にとって、何を意図した数字か分かりにくい。 (2) 必要な長さと8バイト単位の長さの2重管理になってしまう。 (3) Cコンパイラの実装にとらわれた考え方に基づいている。 (4) そもそも、8バイト単位にする意味が思いつかなかった。 といった所でしょうか。 もしかしたらメリットはあるのかもしれませんが、ソースのメンテナンス性を下げてまで行う理由を見つけられませんでした。 そんなわけで、最大長の決まっている配列の場合は、8バイト単位で宣言するのをやめました。 今でも、バッファのような、長さをきっちり決める必要がなく多少余裕があったほうがいいものは、8バイト単位(というより2のn乗)にしています。 でもそれは、単にきりのいい数字と感じているからです。 ちなみに、普段私が構造体を書くときは、以下のようにしています。
# 定数宣言が#defineじゃなくてenumなのは、「プログラミング作法」の影響です | ||||||||
|
投稿日時: 2004-08-19 14:38
こんにちは。
明示的にバウンダリ調整を行うことで、移植性を高めるためでしょう。 例えばintのサイズが4バイトの環境で以下のような構造体を定義した場合、
処理系やコンパイルオプションの違いなどで、sizeofの結果が8の場合と7の場合が考えられます。 また、他言語や他OSとのソケット等を使った通信を行う場合などでも問題が出てきたりすることがあります。 コンパイラによって勝手に大きさを変えられる前に自前で変えておこうということだと思います。 | ||||||||
|
投稿日時: 2004-08-19 14:43
正しくは「8」ではなく、「最小単位」です。これは、struct宣言を見て計算したバイト数と、sizeofで算出されるバイト数をあわせることが目的です。
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 ] | ||||||||
|
投稿日時: 2004-08-19 15:19
Visual C++ではコンパイラオプションの/Zpで指定できます。
1、2、4、8、16から選べます。 ソース中のある構造体のみ変更したいときは #pragma pack(1) ←アライメントを1に設定 構造体定義 #pragma pack() ←アライメントをデフォルトに戻す のようにも使えます。 | ||||||||
|
投稿日時: 2004-08-19 15:20
ソース埋め込みなら #pragma pack(〜) 、コンパイラなら /Zp〜 、ですね。 # 懐かしい……。 |