在C字节反转顺序

问题描述 投票:0回答:5

这已经相当困难。我提取比特收集来自无符号字符数组的信息。还有一个部分,我被困在。该阵列具有这四个字节: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);
}
c arrays sorting
5个回答
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. 您需要调换*start*end的值。
  2. 您需要通过i在循环递减2。否则,你将重新交换价值。
  3. 通过您打印的价值的时候,你已经增加start,使其不指向它是函数被调用时。

以下是我想出了:

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

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

0
投票

您的反向代码无法正常工作。

使用一个临时变量:

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

你也只能做一半的迭代,所以在你的情况下,在功能reverse_order i()是2

该函数的自变量端不必要的,因为你必须为4的硬编码长度计算而是在功能端

unsigned char* end = star + 3 ;

0
投票

还有就是允许交换两个变量不使用临时这个漂亮的XOR招:

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

它可能不是更快,最有可能需要一些意见,但它总是好的,以显示你如何知道你的逐位逻辑;)

© www.soinside.com 2019 - 2024. All rights reserved.