【问题标题】:function that takes a long value and returns with its bytes in reverse order in C在 C 中采用 long 值并以相反顺序返回其字节的函数
【发布时间】:2013-01-21 07:22:56
【问题描述】:

我正在做一个作业,要求我编写一个函数,该函数接受一个 long 值并在 C 中以相反的顺序返回其字节,给出了函数的原型,即

long swapLong(long x)

我的代码如下所示:

long swapLong(long in)
{
    long out;
    char *inp = (char *) &in ;
    char *outp = (char *) &out;

    int i=0;
    for (i=0; i<8 ;i++)
    {    
        outp[i] = inp[7-i]; 
    }

    return out;
} 

如果函数的输入是0x1122334455667788

它应该返回 0x8877665544332211

然而,当我用

测试它时
long test2 = 0x1122334455667788;
long result2= swapLong(test2);
printf("0x %lx\n", test2);
printf("0x %lx\n", result2);

结果是0x44332211

这个函数似乎只交换前半部分哦输入,我不知道后半部分会发生什么

我编写了另一个名为“int swapInt(int x)”的函数,使用与 swapLong() 类似的想法,效果很好....所以我不知道我对 swapLong() 做错了什么

【问题讨论】:

  • long 在您的机器上是 32 位类型吗?
  • 您应该使用stdint.h 中的uint64_t 类型。它保证是64位。除此之外,使用按位运算符进行字节交换。
  • 除了编辑之外,您还可以使用按位运算符解决此问题,这将帮助您避免违反严格的别名规则。查看htonl 的实现作为示例。
  • @TedWoo 在程序顶部添加#include &lt;stdint.h&gt;sizeof (long) 会告诉你有多少字节; i&lt;sizeof (long) 会比 i&lt;8 更好。
  • 阅读man endian:您可以使用其中的宏进行字节顺序转换。

标签: c pointers byte-shifting


【解决方案1】:

您可能希望使用sizeof(long)而不是8

...
size_t i;
size_t sizeLong = sizeof(long);
for (i=0; i<sizeLong ;i++)
{    
    outp[i] = inp[sizeLong-i-1]; 
}
...

【讨论】:

  • 如果 (-1) 不正确,则回滚该更改,但我很确定这是缺少的。循环中的第一个命中是从 `imp[sizeof(long)] 中提取低字节,这太多了。现在应该可以工作了(著名的遗言)。
  • 我又试了一下,结果还是0x44332211,还是看不到第二部分。
  • @TedWoo 帮自己一个忙,把它放在代码的顶部:printf("sizeof(long) = %lu\n", sizeof(long)); 从你显示的内容来看,你的 long 值只有 32 位长(这在32 位平台)。您在问题中说“结果是 0x44332211”。那将是 second printffirst printf 的结果是什么?应该是打印test2??original
  • @WhozCraig 我按照你说的做了,结果是“sizeof(long) = 8”,所以这不意味着我的 long 是 64 位吗?因为 1 个字节是 8 位
  • @TedWoo 这正是它的意思,因此我受阻。 Alk 的代码应该很容易正确地旋转你的字节。它确实是我的(但我知道我也有 64 位长:我输入 0x1122334455667788,我的结果是 0x8877665544332211,完全符合预期。)你的 long 在一个函数中是 64 位,而在另一个函数中是 32 位是完全奇怪的。并且原始值(test2)在之前的printf中打印全64位??
【解决方案2】:

您的代码在您给定的输入下在我的系统上运行良好。我很确定你的 long 是 32 位。

5分钟后我不能编辑我的评论,所以我会写在这里。

C 确保 int 必须至少与 short 一样大,long 必须至少与 int 一样大。因此,您的编译器会根据目标平台(处理器)选择最佳大小。

【讨论】:

  • 真的吗?所以这段代码的工作取决于不同类型的系统?那么如何将我的 long 更改为 64 位呢?感谢您的快速回复
  • @TedWoo 好吧,我怀疑你可以改变你的 long 。但是您可以使用 64 位类型的 uint64_t。只需在您的程序中包含 stdint.h 即可。如果你想和你的朋友一起玩,你可以做#define long uint64_t。在包括 stdint.h :P 之后。但这完全不推荐大声笑
【解决方案3】:

根据您的描述,您似乎忽略了截断常量值的警告

long test2 = 0x1122334455667788; // 1234605616436508552 &gt; 2^32-1

因为您的 long 似乎只有 32 位。

在循环中使用sizeof() 而不是8,它应该可以正常工作。

在你的程序开始时你可以写

assert( sizeof(long) == 4 ); // to see if it is 32-bit or not.

【讨论】:

    【解决方案4】:

    弄清楚这里发生了什么以获得进一步的启发:

    long swapLong(long x)
    {
        int s = sizeof(long);
        long r = 0;
        for(int i=0; i<s; ++i)
        {
            r <<= 8;
            r |= x & 0xff;
            x >>= 8;
        }
        return r;
    }
    

    【讨论】:

      猜你喜欢
      • 2017-10-30
      • 1970-01-01
      • 1970-01-01
      • 2016-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-01
      • 1970-01-01
      相关资源
      最近更新 更多