2

これは配列を数値に変換する安全な方法ですか?

// 23 FD 15 94 -> 603788692
char number[4] = {0x94, 0x15, 0xFD, 0x23};
uint32_t* n = (uint32_t*)number;
printf("number is %lu", *n);

より詳しい情報

私はLSBアーキテクチャの組み込みデバイスでそれを使用していますが、移植可能である必要はありません。私は現在シフトを使用していますが、このコードが安全であれば、私はそれを好みます。

4

3 に答える 3

3

いいえ、安全ではありません。

これは、オブジェクトはそれ自体の型、符号付き/符号なしバリアント、または文字型を介してのみアクセスできるという C エイリアス規則に違反しています。また、アラインメントを解除することで、未定義の動作を呼び出すこともできます。

配列から値を取得する安全な解決策は、uint32_t値に対してビット単位の演算子 (<<および&)を使用しcharて を形成することuint32_tです。

于 2013-10-05T11:27:38.797 に答える
3

いいえ。整数である場合にのみ、整数として何かにアクセスできます 。

しかし、ロジックを逆にするだけで、オブジェクトのバイナリ表現を操作する方法を次に示します。

uint32_t n;

unsigned char * p = (unsigned char *)&n;

assert(sizeof n == 4);    // assumes CHAR_BIT == 8

p[0] = 0x94; p[1] = 0x15; p[2] = 0xFD; p[3] = 0x23;

教訓: すべてのオブジェクトを一連のバイトとして扱うことはできますが、任意の一連のバイトを特定のオブジェクトとして扱うことはできません。

さらに、型のバイナリ表現はプラットフォームに大きく依存するため、これから得られる実際の整数値はわかりません。基数 256 の数字から整数値を合成するだけの場合は、通常の数学を使用します。

uint32_t n = 0x94 + (0x15 * 0x100) + (0xFD * 0x10000) + (0x23 * 0x1000000);

これは完全にプラットフォームに依存せず、表現ではなく純粋にの観点から必要なものを表現します。コンパイラーに任せて、コードのマシン表現を生成してください。

于 2013-10-05T11:30:24.113 に答える
0

次のような方がよいでしょう (移植性が高くなります):

int n = (c[3]<<24)|(c[2]<<16)|(c[1]<<8)|c[0];

ここで、c はunsigned char 配列です。

于 2013-10-05T11:29:36.293 に答える