我想知道数据类型是如何存储在c中的,所以我编写了一个程序来检查值的存储方式。当我看到输出时,我无法理解内存中不同数据类型的存储值。
这是我试过的程序,
numberOfRowsInSection
输入输出= 10
enter a num10 10 4 000000000000000000000000000001010 10 2 00000000000001010 10 8 00000000000000000000000000000101000000000000000000000000000001010 10 4 000000000000000000000000000001010 10 4 000000000000000000000000000001010
输入输出= -10
enter a num-10 -10 4 011111111111111111111111111110110 -10 2 11111111111110110 -10 8 01111111111111111111111111111011011111111111111111111111111110110 -10 4 011111111111111111111111111110110 -10 4 011111111111111111111111111110110
有人可以解释为什么会这样吗? &安培;不同的数据类型如何在内存中存储值?提前谢谢
答案 0 :(得分:8)
我想知道数据类型如何存储在C
中
讽刺的是,这毫无意义。 数据的存储方式是实施细节 (C99或C11标准未定义数据的存储方式),原则上你不应该打扰并尝试写portable code。
实际上,如何在名为Application Binary Interface的文档中指定数据的存储和表示方式,以及如何在函数调用等中传输数据。这些约定特定于处理器,通常是操作系统,后面是编译器(和其他工具)。
请注意,某些数据可能不在内存中,但是只在登记册中。
您可以在two's complement,instruction sets,x86,calling conventions,x86 calling conventions,processor registers,address space上阅读wikipages, virtual memory,endianness,data-structure alignment,integer (computer science),floating point,IEEE floating point,....
在实践中,数据表示非常强大。系统特定的。您的ARM / Android平板电脑和Linux / x86-64桌面以及Arduino工具包或IBM System Z大型机上的内容有所不同(所以你的程序会给出不同的结果。)
请注意,C99为您<stdint.h>
提供了标准类型,例如int32_t
,uint64_t
,intptr_t
如果您关心interoperability,请详细了解serialization并使用明确定义的文字格式(例如JSON)。
答案 1 :(得分:1)
您的正数和无符号数表示为标准二进制数,未使用的位用0填充。
签名变量中的负数存储在two's-complement中。阅读,这是计算机科学的基本概念。
基本上,二进制补码是一种用二进制表示负值的方法。
例如,-10是
011111111111111111111111111110110
在32位的二进制补码中。你可以找到给定负数的双补码,如下所示:
-10:
首先,取二进制的正数。 10这是
00000000000000000000000000001010
现在将其反转(将所有0更改为1,反之亦然)
11111111111111111111111111110101
现在在正常添加中添加一个。
11111111111111111111111111110110
瞧,你的32位数字的二进制表示为-10。
虽然,存储值的确切方式,正如另一个答案所提到的,由编译器决定,因为没有设置规则。
答案 2 :(得分:1)
任何type
的存储要求取决于底层操作系统和硬件。 x86_64
和x86
存储空间大小存在显着差异。你可以使用稍微不同的版本来完成你刚开始做的事情。例如:
#include <stdio.h>
#if defined(__LP64__) || defined(_LP64)
# define BUILD_64 1
#endif
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
/* signed data type low storage limit */
long long limit_s_low (unsigned char bytes)
{ return -(1ULL << (bytes * CHAR_BIT - 1)); }
/* signed data type high storage limit */
long long limit_s_high (unsigned char bytes)
{ return (1ULL << (bytes * CHAR_BIT - 1)) - 1; }
/* unsigned data type high storage limit */
unsigned long long limit_u_high (unsigned char bytes)
{
if (bytes < sizeof (long long))
return (1ULL << (bytes * CHAR_BIT)) - 1;
else
return ~1ULL - 1;
}
int main (void) {
#ifdef BUILD_64
printf ("\n data type sizes for x86_64:\n\n");
printf (" sizeof (char) : %lu\n", sizeof (char));
printf (" sizeof (char*) : %lu (all pointers)\n", sizeof (char*));
printf (" sizeof (short) : %lu\n", sizeof (short));
printf (" sizeof (int) : %lu\n", sizeof (int));
printf (" sizeof (long) : %lu\n", sizeof (long));
printf (" sizeof (long long) : %lu\n\n", sizeof (long long));
#else
printf ("\n data type sizes for x86 (32-bit) :\n\n");
printf (" sizeof (char) : %u\n", sizeof (char));
printf (" sizeof (char*) : %u (all pointers)\n", sizeof (char*));
printf (" sizeof (short) : %u\n", sizeof (short));
printf (" sizeof (int) : %u\n", sizeof (int));
printf (" sizeof (long) : %u\n", sizeof (long));
printf (" sizeof (long long) : %u\n\n", sizeof (long long));
#endif
#ifdef BUILD_64
printf (" data type storage sizes for x86_64:\n\n");
#else
printf (" data type storage sizes for x86:\n\n");
#endif
printf (" char - signed : %11lld to %lld\n",
limit_s_low (sizeof (char)), limit_s_high (sizeof (char)));
printf (" char - unsigned : %11d to %llu\n",
0, limit_u_high (sizeof (char)));
printf (" short - signed : %11lld to %lld\n",
limit_s_low (sizeof (short)), limit_s_high (sizeof (short)));
printf (" short - unsigned : %11d to %llu\n",
0, limit_u_high (sizeof (short)));
#ifdef BUILD_64
printf (" int - signed : %lld to %lld\n",
limit_s_low (sizeof (int)), limit_s_high (sizeof (int)));
printf (" int - unsigned : %11d to %llu\n",
0, limit_u_high (sizeof (int)));
printf (" (l)long - signed : %.4e to %.4e\n",
(double)limit_s_low (sizeof (long)),
(double)limit_s_high (sizeof (long)));
printf (" (l)long - unsigned : %11d to %.4e %llu\n\n",
0, (double)limit_u_high (sizeof (long)),
limit_u_high (sizeof (long long)));
#else
printf (" int/long - signed : %lld to %lld\n",
limit_s_low (sizeof (int)), limit_s_high (sizeof (int)));
printf (" int/long - unsigned : %11d to %llu\n",
0, limit_u_high (sizeof (int)));
printf (" llong - signed : %.4e to %.4e\n",
(double)limit_s_low (sizeof (long long)),
(double)limit_s_high (sizeof (long long)));
printf (" llong - unsigned : %11d to %.4e %llu\n\n",
0, (double)limit_u_high (sizeof (long long)),
limit_u_high (sizeof (long long)));
#endif
return 0;
}
#if defined(__LP64__) || defined(_LP64)
阻止测试系统是否正在运行x86_64
,如果没有,则默认为评估x86
的存储大小。它在x86
上同样可编辑/可运行。在x86_64
,您通常会看到以下内容:
<强>输出强>
$ ./bin/typesize
data type sizes for x86_64:
sizeof (char) : 1
sizeof (char*) : 8 (all pointers)
sizeof (short) : 2
sizeof (int) : 4
sizeof (long) : 8
sizeof (long long) : 8
data type storage sizes for x86_64:
char - signed : -128 to 127
char - unsigned : 0 to 255
short - signed : -32768 to 32767
short - unsigned : 0 to 65535
int - signed : -2147483648 to 2147483647
int - unsigned : 0 to 4294967295
(l)long - signed : -9.2234e+18 to 9.2234e+18
(l)long - unsigned : 0 to 1.8447e+19 18446744073709551613
在32位框中,输出为:
$ ./datatype/typecast/bin/typesize_32
data type sizes for x86 (32-bit) :
sizeof (char) : 1
sizeof (char*) : 4 (all pointers)
sizeof (short) : 2
sizeof (int) : 4
sizeof (long) : 4
sizeof (long long) : 8
data type storage sizes for x86:
char - signed : -128 to 127
char - unsigned : 0 to 255
short - signed : -32768 to 32767
short - unsigned : 0 to 65535
int/long - signed : -2147483648 to 2147483647
int/long - unsigned : 0 to 4294967295
llong - signed : -9.2234e+18 to 9.2234e+18
llong - unsigned : 0 to 1.8447e+19 18446744073709551613
如果您有任何疑问或希望获得其他帮助,请与我们联系。