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个不同的整数变量来节省大量内容吗?有没有更好的方法来编写这个函数。谢谢你的时间。
答案 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,这将使除了最低有效字节
之外的所有其他字节为0ANSI-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