Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 位交换和指针_C++_Byte_Swap_Endianness - Fatal编程技术网

C++ 位交换和指针

C++ 位交换和指针,c++,byte,swap,endianness,C++,Byte,Swap,Endianness,我有一个结构,它由多个32位元素组成。我应用了一个#pragma包(4),因此下面的结构是线性和对齐的 struct { int a; // 4 bytes int b; // 4 bytes int c; // 4 bytes } mystruct; // total 16 bytes 如何交换这些元素(little->big endian) 方法是void交换(void*a,int-b),其中a指针指向结构,而b整数给出结构的大小 例如: void swap(void* a,

我有一个
结构
,它由多个32位元素组成。我应用了一个
#pragma包(4)
,因此下面的结构是线性和对齐的

struct
{
  int a; // 4 bytes
  int b; // 4 bytes
  int c; // 4 bytes
} mystruct; // total 16 bytes
如何交换这些元素(little->big endian)

方法是
void交换(void*a,int-b)
,其中
a
指针指向结构,而
b
整数给出结构的大小

例如:

void swap(void* a, int b)
{
  //FIXME !
  for (int i = 0; i < b; i+= 32)
  {
    a = (a & 0x0000FFFF) << 16 | (a & 0xFFFF0000) >> 16;
    a = (a & 0x00FF00FF) << 8 | (a & 0xFF00FF00) >> 8;
    a += 32;
  }
}
void交换(void*a,int-b)
{
//修理我!
对于(int i=0;i16;
a=(a&0x00FF00FF)>8;
a+=32;
}
}

这里有一个可能的例程修复程序

void swap(void* a, int b)
{
  for (int i = 0; i < b; i += 4)
  {
    int* p = (char*)a + i;
    *p = (*p & 0x0000FFFF) << 16 | (*p & 0xFFFF0000) >> 16;
    *p = (*p & 0x00FF00FF) << 8 | (*p & 0xFF00FF00) >> 8;
  }
}
void交换(void*a,int-b)
{
对于(int i=0;i16;
*p=(*p&0x00FF00FF)>8;
}
}

未经测试,但希望更接近正确。

如果您使用的是基于*nix的机器。有一个有用的函数可以做到这一点:

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostint32);   // from host to network
                                      // means little to big if your machine is x86
#包括
uint32_t htonl(uint32_t hostin32);//从主机到网络
//如果您的机器是x86,则表示从小到大
无效交换(无效*A,内部b)
{
//修理我!
int*c=(int*)A;//必须强制转换为现有类型。“void”不存在
对于(inti=0;i>8扩展符号位
a=(a&0x0000FFFF)>16;
a=(a&0x00FF00FF)>8;
*c++=a;//写回内容
}
}
无论如何:我最喜欢用c或c类语言进行字节交换的方法是通过拷贝: 这个概念比内置函数的名称更容易记住


void swap(char*d,char*s,int N){for(i=0;i您可以在不使用临时

void byteswap( unsigned char & a, unsigned char & b )
{
   a ^= b;
   b ^= a;
   a ^= b;
}
现在,让我们将其应用于可变长度的数字

template< typename T >
void endianSwap( T & t )
{
    unsigned char * first = reinterpret_cast< unsigned char * >( &t );
    unsigned char * last = first + sizeof(T) - 1;
    while( first < last )
    {
       byteswap( *first, *last );
       ++first;
       --last;
    }
}
当然,作为使用byteswap的endianSwap的替代方法,我们可以使用std::reverse

template<typename T> endianSwap( T& t )
{
    unsigned char * begin = reinterpret_cast<unsigned char *>(&t);
    unsigned char * end = begin + sizeof( T );
    std::reverse( begin, end );
}
模板交换(T&T)
{
无符号字符*begin=重新解释强制转换(&t);
无符号字符*end=begin+sizeof(T);
标准::反向(开始、结束);
}

我假设little->big-endian是指颠倒每个4字节元素中字节的顺序。我还假设“
a
null指针在结构上”是指“
a
指针在结构上”。 您的代码中有一些错误。请尝试以下操作:

void swap(void* a, int b)
{
  for (int *pInt = (int *)a; pInt < ((char *)a + b); pInt++)
  {
    *pInt = (*pInt & 0x0000FFFF) << 16 | (*pInt  & 0xFFFF0000) >> 16;
    *pInt = (*pInt & 0x00FF00FF) << 8 | (*pInt & 0xFF00FF00) >> 8;
  }
}
void交换(void*a,int-b)
{
对于(int*pInt=(int*)a;pInt<((char*)a+b);pInt++)
{
*品脱=(*品脱和0x0000FFFF)>16;
*品脱=(*品脱和0x00FF00FF)>8;
}
}

元素d不是四个字节,而是一个字节。通过使用
#pragma pack(4)
您已强制编译器在元素d之后添加三个填充字节,但您的代码访问这些字节仍然是一个错误。
字符d[4]有什么问题吗
?@john post编辑,这不是我要找的。现在让我们假设结构仅由3个int组成。顺便说一句,您当前的pragma可能已经过时,因为一个满是
int
s的结构至少与
int
的对齐方式对齐,这很可能至少是4个字节。另一方面,我不明白您为什么要这样做让结构与16个字节对齐(除非您认为
#pragma pack
考虑的是元素而不是字节,当然不是字节)。你的意思是字节交换而不是位交换。endian更改是字节交换,而不是位。@ChristianRau结构没有满
int
,我清理了示例以使其更易于理解。当使用“对齐”时,我的意思是结构的元素在内存中相互跟随。这段代码假设大小b是以整数为单位的大小。可能是对的,但我认为更可能是以字节为单位的大小。如果你想交换到big-endian。但是如果你想从大到小交换,该函数将不起作用。那又怎样?还有
ntohl
@Patouf Basi凯莉:是的。简而言之,还有另一个版本。是的,但是如果你在大端机平台上,换成小端机是不起作用的。当然,你可以用它作为小端机系统的实现。
template<typename T> endianSwap( T& t )
{
    unsigned char * begin = reinterpret_cast<unsigned char *>(&t);
    unsigned char * end = begin + sizeof( T );
    std::reverse( begin, end );
}
void swap(void* a, int b)
{
  for (int *pInt = (int *)a; pInt < ((char *)a + b); pInt++)
  {
    *pInt = (*pInt & 0x0000FFFF) << 16 | (*pInt  & 0xFFFF0000) >> 16;
    *pInt = (*pInt & 0x00FF00FF) << 8 | (*pInt & 0xFF00FF00) >> 8;
  }
}