2015-04-03 156 views
0
static unsigned int read24(unsigned char *ptr) 
{ 
    unsigned int b0; 
    unsigned int b1; 
    unsigned int b2; 
    unsigned int b3; 

    b0 = *ptr++; 
    b1 = *ptr++; 
    b2 = *ptr++; 
    b3 = *ptr; 

    return (((b0 >> 24) & 0x000000ff) | 
      ((b1 >> 8) & 0x0000ff00) | 
      ((b2 << 8) & 0x00ff0000) | 
      (b3 << 24) & 0x00000000  // this byte is not important so make it zero 
     ); 

} 

在这里,我写了一个功能,我试图用字符指针读取32位(4字节),并返回的32位(4字节)。我有个疑问如果这将正常工作。另外,我是通过定义4个不同的整数变量来使用/浪费太多的内存吗?有没有更好的方法来编写这个函数。感谢您的时间。使用字符指针读取一个int值,并将其返回

+0

我认为它会返回'1'或者'0'。 – Himanshu 2015-04-03 05:34:26

+0

'read24'与“* ...试图读取32位*”:请解释。 – alk 2015-04-03 09:21:44

+0

我读了4个字节......但我让最后一个字节为零,因为它对我来说不是那么重要.....最后我返回返回4byte值......这实际上就像0x 00xxxxxx ...因此read24 – 2015-04-03 10:02:45

回答

0

考虑使用你的任务以下方法:

#include <string.h> 

unsigned int read24b(unsigned char *ptr) 
{ 
    unsigned int data = 0; 
    memcpy(&data, ptr, 3); 
    return data; 
} 

这是情况下,如果你要位的直接命令,但我想你不...

关于你的代码 - 你必须敷面膜,然后进行转移,如:

unsigned int read24(unsigned char *ptr) 
{ 
    unsigned char b0; 
    unsigned char b1; 
    unsigned char b2; 

    b0 = *ptr++; 
    b1 = *ptr++; 
    b2 = *ptr; 

    return ((b0 & 0x0ff) >> 16 | 
      (b1 & 0x0ff) >> 8 | 
      (b2 & 0x0ff) 
     ); 
} 
+0

这个假设您的平台排序与输入数据相匹配。它还会对如果从int重写三个字节并假定sizeof(int)> = 3'发生什么情况做出不可移植的假设。 – bdonlan 2015-04-03 06:07:24

+0

@voland - 这里int的大小是4字节...我也看到你已经声明b0为unsigned char,并且我使用了unsigned int ...你的意思是建议我应该使用unsigned char吗? – 2015-04-03 08:03:43

+0

@tapanchawda:使用*运算符从(无符号字符*)读取数据时,我更喜欢使用unsigned char类型的数据。当我做类似'b0&0x0ff'的结果时,由于类型为'0x0ff'和类型提升 – VolAnd 2015-04-03 09:07:11

0

首先,降B3,因为你显然意味着读取24位,你甚至不应该试图访问一个额外的字节(如果它没有吨甚至分配?)。

其次,我认为你有你的错位。 b0将始终在[0..255]的范围内,所以如果>> 24,它将变为零。也没有必要掩盖任何东西,因为你来自unsigned char,你知道你只会设置8位。你可能想要么:根据您的数据的字节序

return (b0 << 16) | (b1 << 8) | b2; 

return (b2 << 16) | (b1 << 8) | b0; 

。至于使用这些中间整数,如果你有一个体面的编译器,它不会有问题(编译器会优化它们)。但是,如果您正在为嵌入式平台编写代码,或者编译器的编译状态不足,则可能会忽略中间整数,这可能有助于您的性能。在这种情况下,不要在同一语句中放置多个ptr++,而应使用ptr[n]来避免多个增量中的未定义行为。

+0

是的,我写的是一个嵌入式平台..我可以使用ptr [n]而不是ptr ++。你能帮我一下吗 – 2015-04-03 08:08:55

0

那么,我不太清楚你想要做什么。如果我没有弄错,你想输入一个char *(如果你正在运行一个32位系统,最有可能是4个字节),并得到与int相同的字节组织*(4字节)

如果你全部要的是整型*一个char *字节集可以使用的类型转换的版本:

unsigned int* result = (unsigned int*)ptr; 

如果你想了相同的字节集合,但你最想要的显著字节等于0,那么你可以做到这一点:

unsigned int* result = (unsigned int*)ptr & 0x0FFF; 

一些额外的信息:

- 类型转换暂时“铸造”的方法的变量,你通过使用的临时副本是你的变量铸造你的类型想要的任何类型的可做一个变量的行为,只要你想,如果你强制转换的任何类型: 例子:

unsigned int varX = 48; 
//Prints "Ascii decimal value 48 corresponds with: 0" 
printf ("Ascii decimal value 48 corresponds with: %c\n", (char)varX); 

-Hexidicamal数字占据每一个字节。因此,在你的代码:

0x000000ff - > 8个字节的数据

0X意味着每个占位的是一个十六进制值, 我想你所追求的是0x000F,这将让所有的其它字节0除了至少显著字节

ANSI-C可以处理十六进制(前缀 - > 0X),八进制(前缀 - > 0)和十进制

希望这有助于!

0

当从单个指针构建您的号码时,您必须将这些数值向左递增,因为您将这些值递增在一起。 (用于小端机器)。在阅读b0之后,可以这样想,这将是最终号码中最不重要的字节。更重要的字节在哪里? (往左边)。

当您将指针值读入b0, b1, b2, b3时,它们全部保持为每个一个字节。他们无法知道他们来自哪里的原始号码,所以不需要“相对”转移。您只需从最低有效字节开始,并逐渐将每个连续字节向左移动比最后一个字节多1个字节。

下面,我用无符号字符指针的无符号值作为示例,使用了所有字节。您可以简单地忽略不需要的字节以满足您的需求。

#include <stdio.h> 
#include <stdlib.h> 

#if defined(__LP64__) || defined(_LP64) 
# define BUILD_64 1 
#endif 

#ifdef BUILD_64 
# define BITS_PER_LONG 64 
#else 
# define BITS_PER_LONG 32 
#endif 

char *binstr (unsigned long n); 
static unsigned int read24 (unsigned char *ptr); 

int main (void) { 

    unsigned int n = 16975631; 
    unsigned int o = 0; 

    o = read24 ((unsigned char *)&n); 

    printf ("\n number : %u %s\n", n, binstr (n)); 
    printf (" read24 : %u %s\n\n", o, binstr (o)); 

    return 0; 
} 

static unsigned int read24 (unsigned char *ptr) 
{ 
    unsigned char b0; 
    unsigned char b1; 
    unsigned char b2; 
    unsigned char b3; 

    b0 = *ptr++; /* 00001111000001110000001100000001 */ 
    b1 = *ptr++; /* b0  b1  b2  b3  */ 
    b2 = *ptr++; /* b3  b2  b1  b0  */ 
    b3 = *ptr; /* 00000001000000110000011100001111 */ 

    return ((b0 & 0x000000ffU)   | 
      ((b1 << 8) & 0x0000ff00U) | 
      ((b2 << 16) & 0x00ff0000U) | 
      ((b3 << 24) & 0xff000000U)); 
} 

/* simple return of binary string */ 
char *binstr (unsigned long n) 
{ 
    static char s[BITS_PER_LONG + 1] = {0}; 
    char *p = s + BITS_PER_LONG; 

    if (!n) { 
     *s = '0'; 
     return s; 
    } 

    while (n) { 
     *(--p) = (n & 1) ? '1' : '0'; 
     n >>= 1; 
    } 
    return p; 
} 

输出

$ ./bin/rd_int_as_uc 

number : 16975631 1000000110000011100001111 
read24 : 16975631 1000000110000011100001111