C,小端和大端的混乱 [英] C, Little and Big Endian confusion

查看:73
本文介绍了C,小端和大端的混乱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解C编程内存字节顺序,但我感到困惑。
我在此站点上尝试使用具有一定价值的应用程序进行输出验证: www.yolinux.com/TUTORIALS/Endian-Byte-Order.html

I try to understand C programming memory Bytes order, but I'm confuse. I try my app with some value on this site for my output verification : www.yolinux.com/TUTORIALS/Endian-Byte-Order.html

我在C程序中使用的64位值:

volatile long long ll = (long long)1099511892096;
__mingw_printf("\tlong long, %u Bytes, %u bits,\t%lld to %lli, %lli, 0x%016llX\n", sizeof(long long), sizeof(long long)*8, LLONG_MIN, LLONG_MAX , ll, ll);

void printBits(size_t const size, void const * const ptr)
{
    unsigned char *b = (unsigned char*) ptr;
    unsigned char byte;
    int i, j;
    printf("\t");
    for (i=size-1;i>=0;i--)
    {
        for (j=7;j>=0;j--)
        {
            byte = b[i] & (1<<j);
            byte >>= j;
            printf("%u", byte);
        }

        printf(" ");
    }
    puts("");
}

long long,                8 Bytes,   64 bits,   -9223372036854775808 to 9223372036854775807, 1099511892096, 0x0000010000040880
80 08 04 00 00 01 00 00  (Little-Endian)
10000000 00001000 00000100 00000000 00000000 00000001 00000000 00000000
00 00 01 00 00 04 08 80  (Big-Endian)
00000000 00000000 00000001 00000000 00000000 00000100 00001000 10000000

测试

0x8008040000010000, 1000000000001000000001000000000000000000000000010000000000000000 // online website hex2bin conv. 
                    1000000000001000000001000000000000000000000000010000000000000000 // my C app
0x8008040000010000, 1000010000001000000001000000000000000100000000010000000000000000 // yolinux.com


0x0000010000040880, 0000000000000000000000010000000000000000000001000000100010000000      //online website hex2bin conv., 1099511892096  ! OK
                    0000000000000000000000010000000000000000000001000000100010000000      // my C app,  1099511892096 ! OK
[Convert]::ToInt64("0000000000000000000000010000000000000000000001000000100010000000", 2) // using powershell for other verif., 1099511892096 ! OK          
0x0000010000040880, 0000000000000000000000010000010000000000000001000000100010000100      // yolinux.com, 1116691761284 (from powershell bin conv.) ! BAD !

问题

yolinux.com网站宣布 BIG ENDIAN 0x0000010000040880 !但是我的计算机使用LITTLE ENDIAN,我认为(Intel proc。)
,我从C应用程序和另一个网站hex2bin转换器中获得了相同的值0x0000010000040880。
__mingw_printf(... 0x%016llX ...,... ll)也会打印0x0000010000040880,正如您所看到的。

yolinux.com website announce 0x0000010000040880 for BIG ENDIAN ! But my computer use LITTLE ENDIAN I think (Intel proc.) and I get same value 0x0000010000040880 from my C app and from another website hex2bin converter. __mingw_printf(...0x%016llX...,...ll) also print 0x0000010000040880 as you can see.

下面的yolinux网站我已经倒置了现在,我的输出中是我的(Little-Endian)和(Big-Endian)标签。

Following yolinux website I have inverted my "(Little-Endian)" and "(Big-Endian)" labels in my output for the moment.

此外,正号的符号位必须为0数字是我的结果也是yolinux的结果。(无法帮助我确定。)

Also, the sign bit must be 0 for a positive number it's the case on my result but also yolinux result.(can not help me to be sure.)

如果我正确理解字节序,则仅交换字节而不是位,而我

If I correctly understand Endianness only Bytes are swapped not bits and my groups of bits seems to be correctly inverted.

这只是yolinux.com上的错误,或者我缺少有关64位数字和C编程的步骤吗?

It is simply an error on yolinux.com or is I missing a step about 64-bit numbers and C programming?

推荐答案

使用 printf 打印一些多字节整数时(和正确的格式说明符)系统是小端字节序还是大端字节序都无所谓。结果将是相同的。

When you print some "multi-byte" integer using printf (and the correct format specifier) it doesn't matter whether the system is little or big endian. The result will be the same.

小字节序和大字节序之间的区别是多字节类型在内存中存储的顺序。但是一旦将数据从内存中读取到核心处理器中,就没有任何区别。

The difference between little and big endian is the order that multi-byte types are stored in memory. But once data is read from memory into the core processor, there is no difference.

此代码显示如何将整数(4个字节)放置在我的计算机上的内存中。

This code shows how an integer (4 bytes) is placed in memory on my machine.

#include <stdio.h>

int main()
{
    unsigned int u = 0x12345678;
    printf("size of int is %zu\n", sizeof u);
    printf("DEC: u=%u\n", u);
    printf("HEX: u=0x%x\n", u);
    printf("memory order:\n");
    unsigned char * p = (unsigned char *)&u;
    for(int i=0; i < sizeof u; ++i) printf("address %p holds %x\n", (void*)&p[i], p[i]);
    return 0;
}

输出:

size of int is 4
DEC: u=305419896
HEX: u=0x12345678
memory order:
address 0x7ffddf2c263c holds 78
address 0x7ffddf2c263d holds 56
address 0x7ffddf2c263e holds 34
address 0x7ffddf2c263f holds 12

因此,我可以看到我在一个小端机上,因为LSB(最低有效字节,即78)存储在最低地址上。

So I can see that I'm on a little endian machine as the LSB (least significant byte, i.e. 78) is stored on the lowest address.

大型字节序计算机上的程序会(假设地址相同)显示:

Executing the same program on a big endian machine would (assuming same address) show:

size of int is 4
DEC: u=305419896
HEX: u=0x12345678
memory order:
address 0x7ffddf2c263c holds 12 
address 0x7ffddf2c263d holds 34 
address 0x7ffddf2c263e holds 56 
address 0x7ffddf2c263f holds 78 

现在,最低位存储的是MSB(最高有效字节,即12)。

Now it is the MSB (most significant byte, i.e. 12) that are stored on the lowest address.

重要的事情唯一的理由是,该与如何在内存中存储多字节类型有关。一旦将整数从内存中读取到内核内部的寄存器中,该寄存器将以 大小端机器上的形式存储0x12345678形式的整数。

The important thing to understand is that this only relates to "how multi-byte type are stored in memory". Once the integer is read from memory into a register inside the core, the register will hold the integer in the form 0x12345678 on both little and big endian machines.

这篇关于C,小端和大端的混乱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆