- ベストアンサー
配列からポインタを使って長さの違う変数への格納
uint32_t X; uint8_t Z[4] = {0x01, 0x02, 0x03, 0x04}; X = *Z; 上記のような書き方をした場合、 X には 「0x01020304」という値が格納されるものと考えて良いのでしょうか?
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
そうじゃないですよ。 Z は、 uint8 へのポインタですから、 Zのアドレスのさすuint8値をとってくる その値をuint32 へ拡張する その結果を、Xにいれる ということで、Xには、0x01 がはいります。 なお、C,C++では、変数名に大文字を使うのは、たいていの場合、コーディング規則違反となります。
その他の回答 (4)
- Tacosan
- ベストアンサー率23% (3656/15482)
処理系によってはアラインメント制約に引っかかって X = *(uint32_t*)Z; が動作しないことも考えられます. その場合の動作は未定義ですから, 突然鼻歌を歌いだしたとしても文句は言えません. #4 の最後にあるように適切な式を使う以外は可搬性がありません.
お礼
ご回答ありがとうございます。 スマートに処理するために適切では内方法を採用していては本末転倒ですので、おっしゃるとおりそれらも含めて考えてみたいと思います。
- rinkun
- ベストアンサー率44% (706/1571)
X = *(uint32_t*)Z; とすれば一応32bit値を格納できるが、期待した値が入るかどうかはバイトオーダーによる。 x86系システムなら0x04030201になるでしょう。 意図した値を得るなら X=Z[0]*0x1000000+Z[1]*0x10000+Z[2]*0x100+Z[3]; が妥当でしょうね。
お礼
ご回答ありがとうございます。 実はこれらのコードは 8bit のマイコン上で動かすもので、可能な限り少ないクロックで処理したいという狙いもあります。 ビットシフトで近いことが出来ますので、ユニオンがうまくいかない場合参考にさせて頂きたいと思います。
- 麻野 なぎ(@AsanoNagi)
- ベストアンサー率45% (763/1670)
一応、「共用体」という機能があります。 #include <iostream> int main() { union { unsigned char z[4]; unsigned int x; } data; data.z[0] = 1; data.z[1] = 2; data.z[2] = 3; data.z[3] = 4; std::cout << data.x; return 0; } で、出力されるのは 0x04030201 です。 環境によっては、0x01020304 が出力されるかもしれません。 (この順番は、処理系依存なので、確認が必要です)
お礼
ご回答ありがとうございます。 ユニオンを使った方法を提供して頂いたコード例を参考に検証してみたいと思います。
そういう場合は、union を使うという手があります。ただし、unionを使う方法は、使っているマシンのバイト並び(little endian or big endian)によって、異なる結果となります。
お礼
ご回答ありがとうございます。 ユニオンについて少し調べてみました。 参考にしてみたいと思います。
お礼
ご回答ありがとうございます。 同等のことをやりたい場合、やはりビットシフトしながら順番に追加していくしかないのでしょうか? もっとスマートな方法はないものかと模索しているところです。
補足
皆さんに有意義なアドバイスを頂きましたが、本来の質問へのご回答ですので、ベストアンサーに選ばせて頂きます。 ご回答いただいた皆さんありがとうございました。