【发布时间】:2019-06-30 01:51:59
【问题描述】:
我试图理解 C 编程内存字节顺序,但我很困惑。 我在这个网站上尝试了我的应用程序以进行输出验证: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 网站宣布 0x0000010000040880 为 BIG ENDIAN !但我认为我的电脑使用 LITTLE ENDIAN (Intel proc.) 我从我的 C 应用程序和另一个网站 hex2bin 转换器获得相同的值 0x0000010000040880。 __mingw_printf(...0x%016llX...,...ll) 也打印 0x0000010000040880 如您所见。
在 yolinux 网站之后,我暂时在输出中反转了“(Little-Endian)”和“(Big-Endian)”标签。
此外,正数的符号位必须为 0,这在我的结果中也是如此,在 yolinux 结果中也是如此。(不能帮助我确定。)
如果我正确理解字节顺序,则只交换字节而不交换位,并且我的位组似乎正确反转。
这只是 yolinux.com 上的一个错误,还是我错过了关于 64 位数字和 C 编程的步骤?
【问题讨论】:
-
当您使用
printf打印一个数字时,系统是大端还是小端并不重要——它们将打印相同的东西。大/小端仅与字节顺序在内存中的关系有关 -
数字的十六进制表示不受内存中字节表示的影响,只有后者受字节序的影响。
-
@4386427,是的,但我通过函数和内存指针获得了值。这可以改变什么?我添加了函数。
-
@Aborted-Security 不,只有看内存顺序才能看到区别。
-
@Aborted-Security 人类代表 = Big Endian。如果需要,只需检查是否为小端,然后向后打印字节,否则将它们打印在内存中。顺便说一句,我看了那个教程,它很糟糕。使用
char类型、0x000000000000FF00之类的字面量并使用位字段来证明字节顺序的人显然不知道他们在做什么,也不必移植代码。
标签: c endianness