電子書籍の厳選無料作品が豊富!

uint32_t X;
uint8_t Z[4] = {0x01, 0x02, 0x03, 0x04};

X = *Z;

上記のような書き方をした場合、 X には 「0x01020304」という値が格納されるものと考えて良いのでしょうか?

A 回答 (5件)

そうじゃないですよ。



Z は、 uint8 へのポインタですから、

 Zのアドレスのさすuint8値をとってくる
その値をuint32 へ拡張する
 その結果を、Xにいれる

 ということで、Xには、0x01 がはいります。

 なお、C,C++では、変数名に大文字を使うのは、たいていの場合、コーディング規則違反となります。

この回答への補足

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

補足日時:2014/01/29 14:51
    • good
    • 0
この回答へのお礼

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

お礼日時:2014/01/29 13:06

処理系によってはアラインメント制約に引っかかって


X = *(uint32_t*)Z;
が動作しないことも考えられます. その場合の動作は未定義ですから, 突然鼻歌を歌いだしたとしても文句は言えません.

#4 の最後にあるように適切な式を使う以外は可搬性がありません.
    • good
    • 0
この回答へのお礼

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

お礼日時:2014/01/29 14:49

X = *(uint32_t*)Z;


とすれば一応32bit値を格納できるが、期待した値が入るかどうかはバイトオーダーによる。
x86系システムなら0x04030201になるでしょう。

意図した値を得るなら
X=Z[0]*0x1000000+Z[1]*0x10000+Z[2]*0x100+Z[3];
が妥当でしょうね。
    • good
    • 0
この回答へのお礼

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

お礼日時:2014/01/29 14:50

一応、「共用体」という機能があります。




#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 が出力されるかもしれません。
(この順番は、処理系依存なので、確認が必要です)
    • good
    • 0
この回答へのお礼

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

お礼日時:2014/01/29 14:50

そういう場合は、union を使うという手があります。

ただし、unionを使う方法は、使っているマシンのバイト並び(little endian or big endian)によって、異なる結果となります。
    • good
    • 0
この回答へのお礼

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

お礼日時:2014/01/29 14:50

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!