Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
960 views
in Technique[技术] by (71.8m points)

c - Converting bytes array to integer

I have a 4-byte array (data) of type uint8_t, which represents a speed data integer. I'm trying to cast this array to uint32_t integer (speed), multiply this speed by 10 and then restore it back to the 4-byte array (data). The data format is clear in the code below. I always get the error:

"assignment to expression with array type"

The code:

volatile uint8_t data[4] = {0x00 , 0x00, 0x00, 0x00};
volatile uint32_t speed;
speed=( uint32_t)*data;
speed=speed*10;
data=(uint8_t*)speed;
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To be safe according endianess, portable and secure, you should recreate your data:

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

or

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

Choose solution according position of most significant byte


You get an "assignment to expression with array type" error because you can't assign directly an array: data=(uint8_t*)speed; is totally forbidden in C, you definitively can't have an array for lvalue. You have to do inverse operation:

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);

or, according position of most significant byte:

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

Don't use cast or memcpy as mention in commentaries and original answer: in addition of non portability issues, you will have security issues, according alignment restrictions and aliasing rules on some platform, compiler can generate incorrect code - thanks to user694733 | see here - thanks to Lundin

    speed = *((uint32_t *)data); // DANGEROUS NEVER USE IT
    *((uint32_t *)data) = speed; // DANGEROUS NEVER USE IT

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...