• ベストアンサー

配列からポインタを使って長さの違う変数への格納

uint32_t X; uint8_t Z[4] = {0x01, 0x02, 0x03, 0x04}; X = *Z; 上記のような書き方をした場合、 X には 「0x01020304」という値が格納されるものと考えて良いのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
noname#190876
noname#190876
回答No.1

そうじゃないですよ。 Z は、 uint8 へのポインタですから、  Zのアドレスのさすuint8値をとってくる その値をuint32 へ拡張する  その結果を、Xにいれる  ということで、Xには、0x01 がはいります。  なお、C,C++では、変数名に大文字を使うのは、たいていの場合、コーディング規則違反となります。

zero-spica
質問者

お礼

ご回答ありがとうございます。 同等のことをやりたい場合、やはりビットシフトしながら順番に追加していくしかないのでしょうか? もっとスマートな方法はないものかと模索しているところです。

zero-spica
質問者

補足

皆さんに有意義なアドバイスを頂きましたが、本来の質問へのご回答ですので、ベストアンサーに選ばせて頂きます。 ご回答いただいた皆さんありがとうございました。

その他の回答 (4)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

処理系によってはアラインメント制約に引っかかって X = *(uint32_t*)Z; が動作しないことも考えられます. その場合の動作は未定義ですから, 突然鼻歌を歌いだしたとしても文句は言えません. #4 の最後にあるように適切な式を使う以外は可搬性がありません.

zero-spica
質問者

お礼

ご回答ありがとうございます。 スマートに処理するために適切では内方法を採用していては本末転倒ですので、おっしゃるとおりそれらも含めて考えてみたいと思います。

  • rinkun
  • ベストアンサー率44% (706/1571)
回答No.4

X = *(uint32_t*)Z; とすれば一応32bit値を格納できるが、期待した値が入るかどうかはバイトオーダーによる。 x86系システムなら0x04030201になるでしょう。 意図した値を得るなら X=Z[0]*0x1000000+Z[1]*0x10000+Z[2]*0x100+Z[3]; が妥当でしょうね。

zero-spica
質問者

お礼

ご回答ありがとうございます。 実はこれらのコードは 8bit のマイコン上で動かすもので、可能な限り少ないクロックで処理したいという狙いもあります。 ビットシフトで近いことが出来ますので、ユニオンがうまくいかない場合参考にさせて頂きたいと思います。

回答No.3

一応、「共用体」という機能があります。 #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 が出力されるかもしれません。 (この順番は、処理系依存なので、確認が必要です)

zero-spica
質問者

お礼

ご回答ありがとうございます。 ユニオンを使った方法を提供して頂いたコード例を参考に検証してみたいと思います。

noname#190876
noname#190876
回答No.2

そういう場合は、union を使うという手があります。ただし、unionを使う方法は、使っているマシンのバイト並び(little endian or big endian)によって、異なる結果となります。

zero-spica
質問者

お礼

ご回答ありがとうございます。 ユニオンについて少し調べてみました。 参考にしてみたいと思います。

関連するQ&A