Say I have an unsigned char (or byte) array. I want to take array[1] and array[2] from memory and cast it as short int (2 bytes). Something similar to how a union works, but not starting from the first byte.
Example:
#include <stdio.h>
void main()
{
unsigned char a[28];
unsigned short t;
a[0]=12;
a[1]=10;
a[2]=55;
t=(short) *(a+1);
printf("%i", t);
}
What I want is the value 14090 in decimal. Or 370Ah.
Thank you.
EDIT: I forgot to say, but most of you understood from my example, I am working on a little-endian machine. An 8bit Atmel microcontroller.
It's very simple:
unsigned short t = (a[2] << 8) | a[1];
Note, this assumes unsigned char
is 8 bits, which is most likely the case.
The memory access operation (short)*(a+1)
is not safe.
If a+1
is not aligned to short
(ie, a+1
is not a multiple of sizeof short
), then the result of this operation depends on the compiler at hand.
Compilers that support unaligned load/store operations can resolve it correctly, while others will "round it down" to the nearest address which is aligned to short
.
In general, this operations yields undefined behavior.
On top of all that, even if you know for sure that a+1
is aligned to short
, this operation will still give you different results between Big-Endian architecture and Little-Endian architecture.
Here is a safe way to work-around both issues:
short x = 0x1234;
switch (*(char*)&x)
{
case 0x12: // Big-Endian
t = (a[1] << 8) | a[2]; // Simulate t = (short)*(a+1) on BE
break;
case 0x34: // Little-Endian
t = (a[2] << 8) | a[1]; // Simulate t = (short)*(a+1) on LE
break;
}
Please note that the code above assumes the following:
CHAR_BIT == 8
sizeof short == 2
This is not necessarily true on every platform (although it is mostly the case).
t= *(short *)(a+1);
You cast the pointer to the first element to a pointer-to-short, and then dereference it.
Note that this is not very portable, and can go wrong if the machine is big endian or aligns data somehow. A better way would be:
t = (a[2] << CHAR_BIT) | a[1];
For full portability, you should check your endianness and see which byte to shift, and which one not to. See here how to check a machine's endianness
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.