C++中的整数字节交换
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3916097/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Integer Byte Swapping in C++
提问by Rob S.
I'm working on a homework assignment for my C++ class. The question I am working on reads as follows:
我正在为我的 C++ 课做家庭作业。我正在研究的问题如下:
Write a function that takes an unsigned short int (2 bytes) and swaps the bytes. For example, if the x = 258 ( 00000001 00000010 ) after the swap, x will be 513 ( 00000010 00000001 ).
编写一个函数,它接受一个 unsigned short int(2 个字节)并交换字节。例如,如果交换后 x = 258 ( 00000001 00000010 ),则 x 将为 513 ( 00000010 00000001 )。
Here is my code so far:
到目前为止,这是我的代码:
#include <iostream>
using namespace std;
unsigned short int ByteSwap(unsigned short int *x);
int main()
{
unsigned short int x = 258;
ByteSwap(&x);
cout << endl << x << endl;
system("pause");
return 0;
}
and
和
unsigned short int ByteSwap(unsigned short int *x)
{
long s;
long byte1[8], byte2[8];
for (int i = 0; i < 16; i++)
{
s = (*x >> i)%2;
if(i < 8)
{
byte1[i] = s;
cout << byte1[i];
}
if(i == 8)
cout << " ";
if(i >= 8)
{
byte2[i-8] = s;
cout << byte2[i];
}
}
//Here I need to swap the two bytes
return *x;
}
My code has two problems I am hoping you can help me solve.
我的代码有两个问题希望你能帮我解决。
- For some reason both of my bytes are 01000000
- I really am not sure how I would swap the bytes. My teachers notes on bit manipulation are very broken and hard to follow and do not make much sense me.
- 出于某种原因,我的两个字节都是 01000000
- 我真的不确定如何交换字节。我的老师关于位操作的笔记非常破碎且难以理解,对我没有多大意义。
Thank you very much in advance. I truly appreciate you helping me.
非常感谢您提前。我真的很感谢你帮助我。
回答by nos
I think you're overcomplicating it, if we assume a short consists of 2 bytes (16 bits), all you need to do is
我认为你把它复杂化了,如果我们假设一个 short 由 2 个字节(16 位)组成,你需要做的就是
- extract the high byte
hibyte = (x & 0xff00) >> 8;
- extract the low byte
lobyte = (x & 0xff);
- combine them in the reverse order
x = lobyte << 8 | hibyte;
- 提取高字节
hibyte = (x & 0xff00) >> 8;
- 提取低字节
lobyte = (x & 0xff);
- 以相反的顺序组合它们
x = lobyte << 8 | hibyte;
回答by Evan Teran
It looks like you are trying to swap them a single bit at a time. That's a bit... crazy. What you need to do is isolate the 2 bytes and then just do some shifting. Let's break it down:
看起来您正试图一次交换一点。这有点……疯狂。您需要做的是隔离 2 个字节,然后进行一些移位。让我们分解一下:
uint16_t x = 258;
uint16_t hi = (x & 0xff00); // isolate the upper byte with the AND operator
uint16_t lo = (x & 0xff); // isolate the lower byte with the AND operator
Now you just need to recombine them in the opposite order:
现在你只需要以相反的顺序重新组合它们:
uint16_t y = (lo << 8); // shift the lower byte to the high position and assign it to y
y |= (hi >> 8); // OR in the upper half, into the low position
Of course this can be done in less steps. For example:
当然,这可以用更少的步骤完成。例如:
uint16_t y = (lo << 8) | (hi >> 8);
Or to swap without using any temporary variables:
或者不使用任何临时变量进行交换:
uint16_t y = ((x & 0xff) << 8) | ((x & 0xff00) >> 8);
回答by The Archetypal Paul
You're making hard work of that.
你正在努力工作。
You only neeed exchange the bytes. So work out how to extract the two byte values, then how to re-assemble them the other way around
您只需要交换字节。因此,研究如何提取两个字节值,然后如何以相反的方式重新组装它们
(homework so no full answer given)
(作业所以没有给出完整的答案)
EDIT: Not sure why I bothered :) Usefulness of an answer to a homework question is measured by how much the OP (and maybe other readers) learn, which isn't maximized by giving the answer to the homewortk question directly...
编辑:不知道我为什么要烦恼:) 作业问题答案的有用性是通过 OP(可能还有其他读者)学到的东西来衡量的,这并不能通过直接回答作业问题来最大化......
回答by Brian
Ugly implementation of Jerry's suggestion to treat the short as an array of two bytes:
Jerry 建议的丑陋实现将 short 视为两个字节的数组:
#include <iostream>
typedef union mini
{
unsigned char b[2];
short s;
} micro;
int main()
{
micro x;
x.s = 258;
unsigned char tmp = x.b[0];
x.b[0] = x.b[1];
x.b[1] = tmp;
std::cout << x.s << std::endl;
}
回答by Thomas Matthews
Here is an unrolled example to demonstrate byte by byte:
这是一个逐字节演示的展开示例:
unsigned int swap_bytes(unsigned int original_value)
{
unsigned int new_value = 0; // Start with a known value.
unsigned int byte; // Temporary variable.
// Copy the lowest order byte from the original to
// the new value:
byte = original_value & 0xFF; // Keep only the lowest byte from original value.
new_value = new_value * 0x100; // Shift one byte left to make room for a new byte.
new_value |= byte; // Put the byte, from original, into new value.
// For the next byte, shift the original value by one byte
// and repeat the process:
original_value = original_value >> 8; // 8 bits per byte.
byte = original_value & 0xFF; // Keep only the lowest byte from original value.
new_value = new_value * 0x100; // Shift one byte left to make room for a new byte.
new_value |= byte; // Put the byte, from original, into new value.
//...
return new_value;
}
回答by Jerry Coffin
While you cando this with bit manipulation, you can also do without, if you prefer. Either way, you shouldn't need any loops though. To do it without bit manipulation, you'd view the short
as an array of two char
s, and swap the two char
s, in roughly the same way as you would swap two items while (for example) sorting an array.
虽然您可以通过位操作来做到这一点,但如果您愿意,也可以不用。无论哪种方式,您都不需要任何循环。要在不进行位操作的情况下执行此操作,您可以将short
视为一个包含两个char
s的数组,然后交换两个char
s,其方式与在(例如)对数组进行排序时交换两个项目大致相同。
To do it with bit manipulation, the swapped version is basically the lower byte shifted left 8 bits or
d with the upper half shifted left 8 bits. You'll probably want to treat it as an unsigned
type though, to ensure the upper half doesn't get filled with one bits when you do the right shift.
为了通过位操作来实现,交换版本基本上是低字节左移 8 位or
d,上半部分左移 8 位。不过,您可能希望将其视为一种unsigned
类型,以确保在进行右移时不会填充上半部分。
回答by Kenny Cason
This should also work for you.
这也应该对你有用。
#include <iostream>
int main() {
unsigned int i = 0xCCFF;
std::cout << std::hex << i << std::endl;
i = ( ((i<<8) & 0xFFFF) | ((i >>8) & 0xFFFF)); // swaps the bytes
std::cout << std::hex << i << std::endl;
}
回答by Poorna
#include <stdio.h>
int main()
{
unsigned short a = 258;
a = (a>>8)|((a&0xff)<<8);
printf("%d",a);
}
回答by Skizz
This is a problem:
这是个问题:
byte2[i-8] = s;
cout << byte2[i];//<--should be i-8 as well
This is causing a buffer overrun.
这会导致缓冲区溢出。
However, that's not a great way to do it. Look into the bit shift operators << and >>.
但是,这不是一个很好的方法。查看位移运算符 << 和 >>。
回答by don bright
A bit old fashioned, but still a good bit of fun.
有点老式,但仍然很有趣。
XOR swap: ( see How does XOR variable swapping work?)
XOR 交换:(请参阅XOR 变量交换如何工作?)
#include <iostream>
#include <stdint.h>
int main()
{
uint16_t x = 0x1234;
uint8_t *a = reinterpret_cast<uint8_t*>(&x);
std::cout << std::hex << x << std::endl;
*(a+0) ^= *(a+1) ^= *(a+0) ^= *(a+1);
std::cout << std::hex << x << std::endl;
}