使用char指针读取int值并返回它

时间:2015-04-03 05:31:26

标签: c function pointers char return-value

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个不同的整数变量来节省大量内容吗?有没有更好的方法来编写这个函数。谢谢你的时间。

4 个答案:

答案 0 :(得分: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)
         );
} 

答案 1 :(得分:0)

首先,删除b3,因为你显然有意读24位,你甚至不应该尝试访问那个额外的字节(如果它甚至没有被分配?)。

其次,我认为你的轮班错了。 b0将始终在[0..255]范围内,因此如果您> gt;&gt; 24,它变为零。还没有必要掩盖任何东西,因为你来自无符号字符,你知道你只有8位设置。您可能想要:

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

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

取决于数据的字节顺序。

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

答案 2 :(得分:0)

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

如果你想要的只是char *字节集的int *版本,你可以使用类型转换:

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

如果你想要相同的字节集合,但是你希望最重要的字节等于0,那么你可以这样做:

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

其他一些信息:

- 类型转换是一种临时&#34;铸造&#34;一个变量,你想要的任何类型,你可以通过使用一个临时副本,你可以将变量转换为你可以使变量充当你想要的任何类型的变量: 例如:

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 - &gt; 8字节数据

0x表示每个占位符都是十六进制值 我认为你要的是0x000F,这将使除了最低有效字节

之外的所有其他字节为0

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

希望这有帮助!

答案 3 :(得分:0)

从单个指针构建数字时,必须将数字向左移动,同时将值Or加在一起。 (适用于小端机器)。在您阅读b0之后,可以这样想,这将是您最终数字中最不重要的字节。更重要的字节在哪里? (向左转)。

当您将指针值读入b0, b1, b2, b3时,它们所持有的每个都是一个字节。他们无法知道他们来自原始号码的位置,因此不需要“相对”转移。您只需从最低有效字节开始,然后将每个连续字节向左递增移位比最后一个字节多1个字节。

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

#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