从 char 数组中提取第二个和第三个值并将其转换为短(2 字节)。在 C 中
Extract 2nd and 3rd value from char array and cast it as short (2 bytes). In C
假设我有一个无符号字符(或字节)数组。我想从内存中获取 array[1] 和 array[2] 并将其转换为 short int(2 字节)。类似于联合的工作方式,但不是从第一个字节开始。
示例:
#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);
}
我要的是十进制的14090。或370Ah.
谢谢。
编辑:我忘了说,但是你们中的大多数人从我的示例中了解到,我正在使用小端机器。一个 8 位 Atmel 微控制器。
t= *(short *)(a+1);
您将指向第一个元素的指针转换为短指针,然后取消引用它。
请注意,这不是很便携,如果机器是大端或以某种方式对齐数据,可能会出错。更好的方法是:
t = (a[2] << CHAR_BIT) | a[1];
为了完全的可移植性,您应该检查您的字节顺序,看看要移动哪个字节,不要移动哪个字节。 See here how to check a machine's endianness
很简单:
unsigned short t = (a[2] << 8) | a[1];
注意,这假设 unsigned char
是 8 位,这很可能是这种情况。
内存访问操作(short)*(a+1)
不安全。
如果a+1
没有对齐到short
(即a+1
不是sizeof short
的倍数),那么这个操作的结果取决于编译器手边。
支持未对齐 load/store 操作的编译器可以正确解析它,而其他编译器将 "round it down" 到最近的地址, 对齐到 short
.
通常,此操作会产生未定义的行为。
最重要的是,即使你确定 a+1
是 对齐到 short
,这个操作仍然会给你不同的结果Big-Endian 架构和 Little-Endian 架构之间。
这是解决这两个问题的安全方法:
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;
}
请注意上面的代码假设如下:
CHAR_BIT == 8
sizeof short == 2
这不一定适用于每个平台(尽管大多数情况下都是如此)。
假设我有一个无符号字符(或字节)数组。我想从内存中获取 array[1] 和 array[2] 并将其转换为 short int(2 字节)。类似于联合的工作方式,但不是从第一个字节开始。
示例:
#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);
}
我要的是十进制的14090。或370Ah.
谢谢。
编辑:我忘了说,但是你们中的大多数人从我的示例中了解到,我正在使用小端机器。一个 8 位 Atmel 微控制器。
t= *(short *)(a+1);
您将指向第一个元素的指针转换为短指针,然后取消引用它。
请注意,这不是很便携,如果机器是大端或以某种方式对齐数据,可能会出错。更好的方法是:
t = (a[2] << CHAR_BIT) | a[1];
为了完全的可移植性,您应该检查您的字节顺序,看看要移动哪个字节,不要移动哪个字节。 See here how to check a machine's endianness
很简单:
unsigned short t = (a[2] << 8) | a[1];
注意,这假设 unsigned char
是 8 位,这很可能是这种情况。
内存访问操作(short)*(a+1)
不安全。
如果a+1
没有对齐到short
(即a+1
不是sizeof short
的倍数),那么这个操作的结果取决于编译器手边。
支持未对齐 load/store 操作的编译器可以正确解析它,而其他编译器将 "round it down" 到最近的地址, 对齐到 short
.
通常,此操作会产生未定义的行为。
最重要的是,即使你确定 a+1
是 对齐到 short
,这个操作仍然会给你不同的结果Big-Endian 架构和 Little-Endian 架构之间。
这是解决这两个问题的安全方法:
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;
}
请注意上面的代码假设如下:
CHAR_BIT == 8
sizeof short == 2
这不一定适用于每个平台(尽管大多数情况下都是如此)。