C 64位值的反向字节数
我正在尝试为分配反转64位地址指针的字节,并获得以下代码:C 64位值的反向字节数,c,byte,reverse,swap,endianness,C,Byte,Reverse,Swap,Endianness,我正在尝试为分配反转64位地址指针的字节,并获得以下代码: char swapPtr(char x){ x = (x & 0x00000000FFFFFFFF) << 32 | (x & 0xFFFFFFFF00000000) >> 32; x = (x & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16; x = (x & 0x00FF0
char swapPtr(char x){
x = (x & 0x00000000FFFFFFFF) << 32 | (x & 0xFFFFFFFF00000000) >> 32;
x = (x & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16;
x = (x & 0x00FF00FF00FF00FF) << 8 | (x & 0xFF00FF00FF00FF00) >> 8;
return x;
}
长期以来:
*loc = swapLong(*loc);
您不能使用
char x
作为指针!!!!字符的长度只有一个字节
你至少需要
unsigned long int swapPtr(unsigned long int x) {
最好使用指针的类型
void* swapPtr(void* x) {
当您开始位移位指针时,编译器很可能会抱怨;在这种情况下,最好将参数显式转换为无符号64位整数:
#include <stdint.h>
uint64_t x;
not*loc
(它查看loc
指向的位置-值,而不是地址)
完整程序:
#include <stdio.h>
#include <stdint.h>
uint64_t swapLong(void *X) {
uint64_t x = (uint64_t) X;
x = (x & 0x00000000FFFFFFFF) << 32 | (x & 0xFFFFFFFF00000000) >> 32;
x = (x & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16;
x = (x & 0x00FF00FF00FF00FF) << 8 | (x & 0xFF00FF00FF00FF00) >> 8;
return x;
}
int main(void) {
char a;
printf("the address of a is 0x%016llx\n", (uint64_t)(&a));
printf("swapping all the bytes gives 0x%016llx\n",(uint64_t)swapLong(&a));
}
编辑您可以使用
#include <inttypes.h>
printf("the address of a is 0x%016" PRIx64 "\n", (uint64_t)(&a));
#包括
printf(“a的地址是0x%016“PRIx64”\n),(uint64_t)(&a));
其中,宏PRIx64扩展为“需要以十六进制打印64位数字的格式字符串”。它比上面的更简洁。这里有一种将64位值从LE转换为BE或从LE转换为BE的替代方法 通过定义
var\u type
:
typedef long long var_type;
void swapPtr(var_type* x)
{
char* px = (char*)x;
for (int i=0; i<sizeof(var_type)/2; i++)
{
char temp = px[i];
px[i] = px[sizeof(var_type)-1-i];
px[sizeof(var_type)-1-i] = temp;
}
}
var_type swapVal(var_type x)
{
var_type y;
char* px = (char*)&x;
char* py = (char*)&y;
for (int i=0; i<sizeof(var_type); i++)
py[i] = px[sizeof(var_type)-1-i];
return y;
}
按指针反转:
typedef long long var_type;
void swapPtr(var_type* x)
{
char* px = (char*)x;
for (int i=0; i<sizeof(var_type)/2; i++)
{
char temp = px[i];
px[i] = px[sizeof(var_type)-1-i];
px[sizeof(var_type)-1-i] = temp;
}
}
var_type swapVal(var_type x)
{
var_type y;
char* px = (char*)&x;
char* py = (char*)&y;
for (int i=0; i<sizeof(var_type); i++)
py[i] = px[sizeof(var_type)-1-i];
return y;
}
void swapPtr(变量类型*x)
{
char*px=(char*)x;
对于(int i=0;i您也可以使用\u bswap64内部(在Skylake体系结构上延迟为2,吞吐量为0.5)。它是汇编指令bswap r64
的包装器,因此可能是最有效的:
反转64位整数a的字节顺序,并将结果存储在dst中。此内在函数用于在小端值和大端值之间进行转换
#包括
uint64\u t交换内部(无效*X){
返回uu bswap_64((uint64_t)X);
}
注意:不要忘记标题char
不是正确的数据类型。它是(通常)一个8位字节。如果您在一个有64位字符的平台上,请提及。是的,它在x86_64体系结构上。一个字符是8位。它不可能有64位的值。只是不要为这样的任务使用固定宽度的类型。合适的类型是uintpttr\u t
。此外,您可以“,如果UINTPRT\u SIZE>UINT32\u SIZE
”假设宽度是64位。@ JungGuStut感谢您的澄清。我没有意识到有一个<代码> uTutpTrtt\/Cord>——应该每天都要学习。小子:考虑<代码> PrimTf(“0x016”Prx64,(uTun64)(和A))< /C>或<代码> PrimTf(“0x%016Lxx\n”,(un签署long long)(& a))
而不是发布以获得匹配的格式和整数?@chux-这确实会更好。有几种方法可以改进这一点…当我靠近计算机(而不是电话)+1时可以这样做,以获得更好的通用解决方案。(如果想确保8位字节交换,可能是uint8\u t
而不是char
)谢谢你,chux。我很确定char
在标准中被定义为一个单字节。这不就是“映射”吗在LE和BE之间?换句话说,LE处理器上多字节字的字节顺序与BE处理器上的字节顺序相反,而不管单个字节的大小……正确吗?char
在C中是一个byte
,但在C中不一定是8位的byte
,它至少是8位,在C中,正好是8位。请参阅(也请参阅上面的注释)从定义上讲,LE和BE的顺序相反。但在BE/LE业务中,包括使用的平台在内,存在着微妙的可能性。我怀疑mixed-endian现在已经过时,回归的前景令人怀疑。注意:一些应用程序需要与各种串行通信交换位顺序。因此单个字节的大小是独立的由编译器和CPU体系结构定义(总是将字节称为8位单元)?奇怪……我认为定义16位字节的编译器将是为相同“类型”的底层体系结构指定的编译器。
#include <immintrin.h>
uint64_t swapLongIntrinsic(void *X) {
return __bswap_64((uint64_t) X);
}