读取指针到unsigned char数组的位

时间:2017-09-07 13:21:24

标签: c

假设我有一个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'
}

3 个答案:

答案 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;
};