假设我有一个6个字节的unsigned char
数组
并且一些函数会修改其中的值。如何从0-19bit
检索修改后的值?
void my_func()
{
unsigned char tempVal[6] = { 0,0,0,0,0,0}
unsigned char* temPtr = &temVal; // Say I am using pt
int newVal;
// call external function to modify value
// fun below assign new values to tempVal[0].. till tempVal[5].
void someFuncTomodifyVal( tempPtr );
// Now I want values from say 1st19bits
// how would I achieve that? I know I have to use And condtion with 7FFFF
// so say somthing like
newValue = *tempPtr & 0x7FFFF // but then *tempPtr will give me first byte only?
}
所以我的问题是我应该给出什么而不是*tempPtr
来获得前19位
的例子
void someFuncTomodifyVal( unsigned char m[] )
{
m[0] = 'some value retrieve from other funct'
m[1] = ' values based on some cal'
m[2] = ' values based on some cal'
}
答案 0 :(得分:1)
这里的主要问题是你不能将指针指向unsigned char
并将其粗略地转换为更大的指针类型。这将导致严格的别名冲突 - 未定义的行为。这可能会错误生成代码和类似的恶意错误。
要躲避它并通过指针访问数组,您可以使用其成员中包含相同类型的容器类型:
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <inttypes.h>
typedef union
{
unsigned char u8 [6];
uint32_t u32;
} my_union_t;
int main()
{
unsigned char tempVal[6] = { 0x11,0x22,0x33,0x44,0x55,0x66};
my_union_t* mu = (my_union_t*)tempVal;
printf("%"PRIx32"\n", mu->u32 & 0x7FFFF);
}
至于它将打印什么,它取决于CPU的endianess - 代码不可移植。在我的32位小端CPU上,我得到32211
。
答案 1 :(得分:-1)
你可能想要达到这样的目的:
#include <stdio.h>
#include <stdint.h>
int main(void)
{
unsigned char tempVal[6] = { 0x1,0x2,0x3,0x4,0,0 };
uint32_t *temPtr = (uint32_t *)tempVal; // Say I am using pt
uint32_t newVal = *temPtr;
printf("%08x\n", newVal);
newVal &= 0x7ffff;
printf("%08x\n", newVal);
}
在小端系统上,输出将为:
04030201
00030201
在大端系统上,输出将为:
01020304
01020304
请注意,这是不可移植,因为它取决于目标系统的字节顺序,也违反了strict aliasing rule
便携且正确的解决方案:
#include <stdio.h>
#include <stdint.h>
int main(void)
{
unsigned char tempVal[6] = { 0x1,0x2,0x3,0x4,0,0 };
uint32_t value = 0;
for (int i = 0; i < 4; i++)
{
value <<= 8;
value |= tempVal[i];
}
printf("%08x\n", value);
value &= 0x7ffff;
printf("%08x\n", value);
}
答案 2 :(得分:-2)
错误回答
您可以使用可以存储19位的类型。示例:uint32_t *n = (uint32_t *) tempVal;
。现在,您可以获得所需的位(*n) & 0x7FFFF
答案好
您可以使用union来尊重严格的别名:
union foo {
unsigned char tmp[6];
unsigned int n;
};