C言語関係掲示板

過去ログ

No723 エンディアンとシフト

[戻る] [ホームページ]
No.8778

リトルエンディアン
投稿者---初心者A(2003/08/03 19:40:48)


はじめまして。
C言語というか、プログラミング勉強中です。
さっそくなのですが、わからないことがありますので質問させて頂きます。教えて頂ければ幸いです。

PC種によってエンディアンが異なると思うのですが、リトルエンディアンについてです(Windows)。16bit変数tmp1に0x1234を代入した場合、メモリ上は0x34 0x12という順番で格納されると思います(?)。それで、上位0x12の値を変数tmp1から抜き出して16bit変数tmp2にコピーする場合はどうしたらよいのでしょうか?

tmp1 = 0x1234;
tmp2 = tmp1 & 0xff; // 下位8bitのマスク
であっているのでしょうか?これだと、0x34が抜き出されてしまうのか・・・

それとも、
tmp1 = 0x1234;
tmp2 = (tmp1 >> 8) & 0x00ff;

いろいろと自分でもプログラムを実行させながら検討しているのですが、
実際のメモリの中味等を見ているうちに混乱してしまいまいた。
エンディアンの考え方とかビットシフトについて教えて下さい・・・。



No.8780

Re:リトルエンディアン
投稿者---YuO(2003/08/03 19:58:55)


>いろいろと自分でもプログラムを実行させながら検討しているのですが、
>実際のメモリの中味等を見ているうちに混乱してしまいまいた。
>エンディアンの考え方とかビットシフトについて教えて下さい・・・。

エンディアンなんて気にせずにプログラムを組めばよいです。
メモリ上でどのように並んでいても,扱うのは「値」ですから。

エンディアンが問題になるのは,バイナリのままストレージに出力する場合などです。


No.8787

Re:リトルエンディアン
投稿者---あかま(2003/08/04 00:05:17)


そういうことを考えないでいいようにCなどの高級言語は作られました。
せいぜい異なるエンディアンの計算機と通信するときなどに使うぐらいです。

tmp1 = 0x1234;
tmp2 = tmp1 & 0xff;
でtmp2は0x0034

tmp1 = 0x1234;
tmp2 = tmp1 & 0xff00;
でtmp2は0x1200

tmp1 = 0x1234;
tmp2 = (tmp1>>8) & 0xff;
でtmp2は0x0012


です。任意ビットを取り出す時にC言語上でエンディアンを考える必要はありません。

No.8796

Re:リトルエンディアン
投稿者---初心者A(2003/08/05 02:05:26)


YuO様、あかま様
早急なご対応ありがとうございました。

そういうことだったのですね。深く考え過ぎていたようです。

次なる興味なのですが、もし、他装置との通信をする必要があった場合は、
決められたbitストリームの順序(ビッグ?orリトル?)に並び変えて送信し
てあげればよいということでしょうか?
例えば、通信順序がビッグであり、自装置がリトルエンディアンだった
場合は、どのように送信、受信してあげればよいのでしょうか?
またまた、混乱してしまいました...
いろんなHPなどを探索してみたのですが、このようなことを書いているもの
がなくよく分かりません。

教えて頂ければ幸いです。C言語の話題から反れつつあるのですが、
よろしくお願い致します。

No.8799

Re:リトルエンディアン
投稿者---三毛猫(2003/08/05 10:03:27)


>次なる興味なのですが、もし、他装置との通信をする必要があった場合は、
>決められたbitストリームの順序(ビッグ?orリトル?)に並び変えて送信し
>てあげればよいということでしょうか?

そうですね。予めどちらの形式を利用するか決めておいて、
その形式に合わせる形で送受信を行えば大丈夫です。

ちなみにSocketの場合は、htonl,ntohlなどの関数が
この処理を行います。
ネットワークに流すデータ形式(ネットワークバイトオーダ)と
ホスト側のデータ形式(ホストバイトオーダ)が
異なる場合にデータ形式を変換します。
(同じ場合は変換を行いません)

送信時にホストバイトオーダからネットワークバイトオーダへ、
受信時にはネットワークバイトオーダからホストバイトオーダへと
変換を行うことで正しくデータを受け渡しできます。

No.8824

Re:リトルエンディアン
投稿者---初心者A(2003/08/06 01:48:13)


三毛猫様

ご指導ありがとうございます。
htonl等のような便利な関数が用意されているんですね。
勉強になりました。

また、分からないこと出てきたら、再度投稿させて頂きます。
今後ともよろしくお願いします。