颠倒c中的字节顺序

时间:2014-03-26 05:23:50

标签: c arrays sorting

这令人惊讶地困难。我正在提取位以从一组无符号字符中收集信息。我坚持了一部分。该数组包含以下四个字节:0x79,0xE8,0x39,0x1A,我需要将它们反转为0x1A,0x39,0xE8,0x79。我的reverse_order函数给了我0x59,0x4,0x89,0x10(这是数组中的其他字节):

#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>

#define LATITUDE_OFFSET 4
#define LONGITUDE_OFFSET 5

void reverse_order(unsigned char *start, unsigned char *end)
{
    int i = 4;
    do {
        *start = *end;
        ++start;
        --end;
        --i;
    } while(i > 0);
    int j;
    for(j=0; j<4; j++)
    {
        printf("the value: 0x%x\n", start[j]);
    }
}

int main(void)
{
    unsigned char msg[] = {
        0x28,0x83,0x63,0x20,0x79,
        0xE8,0x39,0x1A,0x59,0x04,
        0x89,0x10,0x8D,0x2E,0xF1,
        0x11,0x6E,0x00,0x10,0x8D,
        0x51,0x57,0x29,0x0D
    };  
    unsigned long long int time_secs;
    unsigned char *start, *end;

    int i, j;

    //remove garbage
    time_secs = 0;
    i = 0;      

    while(msg[i] == 0x28)
    {
        ++i;
    }

    unsigned char resp = ((msg[i] & 0xF) * 16) + 7;
    unsigned char resp2 = (msg[i] & 0xF);
    ++i;

    int unit_id_length = ((msg[i++] & 0xC0) >> 6)+1;

    int is_latitude_south = (msg[i] & 0x10) >> LATITUDE_OFFSET;
    int is_longitude_west = (msg[i] & 0x20) >> LONGITUDE_OFFSET;

    ++i;
    start = &msg[i];
    i+=3;
    end = &msg[i];      
    reverse_order(start, end);
}

5 个答案:

答案 0 :(得分:1)

以下是基于原始版本的reverse_order()的固定版本:

void reverse_order(unsigned char *start, unsigned char *end)
{
    int i = 2;
    int t;
    do {
        t = *start;
        *start = *end;
        *end = t;
        ++start;
        --end;
        --i;
    } while(i > 0);
    int j;
    start -= 2;
    for(j=0; j<4; j++)
    {
        printf("the value: 0x%x\n", start[j]);
    }
}

以下是修订版:

void
reverse(unsigned char *start, unsigned char *end)
{
    unsigned char t;

    while (start < end) {
        t = *start;
        *start = *end;
        *end = t;

        start++;
        end--;
    }
}

答案 1 :(得分:1)

我发现您的代码存在以下问题:

  1. 您需要交换*start*end
  2. 的值
  3. 您需要在循环中按i递减2。否则,您将重新交换值。
  4. 当您打印值时,您已经增加start,因此它不会指向调用该函数时的位置。
  5. 以下是我提出的建议:

    void reverse_order(unsigned char *start, unsigned char *end)
    {
        int i = 4;
        unsigned char cp;
        unsigned char* iter = start;
        int j;
    
        do {
            /* Swap the contents of *iter and *end */
            cp = *iter;
            *iter = *end;
            *end = cp;
            ++iter;
            --end;
            i -= 2;
        } while(i > 0);
        for(j=0; j<4; j++)
        {
            printf("the value: 0x%x\n", start[j]);
        }
    }
    

答案 2 :(得分:0)

您可以使用以下代码确定字节顺序:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
    union {
        short s;
        char c[sizeof(short)];
    }un;
    un.s = 0x0102;

    if (sizeof(short) == 2) {
        if (un.c[0] == 1 && un.c[1] == 2)
            printf("big-endian\n");
        else if (un.c[0] == 2 && un.c[1] == 1)
            printf("little-endian\n");
        else
            printf("unknown\n");
   } else{
        printf("sizeof(short) = %d\n", sizeof(short));
   }
   exit(0);
}

答案 3 :(得分:0)

您的反向代码无效。

使用临时变量:

unsigned char t = *start ;
*start = *end;
*end = t ;

你也只进行了一半的迭代,所以在你的情况下,函数reverse_order()中的i将是2

函数的参数结束是不必要的,因为你的硬编码长度为4.而不是在函数中计算结束

unsigned char* end = star + 3 ;

答案 4 :(得分:0)

有一个很好的XOR技巧,允许在不使用临时交换的情况下交换两个变量:

void reverse_order(unsigned char *start, unsigned char *end)
{
    while (end > start) {
        *start ^= *end;
        *end ^= *start;
        *start ^= *end;
        ++start;
        --end;
    };
}

它可能不会更快,很可能需要一些评论,但它总是很好地表明你学会了你的按位逻辑;)