int 数据如何按位存储在内存中?不是右对齐吗?
How is an int data stored on the memory in terms of bits? Is it not right-aligned?
当我在 C 中使用 fwrite 函数尝试一些东西时,我真的很困惑。
我在这里通读了fwrite的手册http://www.cplusplus.com/reference/cstdio/fwrite/
它说函数逐字节写入数组,所以我尝试写入一个整数数组,期望数组中的每个整数被拆分为 4 个字符。
我认为值的位表示在内存中是右对齐的。也就是说,98('b' 的 ascii) 将存储为
00000000 00000000 00000000 01100010
关于内存。所以我希望 fwrite 函数在 txt 文件中写入 ' ', ' ', ' ', 'b'。相反,它写了 'b'、' '、' '、' '。
一头雾水,又用指针测试了一遍,希望我对内存存储的认识没有错,只是关于fwrite函数的。我做了一个整型数组arr,把(1<<8)+2, 98放进去
我使用字符指针将每个整数拆分为四个字节。这是代码。
#include <stdio.h>
int main()
{
int arr[5]={(1<<8)+2, 98, 'c', 'd', 'e'};
char *p = (char*)&(arr[0]);
printf("%d %d %d %d %d %d", arr[0], (int)(*p), (int)(*(p+1)), (int)(*(p+2)), (int)(*(p+3)), (int)(*(p+4)));
FILE *fp;
fp = fopen("TestFile2.txt", "a");
fwrite(arr, sizeof(char), 5, fp);
fclose(fp);
}
程序在控制台打印“258 2 1 0 0 98”,“b”写在TestFile2中(不包括“s”)。
据我所知,(1<<8)+2 位表示是
00000000 00000000 00000001 00000010 所以程序应该打印 258 0 0 1 2 0.
奇怪的是结果甚至不是值的左对齐位表示。
值如何按位存储在内存中?跟我想的不一样吗?或者,我在这里遗漏了什么吗?
任何帮助将不胜感激。
您似乎漏掉了术语 Endianess。许多系统以 "Little Endian" 顺序保存它们的单词(在 32 位系统中为 4 个字节)- 即 "little end" 首先。这意味着最低有效字节 (LSB) 在前(最低地址),然后从那里开始上升。这就是为什么 2 是第一个(最低地址,LSB),1 是第二个,然后是最高有效字节的 0。仅当您处理字节级数据时,字节序才重要,但是了解您的系统使用哪种字节序非常重要。
对齐与它无关 - 单个字节在所有系统中始终读取相同,就像我们通常写数字一样 - 右侧的 LSB。
问题是你(作为人类)如何看待内存,你陷入了内存以 0x0000 0x0001 0x002 的方式显示的陷阱,例如内存地址(左边不太重要),让你了解如何4 字节整数存储在您的系统中下一步:
int a=0x01020408;
char* c=(char*)(void*)&a;
看看它是如何按字节存储的;最有可能是 c[0]=0x8; c[1]=0x04; c[2]=0x02;
您还可以考虑一下处理器如何将这 4 个字节的内存加载到寄存器中;最低有效内存地址被加载到最低有效寄存器位
内存存储中没有"right alignment"这样的概念。只有大端(意味着最高有效字节存储在低地址内存中,而最低有效字节存储在高地址内存中)和小端(最低有效字节存储在低地址内存中,最高有效字节存储在最高地址内存中)寻址内存)
字节中的位顺序是另一回事。我见过一些书,其中的位是从 1 到 8 的数字,字节中的权重从高到低,而其他书籍中的位是从 0 到 7 的数字,按它们在单词中的权重。另一个问题是,当一个字中的各个位被序列化到网上时,它们是如何传输的。一些协议首先传输最低有效位(主要是 rs-232c 和以太网),而其他协议首先传输最高有效位(我认为,但我不确定,USB 和 CAN BUS)
如果您使用 fwrite(2)
写入多字节 int
这取决于机器架构,以查看通过文件描述符实际传输的字节顺序。由于 fwrite()
总是将字节从较低地址的字节单元写入较高地址的字节单元,因此整数的字节将在您在论文中写入时写入(首先是权重最大的字节,然后是数字中权重最小的字节)仅当您在大端机器(sparc、motorolas 和一些 arms --- 在 arm 中,endiannes 是用户可选择的)但如果您在 小端机器,那么你会先得到权重较小的字节,然后是权重最大的字节(例如Intel等)
当我在 C 中使用 fwrite 函数尝试一些东西时,我真的很困惑。
我在这里通读了fwrite的手册http://www.cplusplus.com/reference/cstdio/fwrite/
它说函数逐字节写入数组,所以我尝试写入一个整数数组,期望数组中的每个整数被拆分为 4 个字符。
我认为值的位表示在内存中是右对齐的。也就是说,98('b' 的 ascii) 将存储为
00000000 00000000 00000000 01100010
关于内存。所以我希望 fwrite 函数在 txt 文件中写入 ' ', ' ', ' ', 'b'。相反,它写了 'b'、' '、' '、' '。
一头雾水,又用指针测试了一遍,希望我对内存存储的认识没有错,只是关于fwrite函数的。我做了一个整型数组arr,把(1<<8)+2, 98放进去
我使用字符指针将每个整数拆分为四个字节。这是代码。
#include <stdio.h>
int main()
{
int arr[5]={(1<<8)+2, 98, 'c', 'd', 'e'};
char *p = (char*)&(arr[0]);
printf("%d %d %d %d %d %d", arr[0], (int)(*p), (int)(*(p+1)), (int)(*(p+2)), (int)(*(p+3)), (int)(*(p+4)));
FILE *fp;
fp = fopen("TestFile2.txt", "a");
fwrite(arr, sizeof(char), 5, fp);
fclose(fp);
}
程序在控制台打印“258 2 1 0 0 98”,“b”写在TestFile2中(不包括“s”)。
据我所知,(1<<8)+2 位表示是
00000000 00000000 00000001 00000010 所以程序应该打印 258 0 0 1 2 0.
奇怪的是结果甚至不是值的左对齐位表示。
值如何按位存储在内存中?跟我想的不一样吗?或者,我在这里遗漏了什么吗?
任何帮助将不胜感激。
您似乎漏掉了术语 Endianess。许多系统以 "Little Endian" 顺序保存它们的单词(在 32 位系统中为 4 个字节)- 即 "little end" 首先。这意味着最低有效字节 (LSB) 在前(最低地址),然后从那里开始上升。这就是为什么 2 是第一个(最低地址,LSB),1 是第二个,然后是最高有效字节的 0。仅当您处理字节级数据时,字节序才重要,但是了解您的系统使用哪种字节序非常重要。
对齐与它无关 - 单个字节在所有系统中始终读取相同,就像我们通常写数字一样 - 右侧的 LSB。
问题是你(作为人类)如何看待内存,你陷入了内存以 0x0000 0x0001 0x002 的方式显示的陷阱,例如内存地址(左边不太重要),让你了解如何4 字节整数存储在您的系统中下一步:
int a=0x01020408;
char* c=(char*)(void*)&a;
看看它是如何按字节存储的;最有可能是 c[0]=0x8; c[1]=0x04; c[2]=0x02; 您还可以考虑一下处理器如何将这 4 个字节的内存加载到寄存器中;最低有效内存地址被加载到最低有效寄存器位
内存存储中没有"right alignment"这样的概念。只有大端(意味着最高有效字节存储在低地址内存中,而最低有效字节存储在高地址内存中)和小端(最低有效字节存储在低地址内存中,最高有效字节存储在最高地址内存中)寻址内存)
字节中的位顺序是另一回事。我见过一些书,其中的位是从 1 到 8 的数字,字节中的权重从高到低,而其他书籍中的位是从 0 到 7 的数字,按它们在单词中的权重。另一个问题是,当一个字中的各个位被序列化到网上时,它们是如何传输的。一些协议首先传输最低有效位(主要是 rs-232c 和以太网),而其他协议首先传输最高有效位(我认为,但我不确定,USB 和 CAN BUS)
如果您使用 fwrite(2)
写入多字节 int
这取决于机器架构,以查看通过文件描述符实际传输的字节顺序。由于 fwrite()
总是将字节从较低地址的字节单元写入较高地址的字节单元,因此整数的字节将在您在论文中写入时写入(首先是权重最大的字节,然后是数字中权重最小的字节)仅当您在大端机器(sparc、motorolas 和一些 arms --- 在 arm 中,endiannes 是用户可选择的)但如果您在 小端机器,那么你会先得到权重较小的字节,然后是权重最大的字节(例如Intel等)