C 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

我正在尝试为分配反转64位地址指针的字节,并获得以下代码:

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);
}