2016-05-25 3 views
2

私はuint8_tの4バイト配列(データ)を持っています。これは速度データの整数を表しています。この配列をuint32_t整数(速度)にキャストしようとしていますが、この速度に10を掛けてから4バイトの配列(データ)に戻してください。データ形式は以下のコードで明確です。バイト配列を整数に変換する

"assignment to expression with array type"

コード: 私は常にエラーを取得

volatile uint8_t data[4] = {0x00 , 0x00, 0x00, 0x00}; 
volatile uint32_t speed; 
speed=(uint32_t)*data; 
speed=speed*10; 
data=(uint8_t*)speed; 
+0

'* data'は実質的に' data [0] 'と同等です。明らかにそれは動作しません。 –

+0

'volatile uint8_t data [4]'は静的配列です。この配列の名前を式で使用すると、その型のポインタに崩壊する 'prvalue'という意味になります。 'data =(uint8_t *)スピード;' –

+0

おそらくspeed =(uint32_t)*データの代わりにspeed = *(uint32_t *)データを書きます。 –

答えて

5

は、あなたのコードは動作しませんdata=(uint8_t*)speed;中にあなたがデータのための「左辺値」を得ることはありませんので、あなただけの譲渡またはいずれにも使用することができない配列型を取得算術の形式。同様に、speed=(uint32_t)*data;はバグです。なぜなら、それは配列の最初の項目だけを与えるからです。

あなたがこれを行う必要がある唯一の正しい方法:

volatile uint8_t data[4] = {0x00 , 0x00, 0x00, 0x00}; 
volatile uint32_t speed; 

speed = (uint32_t)data[0] << 24 | 
     (uint32_t)data[1] << 16 | 
     (uint32_t)data[2] << 8 | 
     (uint32_t)data[3] << 0; 

speed=speed*10; 

data[0] = (uint8_t) ((speed >> 24) & 0xFFu); 
data[1] = (uint8_t) ((speed >> 16) & 0xFFu); 
data[2] = (uint8_t) ((speed >> 8) & 0xFFu); 
data[3] = (uint8_t) ((speed >> 0) & 0xFFu); 

これは100%ポータブルと明確に定義されたコードです。暗黙のプロモーションは行われません。このコードは、エンディアンや実装定義のその他の動作に依存しません。コードを記述するのはなぜですか、コードを書くことができないときは?

+0

その他の現在の回答は、バグにつながる危険な方法や移植性のない方法を示唆しています。あなたが上記の方法を除いて何かを行うべきである理由はありません。構造体、共用体、memcpy、追加、ポインタ変換、その他のナンセンスは忘れてしまいます。 – Lundin

+0

(何らかの理由で 'volatile'が何らかの理由で操作中に保存することが重要である場合、キャストは揮発性の修飾型も使用する必要があります) – Lundin

+0

私の個人的な文化のために、なぜこの場合はbit-or? – Garf365

6

は、ポータブルかつ安全な安全応じエンディアン、であるために、あなたはあなたのデータを再作成する必要があります。

speed = ((uint32_t)data[0]) << 24 
     | ((uint32_t)data[1]) << 16 
     | ((uint32_t)data[2]) << 8 
     | ((uint32_t)data[3]); 

または

speed = ((uint32_t)data[3]) << 24 
     | ((uint32_t)data[2]) << 16 
     | ((uint32_t)data[1]) << 8 
     | ((uint32_t)data[0]); 

チューあなたは直接の配列代入することはできませんので、あなたがエラー「配列型を持つ式に代入」を取得


最上位バイトの南東ソリューション応じてポジション:data=(uint8_t*)speed;は完全にCで禁止されている、あなたは明確にすることはできません左辺の配列。最上位バイトの位置に従って、

data[0] = (uint8_t)((speed >> 24) & 0x00FF); 
data[1] = (uint8_t)((speed >> 16) & 0x00FF); 
data[2] = (uint8_t)((speed >> 8) & 0x00FF); 
data[3] = (uint8_t)(speed & 0x00FF); 

か:あなたは逆の操作を行う必要があり

data[3] = (uint8_t)((speed >> 24) & 0x00FF); 
data[2] = (uint8_t)((speed >> 16) & 0x00FF); 
data[1] = (uint8_t)((speed >> 8) & 0x00FF); 
data[0] = (uint8_t)(speed & 0x00FF); 

EDITを

はに言及としてキャストやmemcpyを使用しないでください 解説と元の答え:非移植性の問題に加えて、整列の制約とaliによると、セキュリティの問題が発生しますいくつかのプラットフォームでは、コンパイラが間違ったコードを生成する可能性があります - user694733 | hereを参照してください - ランディン

のおかげで
speed = *((uint32_t *)data); // DANGEROUS NEVER USE IT 
    *((uint32_t *)data) = speed; // DANGEROUS NEVER USE IT 
+0

std :: uint32_tはC++ではありません... uint32_tだけがCのように見えます –

+0

@ StianSkjelstadはいそれはあります! – Garf365

+0

'speed = *((uint32_t *)data);'は十分な配置制限を持つプラットフォームでは失敗し、厳密な別名規則も破ります(コンパイラが不正なコードを生成する可能性があります)。代わりに 'memcpy'を使用してください。 – user694733

関連する問題