Обмен байтов в C (порядковый номер) - PullRequest
2 голосов
/ 24 февраля 2010

Я пытаюсь поменять байты для назначения, и я подумал, что это будет способ сделать это.

p указывает на скалярный объект, который нужно повернуть размер - это число байтов объекта.

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

Что-то явно не так с ним? Я получил ошибку с тестовым кодом моего профессора:

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

Ответы [ 4 ]

4 голосов
/ 24 февраля 2010

Здесь

char *head = (char *)&p;

вы определяете указатель, который указывает на другой указатель. Таким образом, у вас есть указатель -> указатель -> байт, который явно не то, что вы хотите. К счастью, программа не вылетела.

Это должно быть char *head = (char *)p;, чтобы каждый байт читался из памяти, на которую указывает p.

2 голосов
/ 24 февраля 2010

p - переменная-указатель (то есть переменная, которая содержит адрес памяти чего-либо) и в следующей строке:

char *head = (char *)&p;

... вы используете &p, который дает вам адрес самой переменной-указателя, а не значение адреса памяти , которое содержит переменная-указатель (указывает на).

Вы хотели сделать это вместо этого?

char *head = (char *)p;

Кстати, ваш исходный код выглядит в обратном порядке всей строки, например, "Hello" -> "olleH" (если я не читаю это неправильно)

Это не то же самое, что обратить порядковый номер . Термин endian обычно относится к многобайтовому значению, которое сначала сохраняется с самым старшим или наименее значимым байтом.

Например, десятичное значение 43981 выражается в шестнадцатеричном виде как ABCD. В big-endian самый старший байт (AB) будет храниться в нижней ячейке памяти, а младший байт (CD) будет храниться в старшей ячейке памяти.

В little-endian , порядок обратный; наименее значимый, сопровождаемый наиболее значимым: CDAB.

1 голос
/ 24 февраля 2010

char *head = (char *)&p должно быть char *head = (char *)p

0 голосов
/ 24 февраля 2010

Вы не должны брать адрес p

Это должно работать:

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