I'm trying to swap bytes for an assignment, and I thought this would be the way to do it.
p points to the scalar object to be reversed size is the num开发者_运维知识库ber of bytes of the object.
void *ReverseEndian(void *p, size_t size)
{
char *head = (char *)&p;
char *tail = head + size - 1;
for (; tail > head; --tail, ++head) {
char temp = *head;
*head = *tail;
*tail = temp;
}
return p;
}
Is there something obviously wrong witht he above? I get an error with my professor's test code:
#define TestIt(a, b) TestReverse((void *)&(a),\
ReverseEndian((void *)&(b), sizeof(b)), sizeof(b))
int main()
char ch = 0x01, ch1 = ch;
short sh = 0x0123, sh1 = sh;
long lo = 0x01234567, lo1 = lo;
float fl = 1234.567e27F, fl1 = fl;
double db = 123456.567890, db1 = db;
long double ld = 987654.321053e-204L, ld1 = ld;
void *vp = (void *)0x0123, *vp1 = vp;
char *cp = (char *)0x4567, *cp1 = cp;
char *ip = (char *)0x89AB, *ip1 = ip;
TestIt(ch1, ch);
TestIt(sh1, sh);
TestIt(lo1, lo);
TestIt(fl1, fl);
TestIt(db1, db);
TestIt(ld1, ld);
TestIt(vp1, vp);
TestIt(cp1, cp);
TestIt(ip1, ip);
printf("ReverseEndian succeeded!\n");
return EXIT_SUCCESS;
}
void TestReverse(const void *before, const void *after, size_t size)
{
const char *cpBfore = (const char *)before;
const char *cpAfter = (const char *)after;
const char *tail;
for (tail = cpBfore + (size - 1); size; --size)
if (*tail-- != *cpAfter++)
{
fprintf(stderr, "ReverseEndian failed!\n");
exit(EXIT_FAILURE);
}
}
Here
char *head = (char *)&p;
you're defining a pointer that points to another pointer. So you have pointer -> pointer -> bytes which is obviously not what you want. Lucky the program didn't crash.
It must be char *head = (char *)p;
so that each byte will be read from the memory pointed to by p
.
p
is a pointer variable (i.e., a variable that holds a memory address of something), and in the following line:
char *head = (char *)&p;
...you're using &p
, which gives you the address of the pointer variable itself, rather than the memory address value that the pointer variable contains (points to).
Did you mean to do this instead?
char *head = (char *)p;
By the way, your source code appears to reverse the order of an entire string, e.g. "Hello" --> "olleH" (unless I'm reading it wrong)
That's not the same thing as reversing endianness. The term endian usually refers to a multi-byte value that is stored with the most- or least-significant byte first.
As an example, the decimal value 43981 is expressed in hex as ABCD
. In big-endian, the most-significant byte (AB
) would be stored in the lower memory location, and the least-significant byte (CD
) would be stored in the higher memory location.
In little-endian, the order is reversed; least-significant followed by most-significant: CDAB
.
char *head = (char *)&p
should be char *head = (char *)p
You shouldn't be taking the address of p
This should work:
void *ReverseEndian(void *p, size_t size)
{
char *head = (char *)p; // here
char *tail = head + size - 1;
for (; tail > head; --tail, ++head) {
char temp = *head;
*head = *tail;
*tail = temp;
}
return p;
}
精彩评论